2

プログラムの実行後にExcelインスタンスを削除するためのヒントをここで探しましたが、どの提案も機能していないようです。最初に実行すると、Excelのインスタンスが作成されますが、プログラムの実行中にボタンをクリックしてこのコードを再実行します。Excelの別のインスタンスを作成しますが、今回は作成したインスタンスを削除し、プログラムが最初に実行されたときに作成されたインスタンスのみを残します。

私がコードのために持っているのはこれまでのところこれです: (2012年9月14日時点で更新されたコード)

Private Sub GetBatchFileContents()

    Dim xlApp As Excel.Application
    Dim xlWB As Excel.Workbook
    Dim xlWS As Excel.Worksheet
    Dim xlRan As Excel.Range
    Dim xlVal(,) As Object
    Dim lastRow As Int32

    xlApp = New Excel.Application()
    xlWB = xlApp.Workbooks.Open(TextBox1.Text.ToString(), _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing, _
                                Type.Missing)
    xlWS = xlWB.Worksheets.Item(1)
    lastRow = xlWS.Cells(xlWS.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row
    xlRan = xlWS.Range(xlWS.Cells(1, 1), xlWS.Cells(lastRow, 130))
    xlVal = xlRan.Value2()
    ReleaseObj(xlRan)
    ReleaseObj(xlWS)
    xlWB.Close(False, Type.Missing, Type.Missing)
    ReleaseObj(xlWB)
    xlApp.Quit()
    ReleaseObj(xlApp)

End Sub

Private Sub ReleaseObj(ByRef obj As Object)

    Try
        Marshal.FinalReleaseComObject(obj)
    Catch ex As Exception
        Stop
    Finally
        obj = Nothing
    End Try

    GC.Collect()
    GC.WaitForPendingFinalizers()
    GC.Collect()

End Sub

フィードバックをよろしくお願いします!

4

2 に答える 2

1

あなたが説明したものと非常によく似た問題がありました。このサンプルコードを使用することで、うまくいきました

' set all Excel related  objects to nothing
columnHeaders = Nothing
range = Nothing
endCell = Nothing
startCell = Nothing
excelSheet = Nothing
excelSheets = Nothing
excelWorkbook.Close()
excelWorkbook = Nothing
excelApp.Quit()
' release com ressources 
 Marshal.FinalReleaseComObject(excelApp)  ' !

excelApp = Nothing
GC.Collect()
GC.WaitForPendingFinalizers()

MSDNFinalReleaseComObject の およびを参照してくださいReleaseComObject

編集

Private Sub GetBatchFileContents()
    Dim xlApp As Excel.Application
    Dim xlWB As Excel.Workbook
    Dim xlWS As Excel.Worksheet
    Dim xlRan As Excel.Range
    Dim xlVal(,) As Object
    Dim lastRow As Int32

    xlApp = New Excel.Application()
    xlWB = xlApp.Workbooks.Open(TextBox1.Text.ToString(), _
                                Type.Missing, Type.Missing,  Type.Missing,  Type.Missing,  Type.Missing, _
                                Type.Missing,  Type.Missing,  Type.Missing, Type.Missing, Type.Missing, _
                                Type.Missing,  Type.Missing, Type.Missing,  Type.Missing)
    xlWS = xlWB.Worksheets.Item(1)

    ' original
    'lastRow = xlWS.Cells(xlWS.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row

    ' new
    Dim range1 As Excel.Range
    range1 = xlWS.Cells(xlWS.Rows.Count, 1)
    Dim range2 As Excel.Range
    range2 = range1.End(Excel.XlDirection.xlUp)
    lastRow = range2.Row
    ReleaseObj(range1)
    ReleaseObj(range2)

    ' original
    'xlRan = xlWS.Range(xlWS.Cells(1, 1), xlWS.Cells(lastRow, 130))

    ' new
    Dim range1_1 As Excel.Range
    range1_1 = xlWS.Cells(1, 1)
    Dim rangeLastRow_130 As Excel.Range
    rangeLastRow_130 = xlWS.Cells(lastRow, 130)
    xlRan = xlWS.Range(range1_1, rangeLastRow_130)
    ReleaseObj(range1_1)
    ReleaseObj(rangeLastRow_130)

    ' unchanged
    xlVal = xlRan.Value2()
    ReleaseObj(xlRan)
    ReleaseObj(xlWS)
    xlWB.Close(False, Type.Missing, Type.Missing)
    ReleaseObj(xlWB)
    xlApp.Quit()
    ReleaseObj(xlApp)
End Sub

コードを変更して、可能なすべての COM インスタンスを変数に割り当て明示的に解放しました。しかし、私のコンピューターでは問題なく動作するため、テストすることはできません。

さらに、あなたの行動の原因を説明している記事を見つけました。

Excel は管理された AddIn(Shared AddIn または VSTO AddIn)を読み込みますが、これは規則に違反しています。アプリケーションが Excel アプリケーションを自動化した後、ロードされたアドインの基になる RCW が解放されていないため、Excel アプリケーションが正しく終了できませんでした。この状態では、オートメーション クライアントが終了しても Excel は終了しません。したがって、この種の問題をトラブルシューティングする手順は、根本原因を特定するためにすべてのアドインを無効にすることです.´(詳細については記事を参照してください)

私の提案の 1 つがあなたのために働くかどうか私に知らせてください!

于 2012-09-13T19:55:10.553 に答える
0

私がやったことの基本的な概要。Workbooks 機能の全体像で、このロジックをロック ダウン プロセスに組み込みました。Echo をオフにする必要がありました。そうしないと、エンド ユーザーが 2 つのインスタンス間で派手なやり取りをするようになりました。ここで使用できるものが必ずあります;)。

これが私のプロジェクトsrcwb.Close SaveChanges:=Falseで使用したすべてであり、ファイルを閉じました。私が過去に行ったことは、オブジェクト参照をApplication取得して、インスタンスのシステム ID を取得し、アプリケーションから閉じることができるようにすることです。もちろん、これはコード ビハインドの VBA/プロジェクト コントロールがあり、単なるフラット データ ファイルではないことを前提としています。

それ以外の場合は、親ファイルにコレクション オブジェクトを作成し、新しいインスタンスを開いてそのアプリケーション インスタンスをコレクションに格納し、定期的にコレクションを実行して、インスタンスが有効かどうかを確認する必要があります。

于 2012-09-20T16:14:45.860 に答える