10

我需要帮助

  • 弄清楚如何使用菜单路径遍历尚未在 Excel 中注册的当前打开的 Excel 加载项文件(.xla) 。Tools > Add-ins
  • 更具体地说,我对任何未出现在加载项对话框中但具有ThisWorkbook.IsAddin = True.

证明问题:

尝试按如下方式遍历工作簿不会获得具有以下内容的工作簿.AddIn = True

Dim book As Excel.Workbook

For Each book In Application.Workbooks
    Debug.Print book.Name
Next book

循环通过加载项不会获取未注册的加载项:

Dim addin As Excel.AddIn

For Each addin In Application.AddIns
    Debug.Print addin.Name
Next addin

循环遍历 VBProjects 集合有效,但前提是用户在宏安全设置中具有对 Visual Basic 项目的特别受信任的访问权限 - 这很少:

Dim vbproj As Object

For Each vbproj In Application.VBE.VBProjects
    Debug.Print vbproj.Filename
Next vbproj

但是,如果知道工作簿的名称,则可以直接引用该工作簿,而不管它是否是加载项:

Dim book As Excel.Workbook
Set book = Application.Workbooks("add-in.xla")

但是,如果名称未知,并且不能依赖用户的宏安全设置,那么如何获得对这个工作簿的引用呢?

4

6 回答 6

11

从 Office 2010 开始,有一个新的集合 .AddIns2 与 .AddIns 相同,但还包括未注册的 .XLA 插件。

Dim a As AddIn
Dim w As Workbook

On Error Resume Next
With Application
    For Each a In .AddIns2
        If LCase(Right(a.name, 4)) = ".xla" Then
            Set w = Nothing
            Set w = .Workbooks(a.name)
            If w Is Nothing Then
                Set w = .Workbooks.Open(a.FullName)
            End If
        End If
    Next
End With
于 2013-01-17T20:30:37.643 回答
1

我遇到了无法通过用户Addin在 Exel 2013 上(在工作环境中)安装的插件(以及在 VBE 中)的问题。

修补Chris C的解决方案提供了一个很好的解决方法。

Dim a As AddIn
Dim wb As Workbook

On Error Resume Next
With Application
    .DisplayAlerts = False
        For Each a In .AddIns2
        Debug.Print a.Name, a.Installed
            If LCase(Right$(a.Name, 4)) = ".xla" Or LCase(Right$(a.Name, 5)) Like ".xla*" Then
                Set wb = Nothing
                Set wb = .Workbooks(a.Name)
                wb.Close False
                Set wb = .Workbooks.Open(a.FullName)
            End If
        Next
   .DisplayAlerts = True
End With
于 2016-09-21T04:37:46.700 回答
0

我仍在寻找针对此问题的合理解决方案,但目前看来,阅读所有工作簿窗口的窗口文本可以提供所有打开的工作簿的集合,无论是否加载:

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
于 2008-11-13T16:20:02.263 回答
0

那这个呢:

Public Sub ListAddins()

Dim ai As AddIn

    For Each ai In Application.AddIns
        If Not ai.Installed Then
            Debug.Print ai.Application, ai.Parent, ai.Name, ai.FullName
        End If
    Next

End Sub

有什么用?

于 2008-11-26T11:58:57.887 回答
0

使用 =DOCUMENTS,一个 Excel4 宏函数。

Dim Docs As Variant
Docs = Application.Evaluate("documents(2)")

这是它的文档(可在此处获得):

DOCUMENTS
以文本形式的水平数组形式返回按字母顺序排列的指定打开工作簿的名称。使用 DOCUMENTS 检索打开的工作簿的名称,以在其他操作打开的工作簿的函数中使用。

语法
DOCUMENTS(type_num, match_text)
Type_num 是一个数字,指定是否在工作簿数组中包含加载项工作簿,如下表所示。

Type_num       Returns
1 or omitted   Names of all open workbooks except add-in workbooks
2              Names of add-in workbooks only
3              Names of all open workbooks

Match_text 指定要返回其名称的工作簿,并且可以包含通配符。如果省略 match_text,则 DOCUMENTS 返回所有打开的工作簿的名称。

于 2008-11-28T13:40:01.850 回答
0

是否有可能遍历注册表?我知道这并没有给你一个关于你的 Excel 实例正在使用什么的快照,而是一个新实例将使用什么 - 但取决于你需要它的用途,它可能已经足够好了。

相关键是:

'Active add-ins are in values called OPEN*
HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Options

'Inactive add-ins are in values of their full path
HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Add-in Manager
于 2008-12-12T14:16:51.320 回答