こんにちは!いつも業務自動化の現場で奮闘している皆さん、お疲れ様です。
Wordの「マクロの記録」を卒業して、自分でコードを書き始めると、必ずぶつかるのが「表(Table)の操作」です。Excel VBAなら「Cells(r, c)」で直感的に扱えるのに、Wordの表はなんだかクセが強くて、思うように動かなかったり、エラーで止まってしまったりしていませんか?
今回は、日常業務の報告書や仕様書チェックで劇的に役立つ、「表の各行を走査(ループ)し、特定キーワード(例: “NG” や “要確認” など)が含まれる行全体を動的に赤字へ変更するマクロ」を作っていきましょう。
ここをマスターすれば、Wordオブジェクトの構造(DOM)がクリアに見えるようになり、脱・初学者への大きな一歩を踏み出せますよ。リラックスしてついてきてくださいね!
—
1. まずはイメージから:Wordの表はどう構成されている?
Word VBAで表を安全に操るためには、Excelとの違いを頭の中に描いておくことが大切です。Wordの表は、次のような入れ子(階層)構造になっています。
ActiveDocument(文書)
└─ Tables(1)(1つ目の表)
└─ Rows(行の集まり)
└─ Row(各行)
└─ Cells(セルの集まり)
└─ Cell.Range(セルのテキストや書式の実体)
Excelではシート全体が巨大なセルの方眼紙ですが、Wordにおける表は「文書の中に浮かぶオブジェクト」にすぎません。
今回は、この階層を上から順番に降りていき、各行(Row)の中にあるテキストをチェックしていきます。
—
2. 【コピペで動く】行ハイライトマクロの完成形コード
まずは、現場ですぐに試せるコードを用意しました。
文書内に表が1つ以上ある状態で、標準モジュールに貼り付けて実行してみてください。
Option Explicit
”’
”’
Public Sub HighlightRowsByKeyword()
‘ パフォーマンス向上のため、画面更新を一時停止
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
‘ 1. 表の存在確認
If ActiveDocument.Tables.Count = 0 Then
MsgBox “文書内に表が見つかりません。”, vbExclamation, “処理中断”
GoTo CleanUp
End If
‘ 2. オブジェクト変数の宣言
Dim targetTable As Table
Set targetTable = ActiveDocument.Tables(1) ‘ 対象とする表(ここでは最初の表)
Dim targetKeyword As String
targetKeyword = “要確認” ‘ ★判定したいキーワードを指定
Dim targetRow As Row
Dim cellText As String
Dim isMatch As Boolean
Dim targetCell As Cell
‘ 3. 行単位でループ処理を開始
For Each targetRow In targetTable.Rows
isMatch = False
‘ 行内のセルを1つずつ巡回
For Each targetCell In targetRow.Cells
‘ セルからテキストを抽出し、Word特有の末尾制御文字を除去
cellText = CleanCellText(targetCell.Range.Text)
‘ InStr関数でキーワードが含まれているか判定(部分一致・大文字小文字区別なし)
If InStr(1, cellText, targetKeyword, vbTextCompare) > 0 Then
isMatch = True
Exit For ‘ 1つでも見つかればその行の探索は終了
End If
Next targetCell
‘ 4. 条件に合致した場合、行全体のRangeに対して書式を適用
If isMatch Then
‘ 行全体の文字色を鮮烈な赤に
targetRow.Range.Font.ColorIndex = wdRed
‘ お好みで太字にしたい場合は以下を有効化
‘ targetRow.Range.Font.Bold = True
End If
Next targetRow
MsgBox “強調表示処理が完了しました!”, vbInformation, “完了”
CleanUp:
‘ 画面更新を元に戻す
Application.ScreenUpdating = True
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
Resume CleanUp
End Sub
”’
”’
Private Function CleanCellText(ByVal rawText As String) As String
‘ セルの末尾には「段落記号 (vbCr: 13)」と「セル終了マーク (Chr(7))」が付いている
If Len(rawText) >= 2 Then
CleanCellText = Left$(rawText, Len(rawText) – 2)
Else
CleanCellText = rawText
End If
End Function
—
3. 先輩が教える「プロのコード」3つのツボ
一見シンプルなコードに見えますが、Word VBAを挫折せずに使いこなすための極めて重要なノウハウが凝縮されています。順番に紐解いていきましょう。
ツボ①:セル末尾の「見えない魔物(Chr(13) & Chr(7))」を祓う
Word VBAで一番の落とし穴がこれです。
Wordのセルから `.Range.Text` で文字列を取得すると、画面上は「完了」としか見えなくても、内部的には必ず末尾に 2文字の制御文字(`vbCr` + `Chr(7)`:セル区切り記号) がくっついています。
画面の見た目: [ 要確認 ]
実際の内部データ: “要確認” & vbCr & Chr(7)
今回は `InStr` による部分一致判定を行っているため、末尾に余計な文字があってもヒットしますが、もし将来「文字列が完全一致したら」という判定(`If cellText = “要確認”`)を書く場合、この2文字を削っておかないと100%条件不一致になってしまいます。
そのため、補助関数 `CleanCellText` を通す癖をつけておくのがプロの流儀です。
ツボ②:`Selection` を捨てて `Range` を愛そう
マクロの記録を使うと、コードは `Selection.MoveRight` や `Selection.Font.Color = …` のように「カーソル(選択範囲)をあちこち動かす記述」で溢れかえります。
しかし、画面の選択状態を動かすコードは遅く、画面がチラつき、途中でユーザーがWordを触ると誤動作する原因になります。
今回のコードでは `Selection` が1度も登場していませんね。
`targetRow.Range.Font.ColorIndex = wdRed`
このように、メモリ上のオブジェクト(Range)を直接指定して色を変える。これこそが高速かつ堅牢なマクロの基本です。
ツボ③:`InStr` 関数の第4引数 `vbTextCompare`
If InStr(1, cellText, targetKeyword, vbTextCompare) > 0 Then
`InStr` 関数は、対象文字列の中に検索文字が含まれている位置(1始まりの数値)を返します。見つからなければ `0` です。
ここで重要なのが第4引数の `vbTextCompare` です。これを指定することで、英字の大文字・小文字、全角・半角の違いを柔軟に吸収して判定してくれます(例: “ng” でも “NG” でもヒットするようになります)。
—
4. 中級者へのステップアップ:結合セルがある表での注意点
今回のコードは、標準的な格子状の表で完璧に動作します。
しかし、実務の表には「セルの結合」という難敵が潜んでいることがありますよね。
もし縦方向にセルが結合されている行に対して `targetRow.Cells` を取得しようとすると、Wordは「行ごとにセルの数が揃っていない!」とパニックになり、実行時エラー(5991: コレクションの個々の行にアクセスできません)を吐き出すことがあります。
結合セル対策のアプローチ
結合セルが多用されている帳票を相手にする場合は、行単位(`For Each targetRow In targetTable.Rows`)ではなく、セル全体を走査するアプローチに切り替えるのが安全です。
‘ 結合セルが混ざっている場合の別解アプローチ例
Dim singleCell As Cell
For Each singleCell In targetTable.Range.Cells
If InStr(1, singleCell.Range.Text, “要確認”, vbTextCompare) > 0 Then
‘ そのセルが属している「行全体」のRangeを取得して色を変える
singleCell.Range.Rows(1).Range.Font.ColorIndex = wdRed
End If
Next singleCell
「結合セルがあるかも……」という現場では、このアプローチも引き出しとして持っておくと安心ですよ。
—
5. まとめ
今回のポイントをおさらいしましょう。
1. Wordの表は `Table -> Row -> Cell -> Range` の階層で捉える
2. セル内の文字列末尾には `vbCr & Chr(7)` が潜んでいることを忘れない
3. `Selection` ではなく、オブジェクトの `Range` を直接書き換えて高速化
4. `InStr(…, vbTextCompare)` で表記揺れに強い検索を実現する
この「行をループして条件に合致するものを修飾する」というパターンは、Word VBAにおけるデータ走査の基本骨格です。
赤字にするだけでなく、背景色を変えたり(`.Shading.BackgroundPatternColor`)、該当行の内容を別のファイルへ書き出したりと、あらゆる自動化へと応用できます。
ここをクリアできれば、Word VBAの基礎はバッチリですよ!
自信を持って、日々のルーティンワークをサクッと自動化していきましょう。応援しています!
