VB Excel操作テクニック.NET

VBでExcelを読込み、操作するテクニック集。貼付だけで機能するソースコードも公開。
COMが解放されない現象を防ぐExcel操作クラスを作成する
COMが解放されない現象を防ぐExcel操作クラスを作成する

COMが解放されない現象を防ぐExcel操作クラスを作成する

ここで紹介するのは、単純に1つのExcelファイルを編集するクラスを作るとき、
私がいつも使っているクラスの構成ルールを公開します。

以下のルールに従って作成すれば、COMの解放ができず
プロセスが残ってしまう。という現象を軽減させることができるはずです。

● ルール1 クラスの構成
まず、私がExcel1ファイルの操作を前提とした操作クラスを作るとき、
クラスの作成」で公開しているように、
クラス変数でWorksheetオブジェクトまでを宣言します。

● ルール2 メソッド・プロパティのルール
そして各メソッドやプロパティで、必要に応じてRangeやCellsを作って処理を作成し、
原則、そのメソッド内で作ったインスタンスはそのメソッド内で解放する。
というルールで作るようにします。

● ルール3 COM解放メソッド
ここが一番書きたかった部分です。
これはルールというか、COMの解放忘れや解放順の間違いを予防するため
私がいつも用意するようにしている必須のメソッドです。
EnumReleaseTypeは、メソッド呼び出し用に用意したものです。(説明は省略します)

ルール2で記述した通り、基本的にメソッドやプロパティではRangeやCellsを
中心に操作していますが、シート切り替えやBOOKを閉じるときなど、
WorkSheetオブジェクトより上位のオブジェクトを操作する場面も出てきます。

たとえばBOOKを閉じるとき、COMオブジェクトの解放は
WorkSheet → Sheets → WorkBook → WorkBooks
の順で、一度オブジェクトを解放してから再度作り直す必要があります。
上記の解放順で、1つでも忘れていたり、順番が逆転していたりすると
タスクマネージャにプロセスが残ったままになることがあります。

そこで、解放時には下のReleaseXlsComObjectメソッドを使用します。
解放したい単位でEnumの値を指定して呼び出すようにしています。

これを用意しておくだけで、WorkSheetより上位のオブジェクトを解放する際、
気をつかって確認しながら処理を記述する手間が省けます。
また、各メソッドがスッキリしてかなり見やすくなります。


''' <summary>
''' ReleaseExcelComObjectメソッドの引数用
''' </summary>
''' <remarks></remarks>
Private Enum EnumReleaseType
    Sheet
    Sheets
    Book
    WorkBooks
    App
End Enum

''' <summary>
''' COMオブジェクトの解放処理まとめ
''' </summary>
''' <remarks></remarks>
Private Sub ReleaseXlsComObject(ByVal ReleaseType As EnumReleaseType)

    Try
        ' xlSheet解放
        If Not xlSheet Is Nothing Then
            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
            xlSheet = Nothing
        End If

        If ReleaseType = EnumReleaseType.Sheet Then
            Exit Sub
        End If

        ' xlWorkSheets解放
        If Not xlSheets Is Nothing Then
            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
            xlSheets = Nothing
        End If

        If ReleaseType = EnumReleaseType.Sheets Then
            Exit Sub
        End If

        ' xlBook解放
        If Not xlBook Is Nothing Then
            Try
                xlBook.Close()
            Finally
                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
                xlBook = Nothing
            End Try
        End If

        If ReleaseType = EnumReleaseType.Book Then
            Exit Sub
        End If

        ' xlBooks解放
        If Not xlBooks Is Nothing Then
            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
            xlBooks = Nothing
        End If

        If ReleaseType = EnumReleaseType.WorkBooks Then
            Exit Sub
        End If

        ' xlApp解放
        If Not xlApp Is Nothing Then
            Try
                ' アラートを戻す
                xlApp.DisplayAlerts = True
                xlApp.Quit()
            Finally
                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
            End Try
        End If

    Catch ex As Exception
        Throw
    End Try

End Sub


'

« »