C# 使用Microsoft.Office.Interop.Excel实现删除工作表后调用自定义函数
工作表删除后触发自定义函数的实现方案
Microsoft.Office.Interop.Excel 原生没有公开SheetAfterDelete这类删除完成后的事件,我们可以通过WorkbookEvents_SheetBeforeDeleteEventHandler配合消息队列调度的方式来模拟实现,效果和原生AfterDelete事件一致。
方案1:UI线程调度实现(适配WinForm/WPF/VSTO场景)
实现思路
BeforeDelete事件触发时,删除操作已经进入Excel的UI消息队列等待执行,只需将自定义逻辑以低优先级投递到当前UI消息队列的末尾,Excel会先完成工作表删除操作,再执行你投递的自定义逻辑。
实现步骤
- 初始化时订阅
Workbook.SheetBeforeDelete事件 - 在事件回调中提前读取并存储被删除工作表的关键信息(删除完成后无法再访问该工作表对象)
- 通过UI线程的异步调度接口投递自定义逻辑
代码示例
using Microsoft.Office.Interop.Excel; using System.Windows.Threading; // 初始化Excel对象并订阅事件 Application excelApp = new Application(); Workbook targetWorkbook = excelApp.Workbooks.Open("你的Excel文件路径"); targetWorkbook.SheetBeforeDelete += OnSheetBeforeDelete; private void OnSheetBeforeDelete(object sh, ref bool cancel) { // 提前存储需要用到的工作表信息,比如名称、CodeName、自定义属性等 Worksheet deletedSheet = (Worksheet)sh; string sheetName = deletedSheet.Name; int sheetId = deletedSheet.Index; // 将自定义逻辑投递到UI消息队列末尾,优先级设为Background确保删除操作先执行 Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { // 此处执行你的自定义逻辑,此时工作表已经完成删除 CustomAfterDeleteHandler(sheetName, sheetId); })); } // 你的自定义删除后处理函数 private void CustomAfterDeleteHandler(string deletedSheetName, int deletedSheetIndex) { // 编写你的业务逻辑 }
WinForm场景下只需将
Dispatcher.BeginInvoke替换为对应窗口的BeginInvoke方法即可,逻辑完全一致。
方案2:事件联动实现(适配无UI后台场景)
如果没有UI线程可用,可以通过事件联动的方式实现:
- 全局维护一个待删除工作表的标识队列
- 在
SheetBeforeDelete事件中将待删除工作表的唯一标识存入队列 - 订阅
Workbook.SheetActivate/Application.WindowResize这类删除操作完成后必然会触发的事件 - 在上述事件回调中校验队列中的标识是否还存在于工作表集合中,不存在则说明删除已完成,执行对应自定义逻辑并移除队列中的标识
注意事项
- 不要在
SheetBeforeDelete回调中直接校验工作表是否存在,此时删除操作尚未执行,工作表仍然存活 - 被删除工作表的所有内部数据必须在
SheetBeforeDelete阶段读取存储,删除完成后无法再访问该工作表的COM对象 - 批量删除工作表场景下,可将所有待删除信息存入队列,在后续调度逻辑中统一批量处理
内容的提问来源于stack exchange,提问作者Bishan Vithanage
相关产品推荐
相关产品推荐

