tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^3: すいません。またタスクエラーです(^^;)
投稿日: 2004/09/14(Tue) 10:05
投稿者魔界の仮面弁士
> > > xlBook = xlApp.Workbooks.Add
> > Workbooksコレクションも変数にとっておき、
> > 最後にReleaseComObjectする必要があります。

> > > xlSheet = xlBook.Worksheets(1)
> > Worksheetsコレクションも変数にとっておき、
> > 最後にReleaseComObjectする必要があります。
>
>    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
> のことでしょうか?これはしています。

いえ、そういう事では無いのです。

確かに、最後の Marshal.ReleaseComObject() の呼び出しは必須なのですが、
クーガさんが解放しているのは「Workbookオブジェクト」ですよね。
それに対して、私が書いたのは「Workbooksオブジェクト」となります。
(名前は良く似ていますけどね)

もちろん、クーガさんが書かれていますように、Workbook も解放する必要があるのですが、
それに加えて、一時的に参照された Workbooks というコレクションオブジェクトについても
解放しなければならない、という事です。

つまり、この場合には、
  xlBook = xlApp.Workbooks.Add
とするのではなく、
  xlBooks = xlApp.Workbooks
  xlBook = xlBooks.Add()
などのようにして、個々のCOMオブジェクトを変数に保持しておき、最後に、
この2つの変数を Marshal.ReleaseComObject() するという手順が必要なのです。
そしてこれは、その他のコレクション(Worksheets等)についても同様です。

# なお、COM側にとってみれば、.NETの変数がNothingされたかどうかは、あまり関係ありません。
# Marshal.ReleaseComObject さえ確実に行われれば、Nothingの代入やガベージコレクトが
# 行われなくても、(COM側が使用していた分の)メモリは解放されるはずです。


> これは、Cellを使わないで、Rangeを使用したほうがいいということですか?
Cellsプロパティは、Rangeオブジェクトを返します。
そしてこれも、上記の「コレクションの解放」の話と、同様の内容なのです。

たとえば、
  xlSheet1.Cells(1, 1)
というのは、
  xlSheet1.Cells._Default(1, 1)
を省略した書き方と言えます。

Cellsプロパティ自体は、実際には「全てのセルを含むRangeオブジェクト」を返します。
そして、Rangeオブジェクトの規定のプロパティ(_Defaultプロパティ)によって、
また別のRangeオブジェクトが返されるようになっています。

いずれのRangeオブジェクトも、(.NETのクラスではなく)COMのオブジェクトですから、
最後には Marshal.ReleaseComObject() が必要とされます。という事は、先の話と同様で、
途中のRangeオブジェクトも変数にとっておき、最後には解放してやらねばならないのです。

つまり、Cellsプロパティを使った
  xlRange = objsheet.Cells(1, 1)
というコードがあったとしたら、これを
  xlRange1 = xlSheet1.Cells
  xlRange2 = xlRange1(1, 1)    'または、「xlRange2 = xlRange1._Default(1, 1)」
のように修正して、最後にこの xlRange1, xlRange2 を解放させれば良い事になります。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。