Iterating unregistered add-ins (.xla)

跟風遠走 提交于 2019-11-30 09:10:37

As of Office 2010, there is a new collection .AddIns2 which is the same as .AddIns but also includes the unregistered .XLA plug-ins.

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
brettdj

I have had issues with addins that are installed (and in the VBE) not being available via user's Addin on Exel 2013 (in a work environment).

Tinkering with the solution from Chris C gave a good workaround.

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

I'm still on the lookout for a sane solution for this problem, but for the time being it seems that reading the window texts of all workbook windows gives a collection of all open workbooks, add-in or not:

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

What about this:

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

Any use?

Use =DOCUMENTS, an Excel4 macro function.

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

Here's the documentation for it (available here):

DOCUMENTS
Returns, as a horizontal array in text form, the names of the specified open workbooks in alphabetic order. Use DOCUMENTS to retrieve the names of open workbooks to use in other functions that manipulate open workbooks.

Syntax
DOCUMENTS(type_num, match_text)
Type_num is a number specifying whether to include add-in workbooks in the array of workbooks, according to the following table.

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 specifies the workbooks whose names you want returned and can include wildcard characters. If match_text is omitted, DOCUMENTS returns the names of all open workbooks.

Is iterating through the registry a possibility? I know that that doesn't give you a snapshot of what your instance of Excel is using, but what a new instance would use - but depending on what you need it for, it might be good enough.

The relevant keys are:

'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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!