在C#应用程序期间在外部打开Excel文件时,会发生异常

时间:2012-07-13 20:04:47

标签: c# excel

我写了一个C#应用程序,它查询数据库并将结果放在excel文件中。该程序本身工作正常。但是,如果我在应用程序运行时打开第二个完全不相关的excel文件,则会发生异常并且该过程将停止。

现在,在程序本身中,我将可见性设置为false,在打开第二个不相关的Excel文件后,生成的文件突然打开并可见,然后我得到异常。

任何人都知道导致问题的原因或解决方法吗?

代码的相关部分如下,异常发生在工作单行.get_Range(currCol.GetString()+ excelRow,Missing.Value).Formula = item.ToString();

异常本身是:“来自HRESULT的异常:0x800AC472”

        Application exc = new Application();

        //Makes the Excel file not visible
        exc.Visible = false;
        exc.UserControl = false;
        exc.DisplayAlerts = false;


        Workbooks workbooks = exc.Workbooks;
        Workbook workbook = workbooks.Add(XlWBATemplate.xlWBATWorksheet);


        Sheets sheets = workbook.Worksheets;
        Worksheet worksheet = (Worksheet)sheets.get_Item(1);

        int excelRow = 1;
        ExcelChar currCol = new ExcelChar('A');
        System.Data.DataTable testTable = dbConnection.searchQuery("Select * from testTable").Copy();

        if (worksheet == null)
        {
            Console.WriteLine("ERROR: worksheet == null");
        }



        foreach (System.Data.DataRow row in testTable.Rows)
        {
            foreach (var item in row.ItemArray)
            {
                worksheet.get_Range(currCol.GetString() + excelRow, Missing.Value).Formula = item.ToString();
                currCol.Add(1);
            }
            excelRow++;
            currCol = new ExcelChar('A');
        }

3 个答案:

答案 0 :(得分:1)

看看this thread

看起来你的错误是VBA_E_IGNORE,在这种情况下你需要注册an IMessageFilter implementation,这样你才能实现重试逻辑。

过去我曾经看过这个问题,当使用相同的Excel实例和互操作时 - 例如在使用以下方法实例化Excel Application对象时:

Marshal.GetActiveObject("Excel.Application")

在您的情况下,您使用以下方法创建新的Excel实例:

exc = new Application();

您应该尝试做的是确保尽快关闭此实例。由于this KB article中描述的问题,这并不总是容易的。否则,您可能会考虑使用COM Interop之外的其他内容来写入Excel(例如OLEDB或第三方库,如Aspose或EPPlus)。

当Excel忙时 - 例如有一个模式对话框显示,或正忙于加载工作簿,它不会响应传入的COM消息,因此它返回一个错误,该错误被转换为此异常。 IMessageFilter实现(具体为:RetryRejectedCall)通常会重试几次,然后失败或提示用户重试(“服务器忙”)。

答案 1 :(得分:0)

使用Office InterOp服务时,必须以相反的顺序关闭已创建的对象。

private static void Excel_FromDataTable(DataTable dt)
    {
        // Global missing variable.
        object missing = System.Reflection.Missing.Value;

        // Creates an excel object, 
        Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
        // Then a workbooks object,
        Excel.Workbooks workbooks = excel.Workbooks;
        // Then adds a workbook object,
        Excel.Workbook workbook = workbooks.Add(true);
        // Then adds a worksheet object,
        Excel.Worksheet activeSheet = workbook.ActiveSheet;
        // Then names the worksheet to what we need.
        activeSheet.Name = "scbyext";

        // Add column headings,
        int iCol = 0;
        // for each row of data,
        int iRow = 0;
        foreach (DataRow r in dt.Rows)
        {
            iRow++;

            // Then add each row's cell data.
            iCol = 0;
            foreach (DataColumn c in dt.Columns)
            {
                iCol++;
                excel.Cells[iRow, iCol] = r[c.ColumnName];
            }
        }

        // Disable Excel prompts.
        excel.DisplayAlerts = false;
        // Save the workbook to the correct folder.
        workbook.SaveAs("C:\\Escaped\\Path",
        Excel.XlFileFormat.xlExcel8, missing, missing,
        false, false, Excel.XlSaveAsAccessMode.xlNoChange,
        missing, missing, missing, missing, missing);

        // Release the objects we made, in reverse order, to allow Excel to quit correctly.
        ReleaseObj(activeSheet);
        ReleaseObj(workbook);
        ReleaseObj(workbooks);
        excel.Quit();
        ReleaseObj(excel);
    }

如果不这样做,该过程将保持打开状态。我不确定当它停滞不前时它正在做什么,但到了当天结束时它使用的CPU时间会变得非常高。

答案 2 :(得分:0)

我有类似的问题。我正在使用C#创建一个excel文件,其中有很多图表需要很长时间才能创建。如果用户在我的C#文件仍在写入时打开了现有的excel文件,则会导致抛出异常,我的应用程序将崩溃。

我用以下内容修复了它:

xlApp = new Application();
xlApp.IgnoreRemoteRequests = true;