2

ベロー関数は、Excel ファイルをフォーマットするために使用されますが、関数を実行した後、アプリケーション Excel が Try.. (アプリケーションを強制終了できません) から閉じません。

private void FormateExcelFile()
{
    try
    {
        int nI = 0;//For Loop
        string nFieldName = string.Empty;
        nUserName=  WindowsIdentity.GetCurrent().Name; //Get Windows Login User
        string reportFilenPath = Application.StartupPath + "\\OutPutFiles\\" + "NewTempFile.xls";
        string connString = "provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + reportFilenPath + "';Extended Properties=Excel 8.0;";
        DataTable parts = new DataTable();
        using (OleDbConnection conn = new OleDbConnection(connString))
        {
            string sqlParts = "Select * from [" + nSheetName + "]";
            OleDbDataAdapter adapter = new OleDbDataAdapter(sqlParts, conn);
            adapter.Fill(parts);
        }

        for (nI = 0; nI < parts.Columns.Count; nI++)
        {
            DataColumn column = parts.Columns[nI];
            if (nI == 0) { nFieldName = column.ColumnName; }
            else { nFieldName = nFieldName + "," + column.ColumnName; }
        }
        parts.Dispose(); parts = null;

        oExcel = new Excel.Application();
        oBook = oExcel.Workbooks.Open(reportFilenPath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
        oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oBook.Worksheets.get_Item(nSheetName.Replace("$", ""));
        oExcel.DisplayAlerts = false;
        oExcel.Visible = true;



        //Check the Field Is Avilable in the Sheet if not then Add
        if (nFieldName.Contains("Sub Device") == false)
        {
            nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Sub Device";
        }
        if (nFieldName.Contains("Brand") == false)
        {
            nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Brand";
        }
        if (nFieldName.Contains("Model") == false)
        {
            nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Model";
        }
        if (nFieldName.Contains("Product Details") == false)
        {
            nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Product Details";
        }
        if (nFieldName.Contains("Price") == false)
        {
            nRng = (Excel.Range)oSheet.Cells[1, 1];
            //nRng = oSheet.get_Range("A1", oMissing);
            nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
            oSheet.Cells[1, 1] = "Price";
        }

        oBook.Save();
        oBook.Close(false, oMissing, oMissing);
        oExcel.DisplayAlerts = true;
        releaseObject(oSheet);
        releaseObject(oBook);
        oExcel.Quit();
        releaseObject(oExcel);
        releaseObject(nRng);
        nRng = null;
        oExcel = null;
        oSheet = null;


    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        releaseObject(oSheet);
        releaseObject(oBook);
        //oExcel.Quit();
        releaseObject(oExcel);
    }
}

private void releaseObject(object obj)
{
    try
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null;
    }
    catch (Exception ex)
    {
        obj = null;
        MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
    }
    finally
    {
        GC.Collect();
    }
}
4

4 に答える 4

1

参照しているすべての Excel オブジェクトを解放する必要があります。例えば:

if (nFieldName.Contains("Sub Device") == false)
{
    nRng = oSheet.get_Range("A1", oMissing);
    nRng.EntireColumn.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
    oSheet.Cells[1, 1] = "Sub Device";
}

次のようにする必要があります(簡単にするためにtry/finallyを省略します)

if (nFieldName.Contains("Sub Device") == false)
{
    nRng = oSheet.get_Range("A1", oMissing);
    var col = nRng.EntireColumn
    col.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, false);
    var cells = oSheet.Cells;
    var firstCell = cells[1,1];
    firstCell.Value = "Sub Device";

    Marshal.ReleaseComObject(nRng);
    Marshal.ReleaseComObject(col);
    Marshal.ReleaseComObject(cells);
    Marshal.ReleaseComObject(firstCell);

}

同様に:

oBook = oExcel.Workbooks.Open(reportFilenPath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oBook.Worksheets.get_Item(nSheetName.Replace("$", ""));

する必要があります:

oBooks = oExcel.Workbooks
oBook = oBooks.Open(...);
oSheets = oBook.Worksheets
oSheet = oSHeets.get_Item(...);

また、oBook と oSheets をリリースする必要があります。

于 2012-10-09T13:48:54.193 に答える
0

Excelの相互運用機能で同じような問題が発生しました。問題はこの種の線によって引き起こされるべきです(少なくとも私の場合はそうでした):

oBook = oExcel.Workbooks.Open(reportFilenPath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false); 

結局、あなたはoBookを実現しますが、これが実際にここで起こっていることです。開いたワークブックをoBookが指すようにするために、(を使用してoExcel.Workbooks)Workbooksオブジェクトにアクセスしました。これはリリースされることはなく、Excelが終了するのを防ぎます。

その行を次のように書き直すことで問題を解決しました。

Microsoft.Interop.Excel.Workbooks oBooks = oExcel.Workbooks;
oBook = oBooks.Open(reportFilenPath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false); 
releaseObject(oBooks);

もちろん、これはこの種のすべての行(たとえば、、など)に対して実行する必要がありoBook.Worksheets.get_Item(...)ますnRng.EntireColumn.Insert(...)

于 2012-10-09T13:32:35.693 に答える
0

次の行を削除します。

nRng = null;
oExcel = null;
oSheet = null;

Excel オブジェクトを解放していると思います。その後、それを null に等しくすることで、マシン上で新しいインスタンスを開始する Excel で何かを行っています。

オブジェクトを解放した後、変数を null または run に設定する必要はありませんGC.Collect();。ガベージ コレクターがこれを処理します。この例では、管理対象オブジェクトを自分でクリーンアップしようとしていると思います (管理されていない Excel オブジェクト) が実際に問題を引き起こしています。

于 2012-10-09T09:27:30.840 に答える
0

次のコマンドで Excel タスクを終了してみてください。

        Marshal.FinalReleaseComObject(sheet);
        app.DisplayAlerts = false; //Very important!
        range = null;
        sheet = null;
        // Garbage collecting
        GC.Collect();
        GC.WaitForPendingFinalizers();
        book.Close(false, Missing.Value, Missing.Value);
        Marshal.FinalReleaseComObject(book);
        book = null;
        app.Quit();
        Marshal.FinalReleaseComObject(app);
        app = null;

Excelファイルへのアクセスで同じ問題が発生しましたが、表示されたコードでは常に閉じます。

もちろん、プログラムがコードに到達する前にクラッシュした場合は、デバッガーでコードを確認してください。

あなたの場合: 本 --> oBook、アプリ --> oExcel、シート --> oSheet。

于 2012-10-09T09:20:39.513 に答える