Word VBAの深淵:変更履歴を汚さずに書式を操作する「外科手術」の極意
Wordの変更履歴(Track Changes)は、ドキュメント管理の生命線である。しかし、我々のような自動化エンジニアにとって、この機能は時に「最も厄介な敵」となる。`Range.Font`や`Paragraph.Format`を安易に叩けば、即座に変更履歴として記録され、文書は真っ赤なノイズで埋め尽くされる。
「履歴を残さず、書式だけをクリーンに修正する」。これは単なるプログラミングテクニックではない。Wordのメモリ構造とオブジェクトのライフサイクルを理解した者にのみ許された、ドキュメントに対する「外科手術」である。
—
1. トラックチェンジの「罠」を回避する唯一の解
WordのCOMオブジェクトモデルは、多くの場合`UndoRecord`オブジェクトや`Application.Undo`の制御下にある。通常、プロパティ変更はイベントとして記録されるが、`Range.Revisions.AcceptAll`のような力技は、履歴を消滅させるため業務要件上許されないことが多い。
ここで我々が取るべき戦略は、「変更履歴の監視を一時的にバイパスする」手法である。
注意すべきメモリの「重み」
Wordのオブジェクト操作で頻発するリークは、`Paragraph`や`Range`をループ内で不用意に生成することに起因する。特に`ActiveDocument.Paragraphs`を直接イテレーションさせるのは、COMのスタックを圧迫し、大規模文書では致命的なパフォーマンス低下を招く。必ず参照を変数に退避させ、`Set obj = Nothing`で明示的に解放する。これはVBAにおける「生存戦略」だ。
—
2. 実践:履歴を汚さない書式更新のアーキテクチャ
以下のコードは、変更履歴を維持したまま、特定の段落のフォントスタイルを修正する最小構成のアーキテクチャである。
Option Explicit
‘ メモリリークを防ぐための最小構成
Public Sub SafeFormatUpdate()
Dim doc As Document
Dim para As Paragraph
Dim rng As Range
Set doc = ActiveDocument
‘ 処理の高速化とチラつき防止
Application.ScreenUpdating = False
‘ TrackChangesのステータスを退避(グローバル設定のバックアップ)
Dim isTracking As Boolean
isTracking = doc.TrackRevisions
‘ 一時的に履歴記録を無効化する
‘ ここが「外科手術」の核心部分である
doc.TrackRevisions = False
For Each para In doc.Paragraphs
‘ 特定の条件(スタイルや文字列)でフィルタリング
If para.Style = “標準” Then
Set rng = para.Range
‘ 書式操作のみを実行
With rng.Font
.Name = “游明朝”
.Size = 11
.Color = wdColorBlack
End With
Set rng = Nothing
End If
Next para
‘ 履歴記録を復元
doc.TrackRevisions = isTracking
Application.ScreenUpdating = True
End Sub
—
3. 深掘り:さらなる高みへ(Windows APIの活用)
もし、Word標準のオブジェクトモデルでさえ履歴が検知されるような極限の環境(古いWordのバージョンや、特殊なアドインが干渉している場合)では、Windows APIを介したメモリ直接操作、あるいはより堅牢なアプローチが必要になる。
例えば、`Word.Application.UndoRecord`を使用することで、一連の書式変更を「単一のトランザクション」としてまとめ、履歴上のノイズを最小化する。
‘ UndoRecordによる操作の隠蔽
Dim undo As UndoRecord
Set undo = Application.UndoRecord
undo.StartCustomRecord “FormatCleanup”
‘ ここに書式変更処理を記述
‘ …
undo.EndCustomRecord
この手法を使えば、たとえ数千行の変更を行っても、ユーザー側からは「一つのまとまった操作」として履歴に表示される。これは、変更履歴の汚染を最小限に抑えるための現代的な解法だ。
—
4. アーキテクトからの提言
システム開発において、「動けばいい」というコードは技術的負債の温床に過ぎない。特にWord VBAは、MS Officeという巨大なCOMサーバーの上で動く、不安定な土台である。
1. オブジェクトの生存期間を意識せよ: ループ内での`Set`と`Nothing`の儀式は、メモリ管理の基本である。
2. イベントの副作用を予測せよ: `TrackRevisions`の切り替えは強力だが、並行して走るアドインとの競合を常に計算に入れておくこと。
3. エラーハンドリングを怠るな: COMオブジェクトが予期せぬタイミングで解放されるケースを想定し、必ず`On Error GoTo`で安全な終了処理を記述すること。
Wordというレガシーな巨大プラットフォームを掌握する唯一の方法は、その挙動を疑い、制御下に置くことである。健闘を祈る。
