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

No35241 の記事


■35241 / )  Excel Com オブジェクトの増殖
□投稿者/ たこ 一般人(15回)-(2022/11/27(Sun) 04:14:52)
  • アイコン環境/言語:[[Windows10 VB.NET .NET Framework 4.7.2 VS2019]] 
    分類:[.NET] 

    環境追記
    [Office 365 Excel バージョン2210]
    [Microsoft Excel 16.0 Object Library]


    いつもお世話になっております。

    今回Excelの既存データをまとめようと思いまして、
    VB.NETのExcel Comオブジェクトを使用して2枚のExcelを開いて処理しています。

    Excelの処理部分はクラスにまとめ処理していますが、タスクマネージャーで見ると閉じたはずのExcelが残っています。
    いろいろやってみましたが解決できず、お知恵をお借りしたいと投稿致します。


    <参考にしたサイト>
    https://hironimo.com/prog/vbnet/vb-net-excel/
    https://oreno-it2.info/archives/1043
    http://vbnettips.blog.shinobi.jp/file-folder/excel%20%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E6%93%8D%E4%BD%9C%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%EF%BC%88microsof
    http://hanatyan.sakura.ne.jp/vb2005/vb2013excel01.htm
    http://up-up-everyday.cocolog-nifty.com/wanco_programming/2015/07/vbnetexcel-81a4.html


    ExcelExクラス(抜粋)
    ----------------------------------------------------------------------------------------------------
      'Excel のアプリケーション参照用オブジェクト
      Friend xlsApplication As Excel.Application = Nothing
      'Excel の Workbooks 参照用オブジェクト (Workbook の Collection)
      Friend xlsWorkbooks As Excel.Workbooks = Nothing
      'Excel の Workbooks 内の1個の Workbook 参照用オブジェクト
      Friend xlsWorkbook As Excel.Workbook = Nothing
      'Excel の Workbook 内の Worksheets 参照用オブジェクト (Worksheet の Collection)
      Friend xlsWorkSheets As Excel.Sheets = Nothing
      'Excel の Sheets 内の1個の Worksheet 参照用オブジェクト
      Friend xlsWorkSheet As Excel.Worksheet = Nothing
      'Excel の Sheet 内の1個のセル Range 参照用オブジェクト
      Friend xlsRange As Excel.Range = Nothing

      Private _WorkBook As String = Nothing
      Private _WorkBookIsNew As Boolean = Nothing
      Public Property WorkBook As String
        Set(value As String)
          _WorkBook = value
          Select Case _WorkBook
            Case ""
              WorkBook_Open()
              _WorkBookIsNew = True
            Case "Close"
              _frgClose = True
              WorkBook_Close()
            Case "Save"
              xlsWorkbook.Save()
            Case "SaveAfterClose", "CloseBeforeSave"
              xlsWorkbook.Save()
              _frgClose = True
              WorkBook_Close()
            Case Else
              WorkBook_Open(_WorkBook)
              _WorkBookIsNew = False
          End Select
        End Set
        Get
          Return _WorkBook
        End Get
      End Property

      Private Sub WorkBook_Open(Optional ByVal strFileName As String = Nothing)
        'Excel アプリケーション起動
        xlsApplication = New Excel.Application
        'Excel の Workbooks 取得
        xlsWorkbooks = xlsApplication.Workbooks
        'Excel非表示
        xlsApplication.Visible = False
        xlsApplication.DisplayAlerts = False
        If IsNothing(strFileName) Then
          '新規 Excel ファイルを開く
          xlsWorkbook = xlsWorkbooks.Add()
        Else
          '既存 Excel ファイルを開く
          xlsWorkbook = xlsWorkbooks.Open(strFileName)
        End If
        'Excel の Worksheets 取得
        xlsWorkSheets = xlsWorkbook.Worksheets
        'Excel の Worksheet 取得
        xlsWorkSheet = xlsWorkSheets.Item(1)
        xlsWorkSheet.Select()
        xlsApplication.Visible = ExcelVisible
      End Sub

      Private Sub WorkBook_Close()
        '終了処理
        'xlsRange の解放
        MRComObject(xlsRange, True)
        'xlsWorkSheet の解放
        MRComObject(xlsWorkSheet, True)
        'xlsWorkSheets の解放
        MRComObject(xlsWorkSheets, True)
        'xlsWorkbookを閉じる
        If Not xlsWorkbook Is Nothing Then xlsWorkbook.Close()
        'xlsWorkbook の解放
        MRComObject(xlsWorkbook, True)
        'xlsWorkbooks の解放
        MRComObject(xlsWorkbooks, True)
        'Excelを閉じる
        If Not xlsApplication Is Nothing Then xlsApplication.Quit()
        'xlsApplication を解放
        MRComObject(xlsApplication, True)
      End Sub

      'COM オブジェクトへの参照を解放
      ''' <summary>
      ''' COMオブジェクトの参照カウントをデクリメントします。
      ''' </summary>
      ''' <typeparam name="T">(省略可能)</typeparam>
      ''' <param name="objCom">
      ''' COM オブジェクト持った変数を指定します。
      ''' このメソッドの呼出し後、この引数の内容は Nothing となります。
      ''' </param>
      ''' <param name="force">
      ''' すべての参照を強制解放する場合はTrue、現在の参照のみを減ずる場合はFalse。
      ''' </param>
      Friend Sub MRComObject(Of T As Class)(ByRef objCom As T, Optional ByVal force As Boolean = False)
        If objCom Is Nothing Then Return
        Try
          If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
            If force Then
              System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
            Else
              System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
            End If
          End If
        Finally
          objCom = Nothing
        End Try
      End Sub
    ----------------------------------------------------------------------------------------------------

    上記ExcelExクラスがベースクラスで、子クラス、孫クラスがあります。
    子クラスで、Data As Microsoft.Office.Interop.Excel.Rangeと言うヶ所があるので、
    (必要無いとは思っているものの)MRComObject(Data)と入れてあります。

    ちょっと書いている途中で思いついたので、ベースクラスのみ呼び出して閉じる…
    ----------------------------------------------------------------------------------------------------
      Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        ExEx1 = New ExcelEx()
        ExEx1.WorkBook = path & "Test.xlsx"
        ExEx1.xlsApplication.WindowState = Excel.XlWindowState.xlMaximized
        ExEx1.Sheets(1)
        ExEx1.WorkBook = "Close"
      End Sub
    ----------------------------------------------------------------------------------------------------
    を実行してもやはりゴミが残ります。

    Excelを閉じた時にプロセスは終了・削除されると思っているのですが、認識が違うのでしょうか…

違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -