我有一个提供一组 UDF 的 Excel 自动化插件。即使通过互操作 API 打开 Excel,我也想让这些 UDF 正常工作。我知道当通过互操作 API 打开 Excel 时,Excel 以/automation
使 Excel不加载 addins的参数启动。为了解决这个问题,我添加了以下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()
好像,这通常仅在未加载插件时出现。当使用 VBA 进行重新计算CTRL+ALT+F9
或Application.CalculationFullRebuild
在 VBA 中进行重新计算时,甚至使用 all 将所有填充的单元格标记为脏时,ThisWorkbook.Worksheets(1).UsedRange.Dirty
都会导致带有 UDF 的单元格显示#NAME?
。编辑其中一个 UDF 单元格(选择F2
、、、Return
)时,该工作表上的所有 UDF(不在其他也使用该 UDF 的工作表上)突然再次返回正确的结果,并且公式=myDemoFunction()
再次变为。
所以我的问题是,如何触发 Excel 以编程方式识别插件?
我的代码库要大得多,但下面是自动化插件的精简版本,显示了这种行为(在 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