タイトル : 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 を解放させれば良い事になります。 |