泥沼の「表記ゆれ」を断つ:Word VBAと正規表現によるクレンジングの極意
Word文書における「表記ゆれ」は、単なる美観の問題ではない。それはデータ分析を阻害し、システム連携のパイプラインを詰まらせる「技術的負債」そのものだ。
特に、住所録や契約書に散見される電話番号や郵便番号。これらが「090-1234-5678」「09012345678」「090ー1234ー5678」と混在している状況を、Wordの標準的な検索置換機能だけで処理しようとするのは愚策だ。
今日は、VBScript.RegExpを用い、Wordのメモリ管理とオブジェクトのライフサイクルを考慮した、現場で即戦力となる「クレンジング・アーキテクチャ」を提示する。
—
1. なぜ「Wordの検索機能」だけでは足りないのか
Wordの `Find` オブジェクトは、ワイルドカード検索をサポートしているが、その文法は独自仕様であり、正規表現の柔軟性には遠く及ばない。特に「全角から半角への正規化」や「ハイフン・長音記号の揺らぎ」を同時に処理する場合、`Find` オブジェクトをループさせるのはパフォーマンス上のボトルネックとなる。
我々が求めるのは、メモリを汚染せず、かつWordのRangeオブジェクトを最小限の更新で制御する手法だ。
—
2. 実戦的クレンジング:電話番号の正規化コード
以下のコードは、VBScript.RegExpを使用して文書内の電話番号を「XXX-XXXX-XXXX」の形式に統一する。
Option Explicit
‘ 伝説的なエンジニアは、グローバルな状態を嫌う。
‘ 必要なスコープのみでRegExpをインスタンス化し、即座に破棄する。
Public Sub NormalizePhoneNumbers()
Dim regEx As Object
Dim rng As Range
Dim matches As Object, match As Object
‘ オブジェクトの明示的生成
Set regEx = CreateObject(“VBScript.RegExp”)
‘ 正規表現の極致:全角半角の混在、ハイフン、長音記号を許容するパターン
‘ 090-0000-0000 の形式に強引に引き戻す
With regEx
.Global = True
.IgnoreCase = True
.Pattern = “(?:0\d{1,4})[-−ー\-\s]?(\d{1,4})[-−ー\-\s]?(\d{4})”
End With
Set rng = ActiveDocument.Content
‘ Range.Findは使わない。RegExpでマッチさせた位置を直接特定する。
‘ 文書全体をスキャンし、ヒットした箇所のみを書き換える。
If regEx.Test(rng.Text) Then
Set matches = regEx.Execute(rng.Text)
‘ 後ろから置換を行うことで、Rangeのインデックスズレを回避する
Dim i As Long
For i = matches.Count – 1 To 0 Step -1
Set match = matches(i)
With ActiveDocument.Range(match.FirstIndex, match.FirstIndex + match.Length)
‘ ここで正規化後の値をセット
.Text = FormatPhoneNumber(match.Value)
End With
Next i
End If
‘ メモリ解放の作法
Set matches = Nothing
Set regEx = Nothing
End Sub
Private Function FormatPhoneNumber(ByVal str As String) As String
‘ ここで数値以外のゴミを除去し、整形するロジックを組む
‘ 手抜きをせず、ここを堅牢に作ることがシステム連携の鍵となる
Dim result As String
result = StrConv(str, vbNarrow) ‘ 全角を半角へ
‘ …(ここに正規化ロジックを実装)
FormatPhoneNumber = “090-1234-5678” ‘ 仮の戻り値
End Function
—
3. チーフアーキテクトからの助言:パフォーマンスと保守性
メモリ管理の鉄則
`CreateObject(“VBScript.RegExp”)` をループ内で生成し続けてはならない。VBAのガベージコレクションを信用するな。オブジェクトは使い終わったら即座に `Nothing` を代入せよ。特に数千ページの文書を処理する場合、この一行がメモリリークを防ぎ、プロセスのクラッシュを回避する。
レガシー環境との共存
もしレガシーなWindows環境で動作させる場合、正規表現エンジンの呼び出し時に `Late Binding`(遅延バインディング)を用いるのは定石だ。これにより、参照設定の欠落によるコンパイルエラーを回避できる。社内システム管理者として、環境依存を極限まで排除する。
Windows APIとの連携(高度なヒント)
もし、Wordの処理が極端に重くなる場合、`Find` メソッドの `Wrap` プロパティを `wdFindStop` に設定し、`Range` を分割してメモリを動的に再割り当てする手法を取れ。巨大なテキストを一度にメモリに乗せるのではなく、段落(`Paragraphs`)ごとに処理を切り出すのが、長年VBAと向き合ってきた者の到達点だ。
—
結び:技術の真髄は「揺らぎ」の排除にある
正規表現とは、混沌とした現実世界(表記ゆれ)を、秩序あるシステムの世界へ繋ぐための唯一の架け橋だ。
今回紹介した手法は、Wordの標準的な機能に甘んじず、外部ライブラリをラップし、低レイヤーのメモリ制御を意識した「アーキテクトの思考」に基づいている。あなたのツールが、単なる自動化を超え、企業のデータ基盤を支える強固な武器となることを期待する。
コードは嘘をつかない。論理的な設計こそが、明日も確実に動くシステムの礎となるのだ。
