DOBON.NETプログラミング道掲示板

No35247 の記事


■35247 / )  Re[3]: Excel Com オブジェクトの増殖
□投稿者/ 魔界の仮面弁士 大御所(1488回)-(2022/11/27(Sun) 11:36:26)
  • アイコンNo35241に返信(たこさんの記事)
    > xlsWorkSheet = xlsWorkSheets.Item(1)
    .Item の戻り値は Object のはずですので、明示的にキャストしましょう。

    参照カウントが不用意に増加することを防ぐため、可能であれば
    「Option Strict On」で実装することをお奨めします。

    たとえば「Range オブジェクトを引数に受け取るプロパティやメソッド」に対して
    Range 型の変数ではなく Object 型の変数を通じて受け渡した場合、
    相互運用機能アセンブリによる内部的な型判定の時点で参照カウントが増加し、
    解放漏れにつながることがあります。

    もしもレイトバインド前提で実装するのなら、.NET ではなく
    VBS や VBA から利用した方が安全です。


    No35245に返信(たこさんの記事)
    >   Public Sub Sheets(strSheetName As String)
    >     xlsWorkSheet = xlsApplication.Sheets(strSheetName)
    >     If SheetVisible Then xlsWorkSheet.Select()
    >   End Sub

    案の定、Sheets メソッドに原因がありそうですね。

    xlsWorkSheet = xlsApplication.Sheets(strSheetName) ではなく
    xlsWorkSheet = xlsWorkSheets(strSheetName) でしょう。


    ただし上記は厳密には同義ではありません。
    xlsWorkSheets は WorkBook_Open 時に
     xlsWorkSheets = xlsWorkbook.Worksheets
    で代入されていますので、strSheetName の処理対象が
    「WorkBook_Open 時のワークブック」のシートではなく
    「現在アクティブなワークブック」のシートの操作を意図しているなら
      Dim wBook = xlsApplication.ActiveWorkbook
      Dim wSheets = wBook.Sheets
      xlsWorkSheets = wSheets(strSheetName)
      MRComObject(wSheets)
      MRComObject(wBook)
    といった形になるかと思います。



    いずれの方法をとるにせよ、xlsWorkSheet の初期値は
    xlsWorkSheets.Item(1) だったはずなので、xlsWorkSheet 変数への
    代入前に MRComObject(xlsWorkSheet) も呼んでおく必要があります。


    Dim x As New Excel.Application()
    Dim y As Excel.Workbooks = x.Workbooks
    Dim z As Excel.Workbooks = x.Workbooks

    MsgBox(y Is z) 'これは True ではなく、False になる可能性が高い

    x.Quit()
    Trace.WriteLine(Marshal.ReleaseComObject(z))
    Trace.WriteLine(Marshal.ReleaseComObject(y))
    Trace.WriteLine(Marshal.ReleaseComObject(x))
違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -