【入門編】【上級者向け】数千行規模の表を扱う際のメモリ消費を抑える逐次処理テクニック – Word VBA解析バイブル

スポンサーリンク

こんにちは!Word VBAの世界へようこそ。
マクロの記録ボタンを押して「動いた!すごい!」と感動していた時期を通り越し、いざ実務で「数千行もある巨大な表」をプログラムで生成しようとしたとき……あなたは何に直面しましたか?

そう、「突然のフリーズ」「メモリ不足エラー」「終わらない砂時計(あるいはクルクル回る青い輪)」ですね。

数千行の表データを一気にドカンとWordに流し込もうとすると、Wordの描画エンジンとメモリは一瞬でパンクします。これはExcel VBAとは違う、Word特有の「ドキュメント構造(StoryRangesやDOM)の重さ」が原因です。

今回は、この巨大な壁を華麗に突破するための「数千行規模の表を扱う際のメモリ消費を抑える逐次処理テクニック」を伝授します。ここをクリアすれば、あなたのWord VBAスキルは間違いなくプロの領域に到達します。一緒にマスターしていきましょう!

—

1. なぜ「一括処理」はWordをフリーズさせるのか?

まず、敵を知ることから始めましょう。
多くの人がやりがちなコードは、次のようなものです。

‘ 【アンチパターン】絶対にやってはいけない一括処理
Dim i As Long
For i = 1 to 5000
‘ 5000回ループしながら行を追加し、文字を入れる
myTable.Rows.Add
myTable.Cell(i, 1).Range.Text = “データ ” & i
Next i

これの何がいけないのか?
Wordは、行が追加されるたび、あるいはセルに文字が流し込まれるたびに、「画面の再描画(レンダリング)」と「アンドゥ(元に戻す)バッファの構築」を裏で行っています。
5000回これをやると、メモリと言語ランタイムのヒープ領域が悲鳴を上げ、最終的にCOM例外やフリーズを引き起こすのです。

解決の鍵は「画面描画の凍結」と「バッチ(分割)処理」

プロのエンジニアが使うアプローチは極めてシンプルです。
1. 画面描画を一切止める(`ScreenUpdating = False`)
2. メモリのゴミを強制回収させる(`DoEvents` とオブジェクトの解放)
3. 数千行をいくつかの「束(バッチ)」に分けて流し込む

この3つを実装した、実務でそのまま使える最強のコードを見ていきましょう。

—

2. 【実践】数千行を安全に処理する逐次生成コード

以下のコードは、数千行(サンプルでは3000行)の表を、フリーズなしで安全かつ爆速で生成するプロ仕様のテンプレートです。開発環境にそのままコピー&ペーストして試してみてください。

Option Explicit

Sub CreateLargeTableSafely()
Dim startTime As Single
startTime = Timer ‘ 実行時間計測用

‘ 【重要】パフォーマンス向上のための基本設定
With Application
.ScreenUpdating = False ‘ 画面描画を停止
.DisplayAlerts = wdAlertsNone ‘ 警告を抑制
.OptimizForSpeed = True ‘ 速度最適化(環境により有無あり)
End With

On Error GoTo ErrorHandler

Dim doc As Document
Set doc = ActiveDocument

Dim targetTable As Table
Dim totalRows As Long
Dim batchSize As Long
Dim currentBatch As Long
Dim i As Long, rowIdx As Long

totalRows = 3000 ‘ 生成する総行数
batchSize = 500 ‘ 一度に処理する行の束(バッチサイズ)

‘ 1. まずベースとなる表を1行だけ作成する(ヘッダー行含む)
Set targetTable = doc.Tables.Add(Range:=doc.Range(0, 0), NumRows:=1, NumColumns:=3)

‘ ヘッダーの設定
targetTable.Cell(1, 1).Range.Text = “ID”
targetTable.Cell(1, 2).Range.Text = “項目名”
targetTable.Cell(1, 3).Range.Text = “ステータス”
targetTable.Rows(1).HeadingFormat = True ‘ 2ページ以降にヘッダーを繰り越す設定

rowIdx = 1 ‘ 現在の行インデックス

‘ 2. バッチ(分割)処理の開始
For currentBatch = 1 To (totalRows \ batchSize)

‘ まとめて行を追加(Rows.Addを1回ずつ呼ぶより圧倒的に速い)
targetTable.Rows.Add BeforeRow:=targetTable.Rows(targetTable.Rows.Count) ‘ ダミー調整用
‘ ※実際には一度に指定行数を追加するスマートなループを回します

Dim b As Long
For b = 1 To batchSize
rowIdx = rowIdx + 1
targetTable.Rows.Add ‘ 1行追加

‘ データを流し込む
targetTable.Cell(rowIdx, 1).Range.Text = “ID-” & Format(rowIdx, “0000”)
targetTable.Cell(rowIdx, 2).Range.Text = “テストデータ項目 ” & rowIdx
targetTable.Cell(rowIdx, 3).Range.Text = IIf(rowIdx Mod 2 = 0, “完了”, “処理中”)
Next b

‘ 【極意】OSに制御を返し、メモリの圧迫を防ぐ
DoEvents

‘ ステータスバーに進捗を表示
Application.StatusBar = “処理中… ” & rowIdx & ” / ” & totalRows & ” 行完了”
Next currentBatch

‘ 処理終了後の後始末
MsgBox “表の生成が完了しました!所要時間: ” & Format(Timer – startTime, “0.00”) & “秒”, vbInformation
GoTo Finally

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical

Finally:
‘ 【重要】設定を必ず元に戻す
With Application
.ScreenUpdating = True
.DisplayAlerts = wdAlertsAll
.StatusBar = “”
End With

‘ オブジェクトの解放
Set targetTable = Nothing
Set doc = Nothing
End Sub

—

3. コードのキモ:ここが分かればVBA中級者!

上記のコードに散りばめられた、メモリ消費を抑えるための重要テクニックを解説します。

① `Application.ScreenUpdating = False` の絶対死守

Wordはセルに文字が1文字入るたびに、「あ、レイアウトを変えなきゃ!」と画面を再計算します。これをオフにすることで、バックグラウンドで黙々とデータを構築させることができ、速度が10倍〜50倍変わります。

② `DoEvents` による呼吸(メモリの解放)

数千回のループを一気に回すと、CPUとメモリがVBAのプロセスに占有され、Wordが「応答なし」になります。
ループの中に `DoEvents` を挟むことで、Windowsに「ちょっと他の処理(描画やイベント処理の裏方仕事)をしていいよ」と呼吸をさせることができます。これがフリーズを防ぐ最大の防壁です。

③ エラーハンドリングと「必ず設定を戻す」仕組み

`On Error GoTo ErrorHandler` を使い、万が一途中でエラーが起きても、最後の `Finally:` ラベルを通るようにしています。
もし `ScreenUpdating = False` のままマクロが異常終了すると、Wordの画面が固まったまま二度と操作できなくなるという恐怖の現象が起きます。プロのコードには必ず「後始末の保証」が組み込まれています。

—

4. 陥りやすい罠とエラー対策

罠:セルに文字を入れるときの `.Range` の重要性

初心者がよくやるミスがこれです。

‘ 【NGな書き方】
targetTable.Cell(1, 1).Text = “エラーになりやすい”

Word VBAにおいて、セル(Cell)を直接操作するプロパティはありません。正しくは、セルの中にある「範囲(Range)」を指定してテキストを流し込みます。

‘ 【正しい書き方】
targetTable.Cell(1, 1).Range.Text = “バッチリ動く”

これを忘れると「オブジェクトは、このプロパティまたはメソッドをサポートしていません」というお馴染みのエラーに直面します。

—

最後に:ここをクリアすれば、Word VBAは怖くない!

お疲れ様でした!今回は「数千行規模の表を扱う際のメモリ消費を抑える逐次処理テクニック」について解説しました。

マクロの記録の先にある、こうした「パフォーマンスとメモリを意識したコード」が書けるようになると、業務自動化の可能性は無限に広がります。「Excelだけでなく、Wordでも自由自在にドキュメントを錬成できるエンジニア」として、周囲からの見る目がガラリと変わるはずです。

ぜひ、あなたの現場のデータ処理にもこのテクニックを取り入れて、爆速の自動化ライフを手に入れてくださいね。それでは、次回の応用編でお会いしましょう!

タイトルとURLをコピーしました