- ベストアンサー
【Excel VBA】 WorksheetやRangeオブジェクトとして宣言した変数の開放は必要でしょうか?
こんばんは。 プロシージャレベルで宣言したWorksheetやRangeなどのオブジェクト変数に対し、 プロシージャを終了する直前に、 Set ○=Nothing を実行して、変数(オブジェクトへの参照)を開放する処理を習慣的行っていました。 これは、絶対に必要な処理なのでしょうか? 開放しないことで不具合が出るケースとはどういう場合なのでしょうか? どなたか、ご教示いただけないでしょうか。 よろしくお願いいたします。 <例> Sub test() Dim Ws1 As Worksheet Set Ws1 = Worksheets("Sheet1") '処理内容 Set Ws1 = Nothing End Sub 尚、CreateObject関数で作成したオブジェクトへの参照などではなく、 あくまでもWorksheetやRangeなどの話です。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
プロシージャレベルの Worksheet や Range オブジェクトでは、 プロシージャの終了とともに自動開放されますから、 Nothing に よる開放処理は必須ではありません。 長く VBA を使っておりますが、省略したからといって不具合が発生 したケースも経験ありません。 ただ、プログラムを書く姿勢として、 自分で使ったモノは、自分で開放する とあるべきではないかと考えます。 VBA においてはマナーみたいなものですね。されど、これは私個人 だけの考えではなく、過去から積み上がった先人プログラマーの 経験側でもあります。 例えば、VBA のこのような言語仕様に慣れきった人、つまり開放 するということが習慣として身についていない人が、メモリ操作や 画像処理など高度な処理を書くようになった場合、必須の開放処理 が抜け落ちたプログラムを平気で書いてしまい、後々メモリリーク に悩むはめになったりしがちです。 言語仕様として、「必須ではない」とはいえ、きちんと開放処理を 記述した方が良いでしょう。 注意が必要なのは、オートメーションを使ったプログラムの場合は、 例えプロシージャレベルであっても開放必須です。これを怠ると #1 でお話がでてますが、いわゆるゾンビプロセスが残るという事態 になります。また、 > プロシージャレベルで宣言したWorksheetやRangeなどの... と限定されているのでお分かりかと思いますが、グローバル等の 広域変数の場合も、誤動作防止、余計なメモリ消費を抑えるため 適所で開放処理が必須になります。 余談になりますが、#1 補足欄のソースは私ならこう書きます。 ご参考までに。 Sub test() On Error Goto Err_ Dim Ws1 As Worksheet Set Ws1 = Worksheets("Sheet1") '処理内容 Bye_: Set Ws1 = Nothing Exit Sub Err_: 'エラー処理 Resume Bye_ End Sub
その他の回答 (1)
- bin-chan
- ベストアンサー率33% (1403/4213)
Nothingは必要であると思ってます。 VBAのつくりが悪くて、何度かNothingを通る前に強制終了させてたらフリーズ。 タスクマネージャでプロセスみたら、EXCELの残ったままのプロセスが・・・。(ゾンビプロセス?) なので、「おまじないかも?」とは思いつつも実行してます。
お礼
bin-chan様 ご回答ありがとうございました。 今までどおり、変数の開放を習慣化しようと思います。 以下、備忘録として利用させていただく事をお許しください。 Sub test() On Error Goto Err_ Dim Ws1 As Worksheet Set Ws1 = Worksheets("Sheet1") '処理内容 Bye_: Set Ws1 = Nothing Exit Sub Err_: MsgBox Err.Description, vbCritical Resume Bye_ End Sub
補足
ご回答ありがとうございます。 途中でエラーが発生した場合のことを考えて ということですね。 それでは、以下のような処理をしたほうが 良いのでしょうか? (Exit Subの前では、あえてNothingしてません) <例> Sub test() On Error Goto Err Dim Ws1 As Worksheet Set Ws1 = Worksheets("Sheet1") '処理内容 Exit Sub Err: Set Ws1 = Nothing End Sub
お礼
KenKen_SP様、大変丁寧なご回答ありがとうございました。 すっきり納得できました。 必須ではないが、行うべきだということですね。 最後のソースを含め大変参考になりました。 またお世話になる事があると思いますが、 その際はよろしくお願いいたします。