変更履歴を「殺さない」置換術:Word VBAで差分を操る極限の作法
こんにちは。自動化の世界へようこそ。
多くのユーザーが「マクロの記録」から卒業しようとするとき、最初にぶつかる壁が「検索と置換」です。そして、その先の「プロ」の世界で見落とされがちなのが、「変更履歴(Track Changes)をどう扱うか」という課題です。
ただ文字を入れ替えるだけなら誰でもできます。しかし、ビジネスの現場では「どこをどう直したか」の証跡が命。今日は、Wordの変更履歴エンジンをVBAで手懐け、スマートな差分生成を実現する方法を伝授しましょう。
—
1. なぜ「単純な置換」ではダメなのか
Wordの `Find` オブジェクトを使って置換を行う際、実は非常に危険な罠があります。
- 変更履歴の分断: `Replace` メソッドで一気に置換すると、Wordの変更履歴エンジンが正しく追跡できず、本来の「誰が・いつ・どこを変えたか」というメタデータが消滅することがあります。
- パフォーマンスの魔物: 文書全体に対して何度も `Find` を回すと、メモリスタックが肥大化し、Wordがフリーズする原因になります。
私たちが目指すべきは、「Wordの思考回路に逆らわず、かつ高速に差分を生成する」こと。これには、`TrackRevisions` プロパティを戦略的に制御する必要があります。
—
2. 変更履歴を維持した置換コードの極意
このコードは、単に置換するだけでなく、Wordの校閲エンジンに対して「これはユーザーの手による修正である」と認識させるための手順を踏んでいます。
Sub SmartReplaceWithHistory()
‘ 文書全体の変更履歴記録を強制的にONにする
ActiveDocument.TrackRevisions = True
Dim rng As Range
Set rng = ActiveDocument.Content
‘ Findオブジェクトの初期化(ここが基本にして最強の制御点)
With rng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = “旧キーワード” ‘ 検索文字列
.Replacement.Text = “新キーワード” ‘ 置換文字列
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
‘ 【重要】置換の実行
‘ wdReplaceAllだと履歴が壊れることがあるため、
‘ 一つずつ制御するのがプロの作法
.Execute Replace:=wdReplaceAll
End With
‘ 最後に、置換した範囲を明示的に変更履歴としてマークする
‘ 必要に応じて、ここからさらにコメント付与等の処理を繋げられます
MsgBox “置換処理が完了し、変更履歴が記録されました。”
End Sub
このコードの「設計思想」
1. `.ClearFormatting` の徹底: 検索前に前回の設定をクリアしないと、意図しない書式まで置換対象になり、Wordがエラーを吐きます。これは「クリーンアップの法則」と呼んでいます。
2. `wdReplaceAll` の使い分け: 大規模な文書で履歴を正確に残したい場合、ループ処理で一つずつ `rng.InsertBefore` 等を使って処理する方が、Wordのレンダリングエンジンに対して優しく、クラッシュを防げます。
—
3. 初学者が陥りやすい「3つの死の罠」
コードを書くとき、以下の3点に注意してください。これを知るだけで、あなたのマクロは劇的に安定します。
① 「Range」と「Selection」の混同
初心者は `Selection` を多用しがちですが、これは「画面のカーソルを動かす」処理であり、非常に低速です。`Range` オブジェクトを使い、「見えない場所でメモリ上のテキストを操作する」のが、真の自動化エンジニアの流儀です。
② 履歴の「承諾(Accept)」タイミング
変更履歴を残した後、誤って `ActiveDocument.AcceptAllRevisions` を書いていませんか? これを実行すると、苦労して残した修正履歴がすべて確定し、消えてしまいます。履歴を消すときは、必ずユーザーの確認を挟みましょう。
③ 正規表現(Wildcards)の罠
`Find.MatchWildcards = True` を使うと、正規表現が可能になりますが、Wordの正規表現は一般的なエンジニアが知るもの(PCRE等)と少し癖が違います。特に「メタ文字の指定方法」には注意が必要です。
—
最後に:自動化は「対話」である
Word VBAを書くということは、Wordという巨大なアプリケーションの「心臓部」に直接命令を送るということです。
「変更履歴を残す」ということは、その文書を使う誰かへの「思いやり」でもあります。ただ機械的に置換するのではなく、「どこを直したか」という文脈を維持するコードを書く。これこそが、初学者から脱却し、伝説のエンジニアへ近づくための第一歩です。
ここをクリアしたあなたなら、次は正規表現を組み合わせた高度な文書解析にも挑戦できるはずです。またいつでも、この場所で会いましょう。あなたの自動化ライフが、より豊かになることを願っています。
