4

我正在开发一个用于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);
}

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

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

4

1 回答 1

2

当您打开工作簿时,最好的建议是跟踪工作簿并在适当的时候将其关闭。如果您的代码非常详细,那么您可以存储一个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 对象引用。正如您所发现的那样,这有点繁琐,Close并且Quit不要自己实现这一点。


    static bool IsOpen(string book)
    {
        foreach (_Workbook wb in xlApp.Workbooks)
        {
            if (wb.Name.Contains(book))
            {
                return true;
            }
        }
        return false;
    }
于 2013-07-29T11:48:24.143 回答