1

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

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

任何人都知道是什么导致了问题或如何解决它?

相关部分代码如下,异常发生在 worksheet.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');
        }
4

3 回答 3

2

看看这个线程

看起来您的错误是 VBA_E_IGNORE,在这种情况下,您需要注册一个 IMessageFilter 实现,以便您可以实现重试逻辑。

我过去曾看到过这个问题,当使用具有互操作性和交互性的相同 Excel 实例时 - 例如,在使用以下方法实例化 Excel 应用程序对象时:

Marshal.GetActiveObject("Excel.Application")

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

exc = new Application();

您应该尝试做的是确保尽快关闭此实例。由于这篇知识库文章中描述的问题,这并不总是那么容易。否则,您可能会考虑将 COM Interop 以外的东西写入 Excel(例如 OLEDB 或第三方库,如 Aspose 或 EPPlus)。

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

于 2012-07-14T15:14:49.740 回答
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 时间会变得相当高。

于 2012-07-13T20:19:42.973 回答
0

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

我用以下方法修复了它:

xlApp = new Application();
xlApp.IgnoreRemoteRequests = true;
于 2016-10-04T16:00:12.280 回答