- PR -

Excelオブジェクトの解放

投稿者投稿内容
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2005-10-13 16:38
引用:

変数xlNames宣言時と、xlNames.Add(こちらは解放不可)の
2カウントという意味ですよね?


Addメソッドが新しいNameオブジェクトを返すということでは?
「なぜ、xlName = xlNames.Add(〜)としないのか」はそういうことだと思いますが。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-13 16:55
こんにちは、じゃんぬ です。
ソースが CodingHorror ですがお許しください。

引用:

まっくさんの書き込み (2005-10-13 16:13) より:

ソースを次のようにしましたが、未だprocessが残ります。
他に暗黙的に参照されているのがあるのでしょうか?


うーん、私はこんな感じでやりましたが、プロセスはちゃんと消滅していました。
(悲惨ですね、このソースはw)

コード:

Private Shared Sub OneMethod()
    ' 必要な変数は Try の外で宣言する
    Dim xlApp As Excel.Application

    ' COM オブジェクトの解放を保証するために Try 〜 Finally を使用する
    Try
        xlApp = New Excel.Application()
        xlApp.Visible = True
        xlApp.DisplayAlerts = False

        Dim xlBooks As Excel.Workbooks = xlApp.Workbooks

        Try
            Dim xlBook As Excel.Workbook = xlBooks.Open("C:\Hoge.xls")

            Try
                Dim xlSheets As Excel.Sheets = xlBook.Worksheets

                Try
                    Dim xlSheet1 As Excel.Worksheet = DirectCast(xlSheets(1), Excel.Worksheet)

                    Try
                        Dim xlCells As Excel.Range = xlSheet1.Cells

                        Try
                            For i As Integer = 1 To 10
                                Dim xlRange As Excel.Range

                                Try
                                    xlRange = DirectCast(xlCells(i, 1), Excel.Range)
                                    xlRange.Value = i.ToString()

                                    Dim xlNames As Excel.Names = xlBook.Names

                                    Try
                                        Dim xlName As Excel.Name = xlNames.Add("name1", RefersToR1C1:="Sheet1!R1C1:R" & i.ToString() & "C1")

                                        Try
                                            '/ xlName を使用
                                        Finally
                                            If Not xlName Is Nothing Then
                                                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlName)
                                            End If
                                        End Try
                                    Finally
                                        If Not xlNames Is Nothing Then
                                            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlNames)
                                        End If
                                    End Try
                                Finally
                                    If Not xlRange Is Nothing Then
                                        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
                                    End If
                                End Try
                            Next i
                        Finally
                            If Not xlCells Is Nothing Then
                                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlCells)
                            End If
                        End Try
                    Finally
                        If Not xlSheet1 Is Nothing Then
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet1)
                        End If
                    End Try
                Finally
                    If Not xlSheets Is Nothing Then
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
                    End If
                End Try
            Finally
                If Not xlBook Is Nothing Then
                    Try
                        xlBook.Close()
                    Finally
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
                    End Try
                End If
            End Try
        Finally
            If Not xlBooks Is Nothing Then
                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
            End If
        End Try
    Finally
        If Not xlApp Is Nothing Then
            Try
                xlApp.Quit()
            Finally
                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
            End Try
        End If
    End Try
End Sub


いかがでしょうか?

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
まっく
会議室デビュー日: 2002/08/30
投稿数: 18
投稿日時: 2005-10-13 18:19
まどかさん、じゃんぬねっとさん
返信ありがとうございます。

引用:

うーん、私はこんな感じでやりましたが、プロセスはちゃんと消滅していました。
(悲惨ですね、このソースはw)



実行してみましたが、プロセスが消滅することを確認出来ました。
参考にさせて頂き、自分のソースに手を入れてみます。

まっく
会議室デビュー日: 2002/08/30
投稿数: 18
投稿日時: 2005-10-13 18:52
まっくです。

自己レスです。
namesオブジェクト操作の後、
直後で上位オブジェクトを解放すると
プロセスが消滅しました。

やり方は理解できたので助かりました。
ありがとうございます。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-13 19:25
引用:

まっくさんの書き込み (2005-10-13 18:52) より:

namesオブジェクト操作の後、
直後で上位オブジェクトを解放すると
プロセスが消滅しました。


ループでのオブジェクト解放を忘れていたのでしょうか?

ループで使いまわす場合でも、新しいオブジェクトが入る前にその都度リリースしなくてはなりません。
そのためにも制御構造をしっかり取っておく必要があります。
COM では、解放のタイミングを失うことは許されません...

# 最悪、参照だけ解放して GC.Collect を予備で呼ぶことでも運が良ければ解放されますが...

今回、説明のために酷いネストのソースを貼りましたが、
あのまま使用するのではなく、各ブロックでメソッドを通すようにしてください。
その場合は参照渡しを使うことになります。

引用:

やり方は理解できたので助かりました。
ありがとうございます。


先のまっくさんの Try 〜 Finally の使い方は誤ってました...
そこだけ注意をして頂きたく、あのようなソースを貼りました。
実際に触って頂いた方が理解してくださると思いましたので...

# 次期 VSTO に期待している人の戯言でした。。。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
まっく
会議室デビュー日: 2002/08/30
投稿数: 18
投稿日時: 2005-10-14 10:19
じゃんぬねっとさん、返信ありがとうございます。

引用:

ループでのオブジェクト解放を忘れていたのでしょうか?

ループで使いまわす場合でも、新しいオブジェクトが入る前にその都度リリースしなくてはなりません。
そのためにも制御構造をしっかり取っておく必要があります。
COM では、解放のタイミングを失うことは許されません...

# 最悪、参照だけ解放して GC.Collect を予備で呼ぶことでも運が良ければ解放されますが...

今回、説明のために酷いネストのソースを貼りましたが、
あのまま使用するのではなく、各ブロックでメソッドを通すようにしてください。
その場合は参照渡しを使うことになります。



後続処理でシートを扱っていますが、
そっちでオブジェクト解放していない為でした。

引用:

引用:

やり方は理解できたので助かりました。
ありがとうございます。


先のまっくさんの Try 〜 Finally の使い方は誤ってました...
そこだけ注意をして頂きたく、あのようなソースを貼りました。
実際に触って頂いた方が理解してくださると思いましたので...

# 次期 VSTO に期待している人の戯言でした。。。





正直、”完全に”理解とまではいってませんが、
構築の際に扱えるよう、理解に努めたいと思います。

ありがとうございました。

スキルアップ/キャリアアップ(JOB@IT)