「マクロの記録」の先へ。Word表処理を劇的に高速化する「メモリ内一括処理」の極意
こんにちは。業務自動化の世界へようこそ。
「マクロの記録」を使って、なんとか自動化の第一歩を踏み出した。そんなあなたに、今日はエンジニアとしての「視界」を一気に広げる、非常に重要な話をしましょう。
もしあなたが今、「表のセルを一つずつループで回して、値を書き換えるマクロ」を作っているとしたら……。それは、エンジニアとしての成長の真っ只中にいます。しかし、同時に「速度」という大きな壁にぶつかる運命にもあります。
「データが増えると、処理が終わるまでコーヒーを淹れに行けるほど時間がかかる」
「セルへのアクセスが多すぎて、画面がチラついて止まらない」
これらを解決するのが、今回お伝えする「多次元配列を用いたメモリ内一括処理」というテクニックです。これを知るだけで、あなたのコードは「動くだけのツール」から「プロ仕様のシステム」へと昇華します。
さあ、準備はいいですか? 一緒に極限の効率化へと踏み出しましょう。
1. なぜ、あなたのマクロは「遅い」のか?
まず、敵を知ることから始めましょう。なぜ、Wordのセルに直接アクセスして処理を行うと遅くなるのでしょうか?
「オブジェクト・オーバーヘッド」という名の壁
Word VBAにおいて、`Table.Cell(row, col)` という記述は、単にメモリ上の値を参照しているわけではありません。
1. VBAがWordアプリケーションに対して「〇行、〇列目のセルをください」とリクエストを送る。
2. Wordがそのセルを「オブジェクト(複雑な情報の塊)」として構築する。
3. セルの中身(テキスト、書式、結合状態など)をすべて読み出す。
このプロセスを、ループの中で何百回、何千回と繰り返していると考えてみてください。これは、「書類の1行を書き換えるたびに、わざわざ本社へ承認印をもらいに行く」ようなものです。非常に非効率ですよね。
解決策:データを「メモリ」という手元のデスクに広げる
プロのエンジニアはこう考えます。
「本社(Wordオブジェクト)へ何度も行くのはやめよう。一度にすべての書類(データ)をコピーして、自分のデスク(メモリ上の配列)に広げ、そこで一気に作業を済ませてから、最後にまとめて本社へ提出しよう」
この「デスク(配列)に広げる」作業こそが、今回のテーマである多次元配列の役割です。
2. 実装の戦略:3ステップ・アプローチ
高速化を実現するための黄金パターンは、以下の3ステップです。
1. 【読み込み】 表の全データを、一度だけ「多次元配列」へ格納する。
2. 【加工】 メモリ上(配列の中)で、数値計算やテキスト加工を高速に行う。
3. 【書き戻し】 加工が終わった配列の内容を、一気に表へ反映させる。
ここで一点、重要な注意があります。Excel VBAとは異なり、Wordには「配列をセルに一括で流し込む」という魔法のようなメソッドは存在しません。しかし、「計算ロジック」をWordの外(メモリ上)に追い出すだけで、処理速度は劇的に改善します。
3. 【実践】高速化コードのテンプレート
それでは、実際に動くコードを見てみましょう。
今回は、「表の中の数値を2倍にする」という単純な処理を例に、プロ仕様の構造を解説します。
Option Explicit
''' <summary>
''' Word表のデータを高速に処理するメインルーチン
''' </summary>
Sub HighSpeedTableProcessing()
Dim tbl As Table
Dim dataArray As Variant
Dim r As Long, c As Long
' 1. 対象となる表を指定(ここでは文書内の最初の表)
If ActiveDocument.Tables.Count = 0 Then
MsgBox "表が見つかりません。", vbExclamation
Exit Sub
End If
Set tbl = ActiveDocument.Tables(1)
' 画面更新を停止して高速化(お約束のテクニック)
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
' ---------------------------------------------------------
' STEP 1: 【読み込み】表から配列へデータを移す
' ---------------------------------------------------------
' 配列のサイズを決定(行数 × 列数)
' ※注意: Wordのセルには末尾に特殊な制御文字が含まれるため、
' 読み込み時にそれを除去する工夫が必要です。
ReDim dataArray(1 To tbl.Rows.Count, 1 To tbl.Columns.Count)
For r = 1 To tbl.Rows.Count
For c = 1 To tbl.Columns.Count
' セルのテキストを取得し、Word特有の末尾文字(Chr(13) & Chr(7))を除去
dataArray(r, c) = CleanCellText(tbl.Cell(r, c).Range.Text)
Next c
Next r
' ---------------------------------------------------------
' STEP 2: 【加工】メモリ上(配列内)で計算を行う
' ---------------------------------------------------------
' ここでの処理はWordへのアクセスを一切行わないため、爆速です。
For r = 1 To UBound(dataArray, 1)
For c = 1 To UBound(dataArray, 2)
' 例:数値であれば2倍にする(テキスト処理もここで行う)
If IsNumeric(dataArray(r, c)) And dataArray(r, c) <> "" Then
dataArray(r, c) = CDbl(dataArray(r, c)) * 2
End If
Next c
Next r
' ---------------------------------------------------------
' STEP 3: 【書き戻し】加工後の配列をセルへ反映
' ---------------------------------------------------------
For r = 1 To UBound(dataArray, 1)
For c = 1 To UBound(dataArray, 2)
' 計算結果をセルに書き戻す
tbl.Cell(r, c).Range.Text = dataArray(r, c)
Next c
Next r
' 終了処理
Application.ScreenUpdating = True
MsgBox "処理が完了しました!", vbInformation
Exit Sub
ErrorHandler:
Application.ScreenUpdating = True
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub
''' <summary>
''' Wordのセル特有の末尾制御文字を削除する補助関数
''' </summary>
Private Function CleanCellText(ByVal txt As String) As String
' Wordのセル末尾には必ず Chr(13) & Chr(7) が含まれるため、これを除去
Dim pos As Integer
pos = InStr(txt, Chr(13))
If pos > 0 Then
CleanCellText = Left(txt, pos - 1)
Else
CleanCellText = txt
End If
End Function
4. ここがプロの勘所!陥りやすいエラーと対策
この手法を使いこなすために、以下の3つのポイントを必ず覚えておいてください。
① Word特有の「ゴミ」を掃除せよ
Wordのセルの値を取得すると、必ず末尾に `Chr(13)`(改行)と `Chr(7)`(セル区切り)という目に見えない文字がついてきます。
これを除去せずに `IsNumeric` で判定したり、計算に使おうとすると、「型が一致しません」というエラーの嵐に襲われます。上記のコードにある `CleanCellText` 関数は、まさにこの「掃除」を行うためのプロの防衛策です。
② 配列のインデックス(添字)に注意
VBAの配列は、宣言の仕方によって `0` から始まることもあれば、`1` から始まることもあります。
今回の例では `ReDim dataArray(1 To …)` と明示的に `1` から開始するように指定しています。これにより、Wordの行番号(1行目、2行目…)と配列の添字を一致させ、思考の混乱を防いでいます。
③ `Application.ScreenUpdating` の魔術
大規模な書き戻しを行う際、画面がチカチカ動くのはユーザー体験としても悪く、速度も低下させます。`Application.ScreenUpdating = False` で画面更新を止め、最後に `True` に戻す。これは、エンジニアとして心得ておくべき「礼儀」であり、高速化の鉄則です。
最後に:一歩踏み出したあなたへ
いかがでしたか?
「セルを一つずつ触る」という直感的な方法から、「一度メモリに引き上げてから処理する」という抽象的な方法へ。この考え方のシフトこそが、初級者と上級者を分ける境界線です。
最初はコードが複雑に見えるかもしれません。しかし、一度この「型」を身につけてしまえば、どんなに巨大なデータが来ても、あなたは冷静に、そして高速に処理を完遂できるはずです。
「ここをクリアすれば、Word VBAの基本はバッチリですよ」
自信を持って、次の自動化プロジェクトに挑んでください。応援しています!
