Word VBAで「置換の履歴」を掌握せよ:堅牢な変更ログ抽出エンジニアリング
Wordの`Find.Execute Replace:=wdReplaceAll`を思考停止で呼び出していないか?
業務自動化を標榜するエンジニアにとって、置換処理は「実行して終わり」ではない。「何が、どこで、どう変わったか」を可視化できない自動化は、ブラックボックスという名の負債を抱える行為に等しい。
今回は、大規模ドキュメントの置換において、変更箇所と周辺の文脈をExcelへ掃き出す「高精度ロギング・アーキテクチャ」を伝授する。
—
1. なぜ「wdReplaceAll」だけでは不十分なのか
`wdReplaceAll`は爆速だが、置換結果の検証が物理的に不可能だ。修正後のドキュメントを目視でチェックするのは、プロの仕事ではない。
堅牢なシステムを構築するためには、以下の設計思想が必要となる。
- 非破壊的なスキャン: 置換前に一度文脈をキャプチャする。
- コンテキストの保持: 置換対象の「周辺(前後数文字)」を切り出し、変更の妥当性を人間が判断できるようにする。
- 疎結合な出力: Word側にログを溜めず、Excelという外部データベースに記録を退避させる。
—
2. 実装の核心:Findオブジェクトのライフサイクル管理
Wordの`Range`オブジェクトを使い、検索ヒットごとにループを回す。この際、`Replace`の引数に依存するのではなく、「検索して、見つけて、そのRangeを更新し、ログを残す」という一連のプロセスを明示的に記述する。
プロダクションコード:変更ログ抽出エンジン
このコードは、WordからExcelを制御する構成だ。事前に「Microsoft Excel x.x Object Library」を参照設定しておくか、遅延バインディング(Late Binding)で実装することを推奨する。
‘ Word VBA: 置換対象を検出し、Excelへレポートを出力する
Sub ExportReplaceLogToExcel()
Dim wdDoc As Document: Set wdDoc = ActiveDocument
Dim xlApp As Object, xlBook As Object, xlSheet As Object
Dim rng As Range
Dim rowIdx As Long: rowIdx = 2
‘ Excelのセットアップ(遅延バインディング)
Set xlApp = CreateObject(“Excel.Application”)
Set xlBook = xlApp.Workbooks.Add
Set xlSheet = xlBook.Sheets(1)
‘ ヘッダー作成
xlSheet.Cells(1, 1).Value = “検索ワード”
xlSheet.Cells(1, 2).Value = “置換後”
xlSheet.Cells(1, 3).Value = “変更前後の文脈”
Set rng = wdDoc.Content
‘ 検索エンジンの設定
With rng.Find
.ClearFormatting
.Text = “旧用語” ‘ ここを可変にする設計が望ましい
.Replacement.Text = “新用語”
.Forward = True
.Wrap = wdFindStop
Do While .Execute
‘ 1. 文脈の切り出し(前後10文字)
Dim context As Range
Set context = rng.Duplicate
context.Expand Unit:=wdCharacter
context.MoveStart Unit:=wdCharacter, Count:=-10
context.MoveEnd Unit:=wdCharacter, Count:=10
‘ 2. Excelへの書き出し
xlSheet.Cells(rowIdx, 1).Value = .Text
xlSheet.Cells(rowIdx, 2).Value = .Replacement.Text
xlSheet.Cells(rowIdx, 3).Value = context.Text
‘ 3. 置換実行(ここで実際にWord上も変更される)
rng.Text = .Replacement.Text
rowIdx = rowIdx + 1
rng.Collapse wdCollapseEnd
Loop
End With
xlApp.Visible = True
MsgBox “ログ抽出完了。変更箇所: ” & rowIdx – 2 & “件”
End Sub
—
3. 現場で生き残るための設計上の注意点
このコードをそのまま現場に投入する際、必ず考慮すべき「エンジニアとしての嗅覚」が3点ある。
① パフォーマンスと画面描画の制御
大規模ドキュメントで`Application.ScreenUpdating = True`のまま実行すると、描画処理で数分単位のロスが発生する。必ず処理の前後で`ScreenUpdating`を制御し、Wordの描画を止めること。
② ワイルドカード検索との親和性
もし`UseWildcards = True`で正規表現を活用する場合、`rng.Text`の置換と`Replacement.Text`の挙動に差異が生じることがある。複雑な正規表現を用いる際は、一旦検索ヒットした箇所を`Range`として特定し、そのRangeに対して直接文字列を書き換える手法が最もバグを産まない。
③ Excelとのコネクション管理
上記コードは`CreateObject`を使用しているが、処理中にExcelがクラッシュした場合、バックグラウンドでプロセスが残り続ける(ゾンビプロセス)。`Error Handler`を実装し、異常終了時でも`xlApp.Quit`が走るような防御的プログラミングを徹底せよ。
—
結論:自動化は「責任」を伴う
置換の自動化は、単なるテキストの置き換えではない。ドキュメントの整合性という企業の資産を守る作業だ。
「とりあえず動いた」で満足するジュニアレベルから脱却し、ログを残し、検証可能なプロセスを構築する。これこそが、信頼される業務自動化エンジニアの条件である。
今日のコードをベースに、自社のドキュメント管理ルールに合わせた「最強のロギング・ツール」へと昇華させてほしい。何か不明点があれば、またいつでも問いに答える。準備はいいか?
