在 C# XLL(使用 ExcelDNA 的 Excel 加载项)中,如何检测工作簿何时关闭?

In a C# XLL (Excel add-in using ExcelDNA), how do I detect when a Workbook is closing?

提问人:RobBaker 提问时间:11/9/2023 更新时间:11/20/2023 访问量:33

问:

我有一个在 C# 中使用 ExcelDNA 构建的 XLL,其中包含一些用于计算的 UDF,以便在普通 XLSX 工作簿中使用。 我希望加载项对工作簿本身中的 BeforeClose 事件执行一些操作,而不必使用自己的事件处理程序将工作簿更改为 XLSM 文件。如何让我的 XLL 从 Excel 应用程序中捕获“工作簿正在关闭”事件,然后获取对该工作簿的引用(实际上只需其文件名即可),以便我可以在文件实际关闭之前对文件运行一些操作?

C# Excel-DNA

评论


答:

0赞 Jim Foye 11/9/2023 #1

通过 nuget 安装 NetOffice Framework:

https://netoffice.io/

现在,在外接程序的 AutoOpen 中,可以创建一个 Application 对象,该对象允许您访问所有 COM 内容,包括事件。

我正在使用 F#,而不是 C#,但这是它对我来说的样子:

open NetOffice.ExcelApi
open NetOffice.ExcelApi.Enums

module AddIn =
    let mutable private myApp : Application = null

    let beforeClose = Application_WorkbookBeforeCloseEventHandler (fun sender e -> 
        // do something here - sender is the workbook
        ())

    // I call this from my type I define that implements IExcelAddIn
    let autoOpen() = 
        myApp <- new Application (null, ExcelDnaUtil.Application)
        myApp.add_WorkbookBeforeCloseEvent beforeClose
0赞 RobBaker 11/20/2023 #2

我找到了一个替代方案,只需使用Microsoft.Office.Interop.Excel(无论如何,我已经使用它与Excel进行了一些非常轻微的交互)。我刚刚为事件处理程序定义了一个方法:

public void Event_Application_WorkbookBeforeClose(xl.Workbook workbook, ref bool Cancel)
{ // Excel BeforeClose event handler - use to tidy up
    // Do some stuff
}

然后,我在很早就运行的一段代码中使用了以下内容(在加载 XLL 之后):

if (!eventHandlerLoaded) { app.WorkbookBeforeClose += Event_Application_WorkbookBeforeClose; eventHandlerLoaded = true; }

我使用静态布尔值“eventHandlerLoaded”来检查我是否已经附加了事件处理程序。

事实证明,这很简单。