2016-03-28 3 views
0

Этот вопрос в основном касается цикла всех книг во всех экземплярах excel!Извлечение всех названий книг в течение нескольких экземпляров excel выполняется

+0

Создайте массив и сохраните книгу, когда вы откроете каждый из них? Или даже использовать его со словарем для более быстрого поиска позже, а не для циклирования? – findwindow

+0

Возможно, это поможет? http://www.ozgrid.com/forum/showthread.php?t=182853 –

+1

Вы только когда-нибудь получите один ... Вы зацикливаете 'Excel' процессы, но *** ничего не делаете *** с их когда-то нашли. Вы создаете новый объект «ExcelApplication» и по умолчанию это ** 1 ** книга. Вот почему вы только когда-либо видите одну книгу ... – Codexer

ответ

1

Основная проблема, с которой вы столкнулись, заключается в том, что вы не используете какой-либо процесс, с которым вы сталкиваетесь. Поэтому вы не получите ничего такого. Внутри цикла для процесса вы создаете новый экземпляр ExcelApplication, а затем попытаетесь выполнить цикл через Workbooks. По умолчанию, когда вы делаете это есть только в то время, следовательно, почему вы получите только Workbook и почему вы только когда-нибудь Workbook.

Solution (Пробовал & Испытано)

Вы должны смотреть в Windows API вызовы, чтобы получить то, что вам нужно. Некоторые из них являются:

  1. GetDesktopWindow()
  2. EnumChildWindows()
  3. GetClassName()
  4. EnumWindowsProc()
  5. AccessibleObjectFromWindow()

    Imports Microsoft.Office.Interop 
    Imports System.Runtime.InteropServices 
    
    Public Class Form1 
    
    Private Declare Function GetDesktopWindow Lib "user32"() As Integer 
    Private Declare Function EnumChildWindows Lib "user32.dll" (ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowsProc, ByVal lParam As IntPtr) As Boolean 
    Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hWnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer 
    Private Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean 
    Private Declare Function AccessibleObjectFromWindow Lib "oleacc" (ByVal Hwnd As Int32, ByVal dwId As Int32, ByRef riid As Guid, <MarshalAs(UnmanagedType.IUnknown)> ByRef ppvObject As Object) As Int32 
    
    Private Const OBJID_NATIVE = &HFFFFFFF0 
    
    'Required to show the workbooks. Used in function to add to. 
    Private lstWorkBooks As New List(Of String) 
    
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 
        lstWorkBooks.Clear() 
        GetExcelOpenWorkBooks() 
    End Sub 
    
    
    Private Sub GetExcelOpenWorkBooks() 
        Try 
         'Get handle to desktop 
         Dim WindowHandle As IntPtr = GetDesktopWindow() 
    
         'Enumerate through the windows (objects) that are open 
         EnumChildWindows(WindowHandle, AddressOf GetExcelWindows, 0) 
    
         'List the workbooks out if we have something 
         If lstWorkBooks.Count > 0 Then MsgBox(String.Join(Environment.NewLine, lstWorkBooks)) 
    
        Catch ex As Exception 
        End Try 
    
    End Sub 
    
    Public Function GetExcelWindows(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean 
    
        Dim Ret As Integer = 0 
        Dim className As String = Space(255) 'Return the string with some padding... 
    
        Ret = GetClassName(hwnd, className, 255) 
        className = className.Substring(0, Ret) 
    
        If className = "EXCEL7" Then 
         Dim ExcelApplication As Excel.Application 
         Dim ExcelObject As Object = Nothing 
         Dim IDispatch As Guid 
    
         AccessibleObjectFromWindow(hwnd, OBJID_NATIVE, IDispatch, ExcelObject) 
    
         'Did we get anything? 
         If ExcelObject IsNot Nothing Then 
          ExcelApplication = ExcelObject.Application 
          'Make sure we have the instance... 
          If ExcelApplication IsNot Nothing Then 
           'Go through the workbooks... 
           For Each wrk As Excel.Workbook In ExcelApplication.Workbooks 
            'If workbook ins't in the list then add it... 
            If Not lstWorkBooks.Contains(wrk.Name) Then 
             lstWorkBooks.Add(wrk.Name) 
            End If 
           Next 
          End If 
    
         End If 
        End If 
    
        Return True 
    
    End Function 
    
    End Class 
    
+1

Серьезно, 'я предпочитаю код vb.net без API. Но если это невозможно, я принимаю решение API. В чем проблема? Этот *** ответ - ваш вопрос и многое другое ***. «Я предпочитаю простой код». Я бы хотел, чтобы это было так просто, если вы считаете, что это так, у вас есть длинный путь к началу :) – Codexer

+1

@Codexer Вы должны были удалить ответ, так как он кажется неблагодарным, что вы решили его проблему. – Sorceri

+0

@Markowitz Спасибо, принимая ответ, как он работает здесь. Если это поможет, важно проголосовать и принять ответ. Это помогает другим, которые могут иметь такую ​​же проблему. Кроме того, без использования API, возможно, невозможно пропустить активные окна и получить этот объект, единственный способ, которым я знаю, - это то, что я опубликовал – Codexer

Смежные вопросы