【入門編】Word VBAで作成する『文書比較ツール』:2つの文書の差分を色付けして抽出するロジック – Word VBA解析バイブル

スポンサーリンク

Word VBAの深淵へ:差分抽出エンジンを構築する

Wordマクロの世界へようこそ。多くの人が「マクロの記録」から始めますが、そこから先へ進むには、Wordが内部で世界をどう捉えているか——つまり「オブジェクトモデル」の哲学を理解する必要があります。

今回は、実務で圧倒的に価値の高い「2つの文書の差分を抽出し、可視化するエンジン」の作り方を解説します。単にコードを並べるのではなく、Wordの心臓部である `Compare` メソッドと、その出力を操る `Range` オブジェクトの神髄に迫ります。

1. Wordオブジェクトモデルの「三種の神器」

Word VBAを操る上で、まずは以下の3つの概念を脳内にインストールしてください。

  • Application: Wordそのもの。全ての頂点です。
  • Document: 「文書」という実体。ここが情報のキャンバスです。
  • Range: ここが最重要です。 カーソル(Selection)と違い、画面を動かさずに文書内の「特定の範囲」を操作できる、メモリ上の透明な物差しです。

「マクロの記録」で生成される `Selection` は、画面の操作をなぞるため動作が極めて低速です。プロのエンジニアは、常に `Range` を使って、目に見えない裏側で高速に処理を行います。

2. 差分抽出エンジンの設計思想

Wordには標準で「文書の比較」機能がありますが、これをVBAから叩くことで、自動化の道が開けます。

手順のイメージ

1. 比較対象の特定: 元の文書(Original)と変更後の文書(Revised)を指定。
2. Compareメソッドの実行: Wordの比較エンジンを呼び出し、新しい文書に結果を吐き出す。
3. 差分の走査: レポートの中から「変更箇所」を特定し、`Range` オブジェクトで色を塗る。

3. 実装:差分抽出マクロ

以下のコードは、デスクトップにある2つのファイルを比較し、変更箇所を赤字でマーキングして別ファイルとして保存するロジックです。

Sub CreateDiffReport()
Dim docOrig As Document, docRev As Document, docReport As Document
Dim diffRange As Range

‘ 1. 文書を開く(実務ではパスは変数で管理しましょう)
Set docOrig = Documents.Open(“C:\Work\Original.docx”, ReadOnly:=True)
Set docRev = Documents.Open(“C:\Work\Revised.docx”, ReadOnly:=True)

‘ 2. 比較エンジンの実行
‘ Compareメソッドは新しいドキュメントを生成します
Set docReport = Application.CompareDocuments( _
OriginalDocument:=docOrig, _
RevisedDocument:=docRev, _
Destination:=wdCompareDestinationNew)

‘ 3. レポート内の差分を特定し、ハイライトする
‘ Wordの比較結果は「校閲」機能の履歴として残ります
Dim rev As Revision
For Each rev In docReport.Revisions
‘ 変更箇所のRangeを取得
Set diffRange = rev.Range

‘ 差分箇所を赤字で強調
With diffRange.Font
.Color = wdColorRed
.Bold = True
End With
Next rev

‘ 4. 後始末(メモリリークを防ぐための重要な作法)
docOrig.Close SaveChanges:=False
docRev.Close SaveChanges:=False

MsgBox “差分レポートが完成しました!”, vbInformation
End Sub

4. プロの視点:陥りやすい罠と解決策

「Selection」を使ってはいけない

初心者がやりがちなのは `Selection.Move` を繰り返す処理です。これは文書が長くなるとPCがフリーズします。必ず `Revision` オブジェクトをループで回し、`rev.Range` を対象にするようにしてください。

メモリの管理(Objectの解放)

VBAは自動でメモリを解放してくれますが、`Set docOrig = Nothing` と明示的に記述する癖をつけておきましょう。大規模な文書を扱う際、メモリ不足によるクラッシュを防ぐための防波堤となります。

なぜ「Range」なのか

`Range` は文書の「開始位置」と「終了位置」という2つのポインタを持つオブジェクトです。文字を選択せずに文字のフォントやスタイルを変更できるため、処理速度が `Selection` と比較して桁違いに速いのです。これが、「マクロの記録」を卒業したエンジニアの武器です。

最後に:ここをクリアすれば「脱・初心者」

今回のコードで、あなたは「Wordという巨大なアプリケーションのエンジンをVBAから呼び出し、その結果を構造的に解析する」という、高度な自動化の入り口に立ちました。

次は、`rev.Type` を判定して「削除された箇所は取り消し線にする」「追加された箇所は下線を引く」といった条件分岐を追加してみてください。そうすれば、あなたのツールは「おもちゃ」から「業務必須のエンジニアリング資産」へと進化します。

Word VBAは奥が深いですが、一度その構造を掌握すれば、これほど頼もしい相棒はいません。応援しています。また次の技術深掘りでお会いしましょう。

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