1

DB にクエリを実行し、結果を Excel ファイルに出力する C# アプリケーションを作成しました。プログラム自体は正常に動作します。ただし、アプリケーションの実行中にまったく関係のない 2 つ目の Excel ファイルを開くと、例外が発生してプロセスが停止します。

ここで、プログラム自体で可視性を false に設定しました。2 番目の無関係な 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 の同じインスタンスを相互運用機能を使用してインタラクティブに使用しているときに、この問題を見てきました。

Marshal.GetActiveObject("Excel.Application")

あなたの場合、次を使用して Excel の新しいインスタンスを作成しています。

exc = new Application();

すべきことは、このインスタンスをできるだけ早く閉じるようにすることです。このKB 記事で説明されている問題のため、これは必ずしも簡単ではありません。それ以外の場合は、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);
    }

そうしないと、プロセスが開いたままになります。スタックしたままになっているときに何をしているのかはわかりませんが、1日の終わりまでに、使用されるCPU時間がかなり高くなる可能性があります.

于 2012-07-13T20:19:42.973 に答える