【问题标题】:How to detect whether an Excel workbook is closed (using Interop in C#)?如何检测 Excel 工作簿是否已关闭(使用 C# 中的互操作)?
【发布时间】:2013-07-29 03:40:50
【问题描述】:

我正在开发一个使用 Microsoft.Office.Interop.Excel.Application 从 Excel 文件中读取值的 C# 项目:

try {
    Application xlApp = new Application();
    Workbook workbook = xlApp.Workbooks.Open(filename)
    // ... Load Excel values ...
} finally {
    // ... Tidy up ...
}

finally 块中,我想确保所有内容都已关闭并正确处理,因此内存中没有任何内容,并且 Excel 可以干净地关闭。已经看到关于这段代码应该是什么样子的各种线程(比我想象的更复杂!)但它可能包括的一件事是:

if (workbook != null) {
    workbook.Close();
    // ... possibly also Marshal.FinalReleaseComObject(workbook);
}

但是,如果工作簿已经关闭,这会引发错误,那么我该如何安全地检查呢?如果可能的话,宁愿不要只捕获错误,因为这种类型的事情往往会扭曲调试。有没有一种干净的方法可以在关闭之前找出工作簿的状态?

还有一个问题 - 我想知道如果 xlApp.Quit(); 之后完成是否需要 workbook.Close() - 退出 Excel 应用程序会导致 workbook.Close()(以及任何 COM 对象释放)隐式发生吗?

【问题讨论】:

    标签: c# .net excel interop try-catch-finally


    【解决方案1】:

    当您打开工作簿时,最好的建议是跟踪工作簿并在适当的时候将其关闭。如果您的代码非常详细,那么您可以存储一个 Boolean 值,指示文件当前是打开还是关闭。

    在 Excel 中没有 IsOpen 等属性。您可以尝试参考工作簿:

    Workbook wbTest = xlApp.Workbooks.get_Item("some.xlsx");
    

    但是如果这本书没有打开,这会产生一个 COM 错误,所以会变得很乱。

    相反,创建您自己的函数IsOpen,它返回一个布尔值并循环通过当前打开的工作簿(Workbooks 集合)检查名称,使用如下代码:

    foreach (_Workbook wb in xlApp.Workbooks)
    {
        Console.WriteLine(wb.Name);
    }
    

    如果工作簿已保存,则不需要workbook.Close() - 反映 Excel 的正常行为。但是,需要释放所有 Excel 对象引用。正如您所发现的,这有点繁琐,CloseQuit 无法自行实现。


        static bool IsOpen(string book)
        {
            foreach (_Workbook wb in xlApp.Workbooks)
            {
                if (wb.Name.Contains(book))
                {
                    return true;
                }
            }
            return false;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2017-05-29
      相关资源
      最近更新 更多