我仍在寻找针对此问题的合理解决方案,但目前看来,阅读所有工作簿窗口的窗口文本可以提供所有打开的工作簿的集合,无论是否加载:
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Function GetAllOpenWorkbooks() As Collection
'Retrieves a collection of all open workbooks and add-ins.
Const EXCEL_APPLICATION_WINDOW As String = "XLDESK"
Const EXCEL_WORKBOOK_WINDOW As String = "EXCEL7"
Dim hWnd As Long
Dim hWndExcel As Long
Dim contentLength As Long
Dim buffer As String
Dim bookName As String
Dim books As Collection
Set books = New Collection
'Find the main Excel window
hWndExcel = FindWindowEx(Application.hWnd, 0&, EXCEL_APPLICATION_WINDOW, vbNullString)
Do
'Find next window
hWnd = FindWindowEx(hWndExcel, hWnd, vbNullString, vbNullString)
If hWnd Then
'Create a string buffer for 100 chars
buffer = String$(100, Chr$(0))
'Get the window class name
contentLength = GetClassName(hWnd, buffer, 100)
'If the window found is a workbook window
If Left$(buffer, contentLength) = EXCEL_WORKBOOK_WINDOW Then
'Recreate the buffer
buffer = String$(100, Chr$(0))
'Get the window text
contentLength = GetWindowText(hWnd, buffer, 100)
'If the window text was returned, get the workbook and add it to the collection
If contentLength Then
bookName = Left$(buffer, contentLength)
books.Add Excel.Application.Workbooks(bookName), bookName
End If
End If
End If
Loop While hWnd
'Return the collection
Set GetAllOpenWorkbooks = books
End Function