【问题标题】:Retrieve all workbook names during more than one excel instances are running在多个 excel 实例运行期间检索所有工作簿名称
【发布时间】:2016-07-15 21:49:05
【问题描述】:

这个问题基本上是关于循环所有excel实例中的所有工作簿!

【问题讨论】:

  • 创建一个数组并在打开每个工作簿时将工作簿存储到其中?或者甚至用字典键入它以便稍后更快地检索而不是循环?
  • 也许这会有所帮助? ozgrid.com/forum/showthread.php?t=182853
  • 您只会得到一个...您正在循环Excel 进程,但不会在找到它们后对其进行任何操作。您创建一个 ExcelApplication 的新对象,默认情况下它是 1 工作簿。这就是为什么你只看到一本书...
  • 甚至是 Windows API? 如果没有任何简单的解决方案,可能很难找到您要查找的内容。
  • @Markowitz 你能用 API 吗?

标签: vb.net excel


【解决方案1】:

您面临的主要问题是您没有使用遇到的任何流程。因此,您不会以这种方式得到任何东西。然后在进程的循环内部创建ExcelApplication 的新实例,然后尝试循环通过Workbooks。默认情况下,当你这样做时,那时只有 1,因此你只得到 1 Workbook 以及为什么你只会看到 1 Workbook.

解决方案(经过试验和测试)

您需要查看 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
    

【讨论】:

  • 说真的,I prefer vb.net code without API. But if this is not possible I accept API solution。问题是什么?这个答案是你的问题,还有更多I prefer simple code 我希望这很容易,如果您认为是这样,那么您还有很长的路要走:)
  • @Codexer 你应该删除答案,因为他似乎对你解决了他的问题不感激。
  • @Markowitz 谢谢,接受答案是它在这里的工作方式。如果有帮助,投票并接受答案很重要。这有助于其他可能遇到相同问题的人。此外,如果不使用 API,可能无法遍历活动窗口并获取该对象,我知道的唯一方法就是我发布的内容
猜你喜欢
  • 2013-04-01
  • 2022-11-01
  • 2014-08-25
  • 2017-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多