【入門編】【上級者向け】表のデータを多次元配列に格納して一括処理し、Wordへの書き戻しを最小限にする高速化手法 – Word VBA解析バイブル

スポンサーリンク

こんにちは。Word VBAの世界へようこそ。
「マクロの記録」を卒業して、自分の思い通りの自動化を実現しようと挑戦しているあなたを、全力でサポートしますね。

さて、今日お話しするのは「Word VBAで表(Table)を扱う際の、決定的な速度差を生む設計思想」についてです。

多くの人が陥る罠があります。それは、「セルに1つずつ値を書き込み、その都度計算や判定を行う」という書き方です。これをやっている限り、データ量が増えた瞬間にWordはフリーズしたかのように重くなります。

なぜか? それはWordが「超高性能なレイアウトエンジン」だからです。1つのセルを書き換えるたびに、Wordは「他の行の高さはどうなるか?」「ページをまたがないか?」と、文書全体の再計算(再描画)を走らせます。これが「描画コスト」という名の正体です。

このコストを最小限に抑え、爆速で処理を終わらせるための秘策。それが「多次元配列への格納と一括処理」です。

ここをマスターすれば、あなたも「Word VBAを使いこなす側」に立てますよ。さあ、一緒に見ていきましょう。

1. コンセプト: 「店に何度も行くか、まとめて買い出すか」

想像してみてください。料理を作るのに、塩が必要になるたびにコンビニへ行き、次に砂糖が必要になったらまたコンビニへ行く……。効率が悪いですよね?

Word VBAでの処理も同じです。

  • NG例: セル(1,1)を読み込む $\rightarrow$ 計算する $\rightarrow$ セル(1,1)に書き込む $\rightarrow$ セル(1,2)を読み込む……(コンビニ往復型)
  • 理想例: 全データを一度に「配列」という買い物カゴに入れる $\rightarrow$ メモリ上で一気に調理(計算)する $\rightarrow$ 最後に完成品をWordに並べる(まとめ買い型)

「Wordの画面を触る回数を最小限にする」。これが高速化の絶対原則です。

2. 【実践】多次元配列を使った高速テーブル生成

今回は、例えば「売上データ」のような数値を処理して表に流し込むケースを想定したコードを書きましょう。

実装コード

Option Explicit

''' <summary>
''' 高速にテーブルを生成し、データを流し込むメインルーチン
''' </summary>
Sub FastTableGeneration()
    Dim doc As Document
    Set doc = ActiveDocument
    
    ' --- 1. データの準備(多次元配列) ---
    ' 本来はDBやCSVから読み込みますが、ここではサンプルとして配列を定義します。
    ' 形式: (行, 列) の2次元配列
    Dim dataMatrix(1 To 5, 1 To 3) As Variant
    
    ' データの流し込み(メモリ内処理なので一瞬です)
    Dim r As Long, c As Long
    dataMatrix(1, 1) = "商品名": dataMatrix(1, 2) = "単価": dataMatrix(1, 3) = "数量"
    dataMatrix(2, 1) = "高性能マウス": dataMatrix(2, 2) = 5000: dataMatrix(2, 3) = 2
    dataMatrix(3, 1) = "メカニカルキーボード": dataMatrix(3, 2) = 12000: dataMatrix(3, 3) = 1
    dataMatrix(4, 1) = "4Kモニター": dataMatrix(4, 2) = 30000: dataMatrix(4, 3) = 2
    dataMatrix(5, 1) = "USBハブ": dataMatrix(5, 2) = 3000: dataMatrix(5, 3) = 5

    ' --- 2. Wordの描画更新を停止(高速化の基本) ---
    Application.ScreenUpdating = False
    
    On Error GoTo ErrorHandler
    
    ' --- 3. 表の動的生成 ---
    ' 必要な行数と列数を配列から取得して表を作成します
    Dim tbl As Table
    Dim rowCount As Long: rowCount = UBound(dataMatrix, 1)
    Dim colCount As Long: colCount = UBound(dataMatrix, 2)
    
    ' カーソル位置に表を挿入
    Set tbl = doc.Tables.Add(Range:=Selection.Range, NumRows:=rowCount, NumColumns:=colCount)
    
    ' 表のスタイルを一括設定(個別に設定すると遅いため)
    tbl.Style = "Grid Table 4 - Accent 1" 
    tbl.Borders.Enable = True
    
    ' --- 4. 配列からWordへの書き戻し(最小限のアクセス) ---
    ' ここで初めてWordのセルにアクセスします。
    ' 計算処理はすべて配列内で済ませ、ここでは「書き込むだけ」に徹します。
    For r = 1 To rowCount
        For c = 1 To colCount
            ' セルの Range オブジェクトを介してテキストを挿入
            ' ※.Range.Text への代入は、Word VBAにおいて最もコストが高い操作の一つです。
            tbl.Cell(r, c).Range.Text = CStr(dataMatrix(r, c))
        Next c
    Next r
    
    MsgBox "処理が完了しました!", vbInformation

CleanUp:
    Application.ScreenUpdating = True
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

3. 先輩エンジニアが教える「ここが落とし穴」ポイント

コードをコピペして動かす前に、Word VBA特有の「クセ」を理解しておいてください。ここが分かっていないと、後で必ずハマります。

① 「セル終端記号」の正体

Wordのセルの中身を `.Range.Text` で取得すると、末尾に不思議な文字(`\r\x07` のような制御文字)が付いています。
これを無視して文字列比較(例:`If cell.Range.Text = “商品名” Then`)を行うと、絶対に一致しません。

  • 対策: 取得したテキストから末尾2文字を消すか、`Like` 演算子を使って判定してください。

`Left(cell.Range.Text, Len(cell.Range.Text) – 2)`

② セルの結合は「後から」やる

表を作成しながらセルを結合(Merge)させると、Wordは内部的にテーブル構造を再計算するため、劇的に速度が低下します。

  • 正解: まず全てのデータを流し込み、最後に「見た目」として結合処理を行う。

③ `Application.ScreenUpdating = False` の魔力

これは基本中の基本ですが、忘れる人が多いです。
Wordは「1文字変わるたびに画面を書き直そう」とします。これをオフにすることで、メモリ上の処理が終わるまで画面更新を待機させ、体感速度を数倍から数十倍に跳ね上げることができます。

4. ステップアップ:さらに高速化するための思考法

もしあなたが、数千行のデータを扱うことになったら、さらに上の手法が必要です。

1. 文字列結合(StringBuilder的なアプローチ):
実は、セルに一つずつ書き込むよりも、「HTML形式のテーブル文字列」を構築して、それを一気にWordに流し込む方が圧倒的に速い場合があります。
2. 配列の型選択:
`Variant` 型の配列は便利ですが、メモリ消費が激しいです。数値だけなら `Double` や `Long`、文字列だけなら `String` の配列を使うことで、メモリ効率を高められます。

まとめ

今回のポイントを整理しましょう。

  • Wordのセルに直接アクセスし続けるのは「コンビニ往復」と同じで遅い。
  • データは一度「多次元配列」に格納し、メモリ内で処理を完結させる。
  • Wordへの書き戻しは、最後に一気に、最小限の回数で行う。
  • `ScreenUpdating = False` は必須の呪文。

この「メモリで処理して、最後に画面へ出す」という設計思想は、Wordに限らず、Excel VBAや他の言語でも通用するプロの共通テクニックです。

ここをクリアすれば、Word VBAの基本はバッチリですよ。自信を持って、さらに複雑な自動化に挑戦してくださいね。応援しています!

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