Word VBAで「動的な表レイアウト」を操る――検索と結合の深淵へ
こんにちは。業務自動化の現場で日々、泥臭いドキュメントと格闘しているエンジニアです。
「マクロの記録」で生成されたゴミのようなコードを卒業し、自分の手でWordを自在に操りたい。そう願うあなたへ。今日は、Word VBAにおける「表(Table)の動的制御」という、中級者への登竜門を解説します。
多くの人が躓くのが、「表の座標指定」と「セルの参照」です。これをマスターすれば、報告書のフォーマット調整や、データ流し込みによる帳票生成が驚くほど効率化されます。
—
1. なぜ「表の制御」は難しいのか?
Excel VBAと異なり、Wordの表は「流動的なオブジェクト」です。
セルを結合した瞬間にインデックス(番号)がズレたり、誤ったRangeを指定してWordがフリーズしたり……。経験者は皆、一度は「オブジェクトが見つかりません」というエラーの洗礼を受けています。
ここを突破する鍵は、「Rangeオブジェクトを常に意識すること」です。
—
2. 今回のミッション:キーワードを起点に結合せよ
「『項目』という文字を探し、その右隣のセルと結合する」。
この動作をコードに落とし込みます。単純に見えて、実は「Wordのメモリ空間で何が起きているか」を理解する必要がある重要なステップです。
実践コード:特定のキーワードから右を結合する
Sub MergeCellByKeyword()
Dim tbl As Table
Dim cell As cell
Dim rng As Range
Dim targetText As String
targetText = “項目”
‘ アクティブな文書の最初の表を対象にする(実務ではループ処理で特定する)
Set tbl = ActiveDocument.Tables(1)
‘ 全セルを走査してキーワードを探す
For Each cell In tbl.Range.Cells
If InStr(cell.Range.Text, targetText) > 0 Then
‘ エラーハンドリング:右隣がない場合(列の端など)を考慮
If cell.ColumnIndex < tbl.Columns.Count Then
' 現在のセルと、右隣のセルを結合
' MergeメソッドはRange単位で実行するのが鉄則
cell.Merge MergeTo:=cell.Next
' 結合後のセルに文字を流し込む処理
cell.Range.Text = "【結合完了】"
Exit For ' 目的を達したら抜ける
End If
End If
Next cell
End Sub
---
3. コードの「極限の知見」:ここがプロの分かれ道
コードを動かすだけでなく、安定性を高めるために以下の3点を覚えて帰ってください。
① `InStr` での文字判定は「ゴミ」に注意
`cell.Range.Text` を取得すると、末尾に必ず「セルの終端記号(Chr(13) & Chr(7))」が含まれます。`InStr` で検索する際は、この制御文字が含まれることを前提に、「一致する箇所があるか」だけで判定するのが安全です。
② `MergeTo` の罠
`cell.Merge MergeTo:=cell.Next` は便利ですが、「すでに結合されているセル」に対して実行するとWordはクラッシュします。
大規模な帳票を作成する場合、事前に「結合済みかどうか」をフラグで管理するか、`On Error Resume Next` を適切に配置して、リトライ処理を入れるのがプロの作法です。
③ パフォーマンスを上げる魔法
表が巨大な場合、画面描画をオフにするだけで速度が劇的に変わります。
Application.ScreenUpdating = False
‘ …ここに処理…
Application.ScreenUpdating = True
これを入れるだけで、処理時間は体感で数倍速くなります。
—
4. まとめ:次の一歩へ
「特定のキーワードを見つけて、動的にレイアウトを変える」。
これができれば、あとは「行の挿入(`tbl.Rows.Add`)」や「数値のフォーマット(`Format(value, “#,
0″)`)」を組み合わせるだけで、どんな複雑な帳票も自動生成可能です。
Word VBAはExcelに比べて「文書の見た目」という変数が多いため難しいですが、その分、自動化できた時の達成感は格別です。
まずはこのコードを、お手元のWordファイルで動かしてみてください。うまく動かない場所があれば、それがあなたの「今の限界点」です。そこを突破した時、また一つ、あなたはエンジニアとして賢くなっています。
何か詰まったら、いつでも聞きに来てくださいね。応援しています!
