エクセルのオブジェクト解放がうまくいかないです。

解決


  2006-07-04 02:24:06  No: 132180

前々ログ↓
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200606/06060105.txt
前ログ↓
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200607/06070004.txt

  'エクセルアプリケーションの生成
        Dim xlApplication As New Excel.Application
        Dim xlBooks As Excel.Workbooks = xlApplication.Workbooks
        '新規のファイルを開く場合
        Dim xlBook As Excel.Workbook = xlBooks.Add
        Dim xlSheets As Excel.Sheets = xlBook.Worksheets
        Dim xlSheet As Excel.Worksheet = xlSheets.Item(1)

        Dim intX As Integer
        Dim intY As Integer

        'エクセルを非表示
        xlApplication.Visible = False

        'Rangeを生成
        Dim xlRange As Excel.Range
        Dim strData(,) As Object

        ReDim Preserve strData(UBound(strAry), UBound(strAry, 2))

        'ループ文作成
        For intX = 0 To UBound(strAry)

            For intDataCnt = 0 To UBound(strAry, 2)

                xlRange = xlSheet.Range("E18:A10")  'データの入力セル範囲

                'データをエクセルに貼り付ける
                strData(intX, intDataCnt) = strAry(intX, intDataCnt)
                xlRange.Value = strData          'セルへデータの入力

            Next
        Next

        ''苗字と名前を取得するSQL文
        'strSql = "SELECT USER_ID, CONCAT(CONCAT(F_NAME, ' '), S_NAME) AS NM FROM ATD_USER"
        'strSql &= " WHERE DEL_FLG = 0"

        ''投げたSQLを実行して取得する関数
        'If getData(strSql, 2, strAry, intDataCnt) = False Then
        '    End
        'End If

      

        xlApplication.WindowState = Excel.XlWindowState.xlMaximized

        'エクセルを表示
        xlApplication.Visible = True

        xlSheet.PrintOut(From:=1, Preview:=True, Collate:=True)
        
        ''Excel を終了する
        'xlApplication.Quit()

        ComObjectRelease(xlRange)
        ComObjectRelease(xlSheet)            'xlSheet の解放
        ComObjectRelease(xlSheets)
         xlBook.Close(False)
        ComObjectRelease(xlBook)
        ComObjectRelease(xlBooks)
        ComObjectRelease(xlApplication)
「ここに↓の処理を入れました
http://www.bcap.co.jp/hanafusa/dotnet/Excel01.htm

    End Sub
    'COMオブジェクトを全部解放する関数
    Private Sub ComObjectRelease(ByRef objCom As Object)
        'COM オブジェクトの使用後、明示的に COM オブジェクトへの参照を解放する
        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
        Finally
            '参照を解除する
            objCom = Nothing
        End Try
    End Sub

いつもお世話になっております。良です。
このプログラムを実行してオブジェクトがどのくらい残っているか
試したんですが10個のオブジェクトが残っています。
というメッセージが出ました。
イミディエイトウィンドウで確かめたら

?localbyname
{Length=10}
    (0): {System.Diagnostics.Process}
    (1): {System.Diagnostics.Process}
    (2): {System.Diagnostics.Process}
    (3): {System.Diagnostics.Process}
    (4): {System.Diagnostics.Process}
    (5): {System.Diagnostics.Process}
    (6): {System.Diagnostics.Process}
    (7): {System.Diagnostics.Process}
    (8): {System.Diagnostics.Process}
    (9): {System.Diagnostics.Process}

ってなりました。何が解放抜けているんでしょうか?


  2006-07-04 02:26:43  No: 132181

すみません
 ''Excel を終了する
        'xlApplication.Quit()
この処理は書いていないです。


特攻隊長まるるう  2006-07-04 02:42:48  No: 132182

[VBレスキュー(花ちゃん) .NETからExcelの基本的な操作方法]
http://www.bcap.co.jp/hanafusa/dotnet/Excel01.htm
>1.MicroSoft Excelを起動(新規ファイルを開く)
>     〜
>    MRComObject(xlRange1)               'xlRange1 の解放(都度解放しないとだめ)

から考えれば、ループの中で
>                xlRange = xlSheet.Range("E18:A10")  'データの入力セル範囲
はマズイねぇ。
>                xlRange.Value = strData          'セルへデータの入力
で使用し終わったら解放しておかないと。。。

関係無いけど
>UBound(strAry)
は[VB.NET]風にすると
  strAry.GetLength(0) - 1
とかになります。


  2006-07-04 03:24:39  No: 132183

こんばんは良です。

> xlRange = xlSheet.Range("E18:A10")  'データの入力セル範囲
>はマズイねぇ。

やはりまずいですか?
ループの中を

    'ループ文作成
        For intX = 0 To strAry.GetLength(0) - 1
            For intDataCnt = 0 To strAry.GetLength(1) - 1
                xlRange = xlSheet.Range("E18:A10")  'データの入力セル範囲

                'データをエクセルに貼り付ける
                strData(intX, intDataCnt) = strAry(intX, intDataCnt)
                xlRange.Value = strData          'セルへデータの入力

                ComObjectRelease(xlRange)

            Next
        Next

に変えてもやはり8個ぐらいオブジェクトが残っているんですよ。
やはりxlRange = xlSheet.Range("E18:A10")  'データの入力セル範囲
を変えたほうがよろしいんでしょうか?
でもその場合にうまいループの仕方がわからないんですよ。
rangeのなかに(strAry.GetLength(0) - 1,strAry.GetLength(1) - 1)
って入れてみましたがだめでした。


  2006-07-04 03:32:56  No: 132184

ComObjectRelease(xlRange)
のところを

System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
に変えてもうまく解放されずに残ってしまいました。

xlRange = xlSheet.Range("E18:A10")  
のところをどううまくシートの貼り付け番号を指定したらよろしいでしょうか?


  2006-07-04 03:43:32  No: 132185

'ループ文作成
        For intX = 0 To strAry.GetLength(0) - 1
            For intDataCnt = 0 To strAry.GetLength(1) - 1
                Dim xlCells As Excel.Range
                xlCells = xlSheet.Cells

                'データをエクセルに貼り付ける
                strData(intX, intDataCnt) = strAry(intX, intDataCnt)

             ☆ xlRange = xlCells(intX, intDataCnt)
                xlRange.Value = strData          'セルへデータの入力

                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
            Next

        Next

ってやりましたら☆のところで
「'System.Runtime.InteropServices.COMException' のハンドルされていない例外が mscorlib.dll で発生しました。

追加情報 : HRESULT からの例外です : 0x800A03EC。」
って言うエラーが出ました。
cellsのなかに変数を入れて指定するのはまずいですか?


特攻隊長まるるう  2006-07-04 03:56:18  No: 132186

>でもその場合にうまいループの仕方がわからないんですよ。
というかオイラには、ループの中でセルの同じ範囲を何度も何度も
設定するほうがよく分からないんですが。。。
        Dim xlRange As Excel.Range
        Dim xlSheet As Excel.Worksheet
        Dim strAry(,) As String
        Dim objData(,) As Object
        Dim intX, intDataCnt As Integer

        xlRange = xlSheet.Range("E18:A10")  'データの入力セル範囲

        ' 書込み用データの作成(ループの中でエクセルのオブジェクトは関係なし)
        For intX = 0 To strAry.GetLength(0) - 1
            For intDataCnt = 0 To strAry.GetLength(1) - 1
                objData(intX, intDataCnt) = strAry(intX, intDataCnt)
            Next
        Next

        'データをエクセルに貼り付ける
        xlRange.Value = objData          'セルへデータの入力
        ComObjectRelease(xlRange)

>に変えてもやはり8個ぐらいオブジェクトが残っているんですよ。
プログラム実行前
>  'エクセルアプリケーションの生成
の前に
>「ここに↓の処理を入れました
>http://www.bcap.co.jp/hanafusa/dotnet/Excel01.htm
の処理を実行して8個だというオチはやめてね?

あとは、もう
http://www.bcap.co.jp/hanafusa/dotnet/Excel08.htm
に書いてあるように、単純なプログラムから順に解放できているか?
を確認しながらコードを追加していくしかないですねぇ。
ぱっと見て分かる修正点は出しましたので、場所が特定できないと。。。


  2006-07-04 04:15:33  No: 132187

>特攻隊長まるるうさん

いつもありがとうございますm(__)m
まるるうさんのやり方でやってもオブジェクトは
残っているみたいなので
もっと細かく切断して
処理を分けてオブジェクトを解放してみます。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加