タイトル | : Re^3: すいません。またタスクエラーです(^^;) |
記事No | : 1082 |
投稿日 | : 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 を解放させれば良い事になります。
|