タイトル : Re^3: Cells.FindNextのループ中の解放 投稿日 : 2009/09/16(Wed) 16:04 投稿者 : 魔界の仮面弁士
> myFindNextのみオブジェクト2を破棄する、といったような方法が思いつきません。。。 変数とオブジェクトインスタンスを分けて考えてください。 一番最初の >> Dim myRng As Excel.Range = xlCells.FindNext(myRng) で問題があるのは、何故だかわかりますか? (正確には「myRng = xlCells.FindNext(myRng)」) FindNext 前は、myRng はオブジェクト1を参照していたけれども、 FindNext 後は、myRng はオブジェクト2を参照するようになりますよね。 このため、オブジェクト1はどの変数からも参照されていない状態に なってしまったため、MRComObject で解放させる方法が使えなくなってしまい、 解放漏れに繋がってしまうというわけです。 > どうにかしてオブジェクト2を次回のループ先頭まで保持しておきながら、 ループ先頭で保持している変数は何ですか? myRng ですよね。 ですから、myRng にオブジェクト2を“破棄せずに”セットすれば良いのです。 最初の質問では、myRng にオブジェクト2をセットしてはいますが、 その直後にそれが破棄されていました。それが余計な作業だったわけです。 > 'MRComObject(myFindNext) '←コメントアウト 正解です。この破棄作業が余計だったわけですね。 > If myRng.Address = 最初セル Then > MRComObject(myRng) : myRng = Nothing > End If 単にループの脱出が目的なら、Exit Do を呼び出せば済みますよ。 myRng の破棄作業は、既にループ脱出後に用意してありますので、 この段階での myRng の破棄は不要です。 また、Nothing 代入の役割は、すでに MRComObject が担っているかと思います。 (MRComObject をどのように実装したのかもよりますが…) > 毎回myFindNextを解放処理する必要があると思うのですが。 ループ中では、「FindNext の戻り値から得た Range」を破棄するのではなく、 「FindNext の引数に渡した Range」を破棄していく事になるかと思います。 > 一応下のようにMRComObject(myFindNext)をコメントアウトしてもExcel.EXEが > 解放されますが、オブジェクト2を破棄できていないはずですし。。 オブジェクト2は、次回のループ時に破棄されます。 表現が難しいですが、この場合には、 「今回のオブジェクト2」=「次回のオブジェクト1」 であるという事です。 別の書き方をすると、こんな感じですかね。 > Dim myRng As Excel.Range = xlCells.Find("文字列") → myRng に オブジェクト1 をセット > Do --- ループ 1 回目 --- > Dim myFindNext As Excel.Range = xlCells.FindNext(myRng) → myFindNext に オブジェクト2 をセット > MRComObject(myRng) → オブジェクト1を破棄 > myRng = myFindNext → myRng に オブジェクト2 をセット > MsgBox(myRng.Value) --- ループ 2 回目 --- > Dim myFindNext As Excel.Range = xlCells.FindNext(myRng) → myFindNext に オブジェクト3 をセット > MRComObject(myRng) → オブジェクト2を破棄 > myRng = myFindNext → myRng に オブジェクト3 をセット > MsgBox(myRng.Value) --- ループ 3 回目 --- > Dim myFindNext As Excel.Range = xlCells.FindNext(myRng) → myFindNext に オブジェクト4 をセット > MRComObject(myRng) → オブジェクト3を破棄 > myRng = myFindNext → myRng に オブジェクト4 をセット > MsgBox(myRng.Value) --- 以下繰り返し --- > Loop Until myRng.Address = 最初セル --- ループ 脱出 --- > MRComObject(myRng) → オブジェクト4を破棄 |