У меня есть надстройка Excel Automation, предоставляющая набор пользовательских функций. Я хочу, чтобы эти пользовательские функции работали даже при открытии Excel через Interop API. Я знаю, что при открытии Excel через Interop APIs Excel запускается с параметром /automation
, который заставляет Excel не загружать надстройки . Чтобы противостоять этому, я добавил следующее событие Workbook_Open()
:
Private Sub Workbook_Open()
Application.AddIns("SomeApp.DemoAddin").Installed = False
Application.AddIns("SomeApp.DemoAddin").Installed = True
End Sub
Этот код успешно загружает надстройку. Я проверил это, используя некоторые записи в надстройке.
Я собрал тестовую рабочую книгу, которая вызывает UDF =myDemoFunction()
. При открытии этой книги с помощью "C:\path\to\EXCEL.exe" /automation C:\path\to\workbook.xlsm
я наблюдаю следующее поведение. Сначала ячейка с UDF отображает правильный результат (в данном случае «15.0»). Тем не менее, формула отображается как =SomeApp.DemoAddin.myDemoFunction()
, что обычно имеет место только тогда, когда надстройка не загружена. При выполнении пересчета с помощью CTRL+ALT+F9
или Application.CalculationFullRebuild
в VBA или даже при маркировке всех заполненных ячеек как грязных с использованием ThisWorkbook.Worksheets(1).UsedRange.Dirty
все ячейки с UDF отображают #NAME?
. При редактировании одной из ячеек UDF (выберите F2
, Return
), тогда все UDF на этом одном листе (не на других листах, также использующих этот UDF) неожиданно снова вернут правильный результат, и формула снова изменится на =myDemoFunction()
.
Итак, мой вопрос: как я могу заставить Excel распознавать надстройку программным способом?
Моя база кода намного больше, но ниже приведена урезанная версия Automationнадстройка, показывающая это поведение (в VB.net):
Imports Extensibility
Imports System.Runtime.InteropServices
Imports Excel = Microsoft.Office.Interop.Excel
<GuidAttribute("352B1C10-DC5A-4BF8-9D31-DB9913B07364"),
ProgIdAttribute("SomeApp.DemoAddin"),
ClassInterface(ClassInterfaceType.AutoDual)>
Public Class DemoAddin
Implements IDTExtensibility2
Private excelApp As Excel.Application
Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
End Sub
Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
End Sub
Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete
End Sub
Public Sub OnDisconnection(RemoveMode As ext_DisconnectMode, ByRef custom As Array) Implements IDTExtensibility2.OnDisconnection
Marshal.ReleaseComObject(excelApp)
excelApp = Nothing
End Sub
Public Sub OnConnection(application As Object, connectMode As ext_ConnectMode, addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection
excelApp = CType(application, Excel.Application)
End Sub
Public Function myDemoFunction() As String
Return excelApp.Version
End Function
End Class