こんにちは! Word VBAの深淵へようこそ。
マクロの記録ボタンを押すだけのステージから抜け出し、「Wordという巨大なドキュメントエンジンを自分の手足のように操りたい」と考えているあなたへ。
今回は、実務の現場で必ずといっていいほど直面する「変更履歴の制御と、変更箇所の精密な特定」についてお話しします。
ここをクリアできれば、単なる「文字の置き換えマクロ」とはおさらばです。文書の歴史をプログラムで読み解き、意のままに操るプロフェッショナルへの扉が開きます。さあ、一緒に本質を学んでいきましょう!
—
1. Word VBAにおける「変更履歴」の正体を知る
まず、Wordの「変更履歴(Track Changes)」機能について、オブジェクトモデルの観点から本質を理解しておきましょう。
画面上では「ここに赤字が入っている」「ここが削除されている」と視覚的に見えますが、Wordの裏側(VBAの世界)では、これらは「Revision(リビジョン)オブジェクト」という独立したコレクションとして管理されています。
文書と変更履歴の構造
- `Document.TrackRevisions`: 文書の校閲モード(変更履歴の記録)自体のON/OFFを切り替えるスイッチです。
- `Document.Revisions`: 文書内に存在するすべての「変更履歴のコレクション」です。追加された文字、削除された文字、書式が変更された箇所などが、すべてここに時系列で格納されています。
ここがExcel VBAと大きく違うところです。Excelは「セルの値」を書き換えるだけですが、Wordは「文章の流れ(ストリーム)」の中に変更の履歴がメタデータとして埋め込まれています。だからこそ、「Rangeオブジェクト」と組み合わせることで、変更箇所ピンポイントで操作できるのです。
—
2. 校閲モードのON/OFFをプログラムで確実に制御する
まずは基本の「キ」。VBAから変更履歴の記録状態を強制的にコントロールする方法です。
「マクロを実行している間だけ変更履歴をオンにしたい」「いや、勝手に履歴を残させずに裏で修正したい」といったシーンで使います。
Sub ControlTrackChangesExample()
Dim doc As Document
Set doc = ActiveDocument
‘ 1. 現在の変更履歴の状態をチェックする
If doc.TrackRevisions = True Then
MsgBox “現在は【校閲モード:ON】です。”, vbInformation
Else
MsgBox “現在は【校閲モード:OFF】です。”, vbInformation
End If
‘ 2. 強制的に校閲モードをONにする
doc.TrackRevisions = True
‘ (ここに何らかのテキスト操作を入れる)
doc.Content.InsertAfter “この追記は変更履歴に残ります。”
‘ 3. 作業が終わったらOFFに戻す(必要に応じて)
‘ doc.TrackRevisions = False
MsgBox “変更履歴の制御テストが完了しました。”, vbInformation
End Sub
💡 先輩エンジニアからのワンポイントアドバイス
自動化スクリプトを書く際、「処理の途中で意図せず変更履歴が残ってしまい、後で大惨事になる」というミスが本当によく起きます。
マクロで一括置換を行うような処理で、ユーザーの変更履歴を汚したくない場合は、必ず処理の冒頭で `doc.TrackRevisions = False` を明示的に設定し、処理の最後で元の状態に戻す(あるいはそのままにする)配慮を忘れないようにしましょう。
—
3. 変更箇所を `Range` で特定し、特定の条件で抽出・操作する
ここからが本番です。「文書内のすべての変更履歴をループし、特定のユーザーによるものだけを抜き出したい、あるいは特定の操作(挿入か削除か)ごとに処理を分けたい」という実務必須のテクニックです。
以下のコードは、文書内の全リビジョンを走査し、それぞれの変更が「誰によって」「どこで行われたか(Rangeの取得)」をイミディエイトウィンドウに出力するサンプルです。
Sub InspectRevisionsWithRange()
Dim doc As Document
Dim rev As Revision
Dim targetRange As Range
Set doc = ActiveDocument
‘ 文書内に変更履歴が一つもない場合は早期脱出
If doc.Revisions.Count = 0 Then
MsgBox “変更履歴は存在しません。”, vbInformation
Exit Sub
End If
‘ すべての変更履歴をループ処理
For Each rev in doc.Revisions
‘ 変更箇所をRangeオブジェクトとして取得
Set targetRange = rev.Range
‘ 変更の種類を判定 (wdRevisionInsert = 挿入, wdRevisionDelete = 削除 など)
Dim revType As String
Select Case rev.Type
Case wdRevisionInsert
revType = “文字の追加”
Case wdRevisionDelete
revType = “文字の削除”
Case Else
revType = “その他の変更(書式など)”
End Select
‘ イミディエイトウィンドウ(Ctrl + G)に詳細を出力
Debug.Print “—————————————-”
Debug.Print “種類: ” & revType
Debug.Print “校閲者: ” & rev.Author
Debug.Print “日時: ” & rev.Date
Debug.Print “該当テキスト: ” & targetRange.Text
Next rev
MsgBox “変更履歴の解析が完了しました。イミディエイトウィンドウを確認してください。”, vbInformation
End Sub
このコードの何がスゴイのか?
`rev.Range` を取得している点に注目してください。
これにより、「変更されたその場所(Range)」に対して、フォントの色を変えたり、特定のキーワードが含まれているかチェックしたり、あるいはそのまま承諾(Accept)/拒否(Reject)するといった次のアクションへシームレスにつなげることができます。
—
4. 陥りやすい罠:ループ中の「承諾(Accept)」と「コレクションの破壊」
ここで、Word VBA初学者が99%ハマる最大の罠について警告しておきます。
変更履歴をループしながら、「特定の条件に合致したらその変更を承諾(Accept)して削除したい」と思ったとき、以下のようなコードを書きたくなりませんか?
‘ 【やってはいけないアンチパターン】
Dim i As Long
For i = 1 to doc.Revisions.Count
If doc.Revisions(i).Author = “山田 太郎” Then
doc.Revisions(i).Accept ‘ 承諾するとRevisionsコレクションから消滅する!
End If
Next i
これをやると、インデックスがズレてしまい、ループの途中でエラー(または意図しないスキップ)が発生します。コレクションの要素を削除・変更しながら前から順番にループを回すのは、VBAにおけるタブー中のタブーです。
🛠️ 正しい解決策:後ろからループ(逆順ループ)を回す
要素が減っていくコレクションを安全に処理する鉄則は、「後ろから数えて処理する(Step -1)」ことです。
Sub SafeAcceptRevisions()
Dim doc As Document
Dim i As Long
Set doc = ActiveDocument
‘ 最後のインデックスから1に向かって逆順にループを回す
For i = doc.Revisions.Count To 1 Step -1
‘ 例: 「山田 太郎」さんの変更であれば強制的に承諾する
If doc.Revisions(i).Author = “山田 太郎” Then
doc.Revisions(i).Accept
‘ ※拒否したい場合は doc.Revisions(i).Reject を使います
End If
Next i
MsgBox “指定した校閲者の変更履歴を正常に一括承諾しました。”, vbInformation
End Sub
この「逆順ループ」のテクニックを知っているだけで、あなたが一流のVBAエンジニアであることが証明できます。
—
まとめ:ここをクリアすればWord VBAは怖くない!
今回は、Word VBAにおける「変更履歴の制御」と「Rangeによる特定、そして安全なループ処理」について解説しました。
- `Document.TrackRevisions` で校閲モードを自由自在に操る。
- `Revision.Range` を通じて、変更箇所をピンポイントで特定・解析する。
- コレクションを操作するときは、逆順ループ(`Step -1`)でインデックスのズレを防ぐ。
この3つさえ押さえておけば、分厚い契約書や仕様書の校閲作業、複数人での修正履歴のクレンジングなど、実務で発生する面倒なドキュメント業務を一瞬で自動化できるようになります。
「ここをクリアすれば、Word VBAの基本はバッチリですよ!」
ぜひ、お手元の開発環境でコードを試して、その圧倒的なスピード感を体感してください。あなたの自動化ライフの健闘を祈っています!
