Word VBAの「重い・落ちる」を卒業せよ:メモリリークを封殺するオブジェクト管理の極意
こんにちは。現場で「なぜかWordマクロが走るたびにPCが重くなる……」と頭を抱えたことはありませんか?
マクロの記録から脱却し、本格的な業務自動化に踏み込んだあなたが次に直面する壁。それは、「Wordオブジェクトの寿命とメモリ管理」です。これを理解すれば、あなたの書くコードは「動く」レベルから、現場の基幹システムを支える「堅牢な」レベルへと進化します。
今日は、表の動的生成を例に、プロが現場で必ず守っている「後始末」の美学を伝授します。
—
1. なぜWordは「重くなる」のか?
Word VBAの背後には、COM(Component Object Model)という仕組みが動いています。あなたが `Set tbl = ActiveDocument.Tables.Add(…)` と書くたび、Windowsの裏側ではWordの脳(オブジェクト)がメモリを確保します。
問題は、「コードが終わっても、Wordは律儀にメモリを握り続けることがある」という点です。特にループ処理で何度も表を生成していると、使われなくなったオブジェクトの亡霊がメモリに積み重なり、PCは悲鳴を上げます。
これを防ぐための黄金律、それは「使ったら、必ずNULL(Nothing)に戻す」です。
—
2. 【実践】メモリリークを防ぐ「安全な表生成」のテンプレート
単に表を作るだけでなく、確実にメモリを解放する構造を見ていきましょう。
Sub GenerateTableWithSafety()
‘ オブジェクト変数を明示的に宣言
Dim doc As Document
Dim tbl As Table
Dim rng As Range
‘ プロセス開始:エラーハンドリングは必須
On Error GoTo Cleanup
Set doc = ActiveDocument
‘ 現在のカーソル位置に表を生成
Set rng = Selection.Range
Set tbl = doc.Tables.Add(Range:=rng, NumRows:=3, NumColumns:=3)
‘ — 表の操作 —
With tbl
.Cell(1, 1).Range.Text = “項目名”
.Cell(1, 2).Range.Text = “数値”
‘ セル結合の例
.Cell(2, 1).Merge MergeTo:=.Cell(2, 2)
End With
‘ — 【ここが極意】明示的なメモリ解放 —
Cleanup:
‘ エラーが発生しても必ずここを通るようにする
Set tbl = Nothing
Set rng = Nothing
Set doc = Nothing
If Err.Number <> 0 Then
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End If
End Sub
なぜ `Set = Nothing` が必要なのか?
変数に `Nothing` を代入することは、Wordに対し「もうこの参照は使わないから、メモリを返却していいよ」と宣言する行為です。これを怠ると、Wordは「まだ誰かが使っているかもしれない」と判断し、メモリを保持し続けます。チリも積もれば山となり、長時間のバッチ処理でWordがフリーズする原因となります。
—
3. 陥りやすい罠:`Selection`と`Range`の使い分け
初心者が陥りやすい最大の罠が、`Selection`を多用することです。
- Selection: 画面上のカーソル位置。描画コストが高く、動作が非常に重い。
- Range: 文書内の「見えない範囲」。高速で、メモリ効率が良い。
「表に数値を流し込む」際、`Selection.TypeText` を繰り返していませんか? これは「カーソルを動かす」という物理的な描画を伴うため、数千行の処理では致命的な速度低下を招きます。
プロの流儀:
なるべく `Range` オブジェクトを使い、「見えない場所でデータを作り、一気にドキュメントへ流し込む」のが鉄則です。
—
4. 現場で生き残るための「3つの心得」
最後に、あなたが明日からコードを書く際に意識すべき「極意」をまとめました。
1. スコープを最小にする
- 広い範囲で使う変数(Publicなど)は避け、必要なプロシージャ内だけで変数を完結させましょう。
2. `On Error GoTo Cleanup` をテンプレート化する
- コードの途中でエラーが起きたとき、そのまま終了するとメモリが解放されません。必ず後処理(Cleanup)を通るルートを作りましょう。
3. `Selection` を排除せよ
- `Selection` を使わずに `Range` で操作できる箇所はないか、常に自問自答してください。これが高速化への最短ルートです。
—
最後に:あなたはもう「初学者」ではない
ここまで読み進めたあなたは、単に動くコードをコピペする段階を卒業し、「システム全体への影響」を考慮できるエンジニアの入り口に立っています。
Word VBAは非常に強力なツールです。正しく付き合えば、あなたの仕事を数時間から数秒に短縮してくれる最高のパートナーになります。今日学んだ「後始末」の習慣を、ぜひあなたのコードの標準装備にしてください。
何か不明点や、さらに深い最適化(例えば、大量データ処理時の `ScreenUpdating = False` の活用など)について知りたいことがあれば、いつでも聞いてくださいね。あなたの開発ライフがより快適なものになるよう、いつでも応援しています。
