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

■34607 / 親記事)  [VB.NET]Excelのプロセスが終了しない
  
□投稿者/ FireFairy 一般人(1回)-(2021/01/06(Wed) 17:14:02)
  • アイコン環境/言語:[Win10 64bit VB.NET Ver3.5] 
    分類:[.NET] 

    いつも参考にさせて頂いており、初めて投稿いたします。
    何卒よろしくお願いいたします。
    
    タイトルの件についてですが、
    取得したデータをExcelに出力し、列を自動調整する処理を書いています。
    複数のシートが作成されますのでシート毎に列を自動調整するよう処理を記載しています。
    以下コードで右向き矢印の処理が原因でExcelのプロセスが残ってしまいます。
    
    先輩方にお力をお借りしたく初投稿させて頂きました。
    恐縮ですが何卒よろしくお願いいたします。
    
    
    以下にコードを抜粋いたします。
    '--------------------------------------
    '----------Excel 列の自動調整----------
    Dim xlApp As New Excel.Application
    Dim xlBooks As Excel.Workbooks = xlApp.Workbooks
    Dim xlBook As Excel.Workbook = xlBooks.Open(IO.Path.Combine(FolderBrowserDialog.SelectedPath, StrExcelFileName))
    Dim xlSheets As Excel.Sheets = xlBook.Worksheets
    Dim xlSheet As Excel.Worksheet
    Dim xlCells As Excel.Range
    Dim xlRange As Excel.Range
    
    For i = 1 To xlSheets.Count
    
        xlSheet = xlSheets(i)
        xlCells = xlSheet.Cells(1, i)
    →  xlRange = xlSheet.Range("A1", xlCells)
        xlRange.EntireColumn.AutoFit()
    
        'MRComObject(xlRange)
        MRComObject(xlCells)
        MRComObject(xlSheet)
    Next
    MRComObject(xlSheets)
    xlBook.Save()
    xlBook.Close()
    MRComObject(xlBook)
    MRComObject(xlBooks)
    xlApp.Quit()
    MRComObject(xlApp)
    '----------Excel 列の自動調整----------
    '--------------------------------------
    
    
    Private Sub MRComObject(ByRef objCom As Object)
        Try
    
            If Not objCom Is Nothing AndAlso System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
                Dim i As Integer
                Do
                    i = System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
                Loop Until i <= 0
            End If
    
        Catch ex As Exception
    
    
        Finally
    
            objCom = Nothing
        End Try
    End Sub

マルチポストを報告
違反を報告
引用返信 削除キー/
■34608 / ResNo.1)  Re[1]: [VB.NET]Excelのプロセスが終了しない
□投稿者/ 魔界の仮面弁士 大御所(1310回)-(2021/01/06(Wed) 18:54:31)
  • アイコン
    2021/01/06(Wed) 18:57:40 編集(投稿者)
    
    ■No34607に返信(FireFairyさんの記事)
    > 複数のシートが作成されますのでシート毎に列を自動調整するよう処理を記載しています。
    > 以下コードで右向き矢印の処理が原因でExcelのプロセスが残ってしまいます。
    
    既に読まれているかもしれませんが、下記の記事を紹介しておきます。
    http://hanatyan.sakura.ne.jp/vb2005/vb2013excel01.htm
    
    
    > Sub MRComObject(ByRef objCom As Object)
    この実装だと、Option Strict On モードで使えないのが難点ですね。
    
    上記記事にあるように、
     Sub MRComObject(Of T As Class)(ByRef objCom As T)
    などとしておくと、Option Strict On にも対応できるようになります。
    
    
    
    とりあえず修正案。
    
    
    For i = 1 To xlSheets.Count
        Dim xlSheet As Excel.Worksheet = xlSheets(i)
        Dim xlCells1 As Excel.Range = xlSheet.Cells
        Dim xlCells2 As Excel.Range = xlCells1(1, i)
        Dim xlCells3 As Excel.Range = xlSheet.Range("A1", xlCells2)
        Dim xlCells4 As Excel.Range = xlCells3.EntireColumn
        xlCells4.AutoFit()
        MRComObject(xlCells4)
        MRComObject(xlCells3)
        MRComObject(xlCells2)
        MRComObject(xlCells1)
        MRComObject(xlSheet)
    Next
    
    
    
    以下説明。
    
    
    
    >     xlCells = xlSheet.Cells(1, i)
    ここがまず最初の修正箇所。
    
    上記ではこれを
        xlCells1 = xlSheet.Cells
        xlCells2 = xlCells1(1, i)
    という二段階の処理に分けています。Workbooks や Worksheets と同じですね。
    
    Cells プロパティの定義は、引数 2 つを伴った
     Public Property Cells(rowIndex As Integer, colIndex As Integer) As Excel.Range
    ではなく、引数を持たない
     Public Property Cells() As Excel.Range
    な定義であることに注意してください。
    
    
    > →  xlRange = xlSheet.Range("A1", xlCells)
    
    書き方としては問題無いのですが、上記のように、
    「COM オブジェクトを引数に渡すメソッドやプロパティ」を呼び出す処理では、
    引数に渡された COM オブジェクト(つまり xlCells2) の参照カウントが
    意図せず増加してしまうケースが稀にあります。
    (特に、Object 型を通じてレイトバインドしている場合に発生しやすいです)
    
    意図せず増加してしまった参照カウントは、Marshal.ReleaseComObject を
    一回呼び出すだけでは十分に解放しきれません。このようなケースでは、
    Marshal.FinalReleaseComObject メソッドを使って強制解放することができます。
    
    ちなみに FinalReleaseComObject を持たない .NET Framework 1.x 世代の場合には、
    今回提示頂いたソースのように、ReleaseComObject の戻り値が 0 になるまで
    解放処理を繰り返すことで代用できます。
    
    
    >    xlRange.EntireColumn.AutoFit()
    これは「.」が二回連なっているため、EntireColumn の解放が遅れる可能性があります。
    これも変数に受けて、キチンと解放するようにしましょう。

違反を報告
引用返信 削除キー/
■34609 / ResNo.2)  Re[2]: [VB.NET]Excelのプロセスが終了しない
□投稿者/ FireFairy 一般人(2回)-(2021/01/07(Thu) 08:24:17)
  • アイコン
    魔界の仮面弁士様
    ご教示ありがとうございました。
    
    修正案の通りにコードを反映したらプロセスが残らないようになりましたので解決いたしました。
    そして教えいただいたサイトも参考にさせていただきます
    
    またお世話になることがあるかもしれませんが、その時は何卒よろしくお願いいたします。

解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -