Повторение незарегистрированных надстроек (.xla)

мне нужна помощь в

  • выяснить, как перебирать открытые в настоящее время файлы надстроек Excel (.xla), которые не были зарегистрированы в Excel, используя путь меню 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")

Но как, черт возьми, получить ссылку на эту книгу, если имя неизвестно, а на настройки безопасности макросов пользователя нельзя положиться?


person jevakallio    schedule 13.11.2008    source источник


Ответы (6)


Начиная с 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
person Chris C.    schedule 17.01.2013
comment
Спасибо! Это было бы действительно полезно 4 года назад: P Принял ваш ответ, потому что ответ, который я принял, был слишком хакерским. - person jevakallio; 18.01.2013
comment
Да, я понял, что немного опоздал. :-) Но я столкнулся с той же проблемой и подумал, что это может помочь кому-то еще. - person Chris C.; 18.01.2013

У меня были проблемы с установленными надстройками (и в VBE), недоступными через Addin пользователя в Exel 2013 (в рабочей среде).

Работа с решением от 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
person brettdj    schedule 21.09.2016

Я все еще ищу разумное решение этой проблемы, но на данный момент кажется, что чтение текстов окон всех окон книг дает коллекцию всех открытых книг, надстроек или нет:

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
person jevakallio    schedule 13.11.2008

Что насчет этого:

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

Любое использование?

person Mike Woodhouse    schedule 26.11.2008

Используйте =ДОКУМЕНТЫ, функцию макроса Excel4.

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

Вот документация для него (доступна здесь):

ДОКУМЕНТЫ
Возвращает в виде горизонтального массива в текстовом виде имена указанных открытых книг в алфавитном порядке. Используйте ДОКУМЕНТЫ, чтобы получить имена открытых книг для использования в других функциях, управляющих открытыми книгами.

Синтаксис
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 опущен, ДОКУМЕНТЫ возвращает имена всех открытых книг.

person Hobbo    schedule 28.11.2008
comment
К сожалению, эта функция больше не работает в современных версиях Excel (по крайней мере, в 2010 году, хотя я думаю, что Microsoft убрала поддержку функций Excel4 по крайней мере в Excel 2007). - person GlennFromIowa; 17.04.2017

Возможна ли переборка реестра? Я знаю, что это не дает вам моментального снимка того, что использует ваш экземпляр 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
person Ant    schedule 12.12.2008