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

タイトル 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を破棄

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

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