【入門編】【中級者向け】表内のテキストを正規表現で検索し、特定のパターンに合致するセルを強調する – Word VBA解析バイブル

スポンサーリンク
スポンサーリンク

マクロ記録の先へ。Word VBAと正規表現で「表」を支配する極限のテクニック

こんにちは。現場の自動化を設計するチーフアーキテクトです。

「マクロの記録」ボタンを押し、生成されたコードを見て「ふむふむ、動いているな」と納得する。それは素晴らしい第一歩です。しかし、あなたがもし「特定の型番だけを探して色を塗りたい」「日付の形式がバラバラなセルを特定したい」といった、“条件付きの複雑なロジック”を求められたとき、マクロの記録では太刀打ちできない壁にぶつかるはずです。

今日のテーマは、Word VBAの真髄の一つである「Table(表)オブジェクト」と、文字列操作の魔術師「VBScript.RegExp(正規表現)」の融合です。

単にコードを写すのではなく、「なぜその書き方をするのか」「オブジェクトの動きはどうなっているのか」というエンジニアの視点をインストールしていきましょう。ここをクリアすれば、あなたのVBAスキルは「記録レベル」から「設計レベル」へと昇華します。

1. なぜ「Word標準の検索」では足りないのか?

Wordには標準で `Find` メソッドという強力な検索機能が備わっています。しかし、実務で遭遇するデータはそんなに綺麗ではありません。

  • 「AB-1234」という型番を探したいが、前後に余計な文字が入っている。
  • 「2023/10/01」や「2023年10月1日」など、表記ゆれがある。
  • 「英字2文字+数字4桁」のような、パターンのルールで探したい。

これらをWord標準のワイルドカード検索で実現しようとすると、条件が複雑になりすぎて、コードがスパゲッティ状態になってしまいます。

そこで登場するのが正規表現(Regular Expression)です。正規表現を使えば、「文字の並びのルール」を定義するだけで、複雑なパターンを瞬時に見つけ出すことができます。

2. 戦略的アーキテクチャ:処理のフローを設計する

いきなりコードを書き始めてはいけません。プロのエンジニアはまず、「データの流れ」を脳内に描きます。今回のプログラムの設計図はこうです。

1. エンジンの準備: 正規表現エンジン(`VBScript.RegExp`)を起動する。
2. 対象の特定: 文書内の「表(Table)」を一つずつ走査する。
3. セルの解体: 表の中の「セル(Cell)」を一つずつ取り出す。
4. パターンの照合: セル内のテキストを正規表現エンジンに放り込み、合致するか判定する。
5. 装飾(アクション): 合致した場合のみ、そのセルの背景色を変える。

ここで重要なのは、「正規表現エンジンはループの外で作る」ということです。ループの中で毎回エンジンを作り直すと、コンピュータのメモリとCPUに無駄な負荷がかかり、処理速度が劇的に低下します。これを「オブジェクトのライフサイクルを意識する」と言います。

3. 実装:型番を検知してハイライトするプロトタイプ

では、実際に動くコードを見てみましょう。
今回は、「英字2文字 + ハイフン + 数字4桁(例: AB-1234)」というパターンを探して、そのセルを黄色く塗るマクロを作成します。

Option Explicit

''' <summary>
''' 表内のセルを走査し、特定の型番パターンに合致するセルをハイライトする
''' </summary>
Sub HighlightModelNumbersInTable()
    Dim targetDoc As Document
    Dim targetTable As Table
    Dim targetCell As Cell
    Dim regEx As Object
    Dim pattern As String
    
    ' 1. 初期設定
    Set targetDoc = ActiveDocument
    
    ' 正規表現エンジンの生成 (Late Bindingを使用)
    ' 参照設定の手間を省くため、実行時にオブジェクトを作成します
    Set regEx = CreateObject("VBScript.RegExp")
    
    ' 検索パターンの定義
    ' [A-Z]{2} : 英大文字2文字
    ' -        : ハイフン
    ' \d{4}    : 数字4桁
    pattern = "[A-Z]{2}-\d{4}"
    
    With regEx
        .Pattern = pattern
        .Global = True        ' 文中全体を検索
        .IgnoreCase = False   ' 大文字小文字を区別
    End With

    ' 2. 文書内の全ての表をループ処理
    ' もし特定の表だけにしたい場合は、targetDoc.Tables(1) のように指定します
    If targetDoc.Tables.Count = 0 Then
        MsgBox "文書内に表が見つかりませんでした。", vbExclamation
        Exit Sub
    End If

    For Each targetTable In targetDoc.Tables
        ' 3. 表内の各セルをループ処理
        For Each targetCell In targetTable.Range.Cells
            
            ' 【重要】セルのテキスト取得における注意点
            ' Wordのセル内テキストには、末尾に制御文字 (Chr(13) & Chr(7)) が含まれます。
            ' これをそのまま正規表現に渡すと誤判定の原因になるため、CleanTextを作成します。
            Dim cellText As String
            cellText = targetCell.Range.Text
            cellText = Left(cellText, Len(cellText) - 2) ' 末尾の2文字を削る
            
            ' 4. 正規表現による照合
            If regEx.Test(cellText) Then
                ' 5. 合致した場合の装飾
                ' セルの背景色を黄色に設定
                targetCell.Shading.BackgroundPatternColor = wdColorYellow
                
                ' デバッグ用:イミディエイトウィンドウにログを出力
                Debug.Print "Match Found: " & cellText & " in Table " & targetTable.Index
            End If
            
        Next targetCell
    Next targetTable

    ' 後片付け
    Set regEx = Nothing
    
    MsgBox "スキャンが完了しました。", vbInformation
End Sub

4. 陥りやすい罠:エンジニアが教える「落とし穴」回避術

このコードを動かす際、あるいは自分で応用する際に、必ず直面する「2つの壁」があります。ここを知っているかどうかが、初級者と中級者の分かれ目です。

① セル末尾の「不可視文字」問題

コード内のコメントにも書きましたが、Wordの `Cell.Range.Text` で取得できる文字列には、目に見えない「セル終了記号(Chr(13) & Chr(7))」が必ずくっついています。

これを考慮せずに文字列比較や正規表現を行うと、「見た目は一致しているのに、プログラム上では一致しない」という、非常にストレスフルなバグに遭遇します。必ず `Left(text, Len(text) – 2)` 等で削ぎ落とす癖をつけましょう。

② パフォーマンスの重み(計算量)

表が10行程度なら問題ありません。しかし、数百行、数千行の巨大な表に対してこの処理を行うと、処理が重くなることがあります。

原因は、`targetCell.Shading.BackgroundPatternColor` のような「描画に関わる操作」をループ内で頻繁に行うことです。Wordは、プロパティを一つ書き換えるたびに「画面をどう更新するか」を計算しようとします。
もし大量のセルを処理する場合は、処理の最初に `Application.ScreenUpdating = False` を入れ、最後に `True` に戻すことで、描画の更新を一時停止し、劇的に高速化させることができます。

5. まとめ:次のステップへ

お疲れ様でした。あなたは今、単なる「記録されたマクロの利用者」から、「ロジックを用いてデータを制御するエンジニア」への一歩を踏み出しました。

今回のポイントを復習しましょう。

  • 正規表現を使えば、複雑な文字列パターンも自在に扱える。
  • オブジェクトのライフサイクルを意識し、重いオブジェクトはループの外で作る。
  • Word特有の制御文字(セル末尾のゴミ)を常に意識する。

次に挑戦するなら、「正規表現で抽出した特定の文字列だけを、別のExcelファイルに書き出す」といった、アプリケーションを跨いだ自動化に挑んでみてください。

コードは道具に過ぎません。大切なのは、その道具を使って「どんな価値を生み出すか」という設計思想です。また次の現場でお会いしましょう。応援していますよ。

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