Word VBAを掌握せよ:隠し文字の「呪縛」を解く、プロフェッショナルなクリーニング術
Wordで文書を作成していると、なぜか見えないはずの文字列が浮き上がったり、あるいは機密保持のために隠したつもりのメモが残存していたりという「事故」に遭遇したことはないだろうか。
Wordの「隠し文字(Hidden属性)」は、単なるテキストの装飾ではない。それはWordのオブジェクトモデルにおいて、`Font.Hidden`というプロパティが制御する、文書のメタデータの一種だ。
今回は、この隠し文字を「狩る」ための堅牢なVBAツールを設計する。単にループを回すだけではない。メモリ効率、文書の整合性、そして保守性を極限まで高めたコードを伝授しよう。
—
1. なぜ「力技」のループが危険なのか
初心者レベルのコードでは、`ActiveDocument.Words`を全走査したり、安易に`Find`オブジェクトを連打したりしがちだ。しかし、これらは以下の理由で「爆弾」を抱えている。
- パフォーマンスの欠如: `Words`コレクションは文書内の全単語をオブジェクト化するため、数千ページある文書ではメモリを食いつぶし、処理が停止する。
- 不完全な検索: `Range.Find`による置換処理を繰り返すと、文書の再描画(Repagination)が走り、処理速度が指数関数的に低下する。
- Undoスタックの肥大化: 変更のたびにUndo(元に戻す)履歴が生成され、大規模な文書ではツール実行後にWordがフリーズする。
プロの流儀: 必要なのは「検索」と「削除」の処理を分離し、`Find`オブジェクトの`Execute`メソッドをスマートに使いこなすこと。これに尽きる。
—
2. 隠し文字を殲滅するプロダクションコード
以下は、文書内の隠し文字を検索し、存在すれば即座にログを出し、一括で削除する堅牢なツールだ。
Option Explicit
‘ ———————————————————
‘ 隠し文字クリーニングツール
‘ 目的: 文書内の全隠し文字を特定し、削除する
‘ ———————————————————
Public Sub CleanHiddenText()
Dim doc As Document
Set doc = ActiveDocument
‘ 画面更新を停止(高速化の鉄則)
Application.ScreenUpdating = False
Dim rng As Range
Set rng = doc.Content
‘ Findオブジェクトで隠し文字を高速検索
With rng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Font.Hidden = True ‘ 隠し文字属性のみをターゲットにする
.Text = “”
.Forward = True
.Wrap = wdFindContinue
.Format = True
‘ ヒットした箇所を順次処理
Do While .Execute
‘ ログ出力:デバッグウィンドウ(Ctrl+G)で確認
Debug.Print “発見: ” & rng.Text
‘ 削除処理
rng.Delete
‘ 削除後のRange再設定(重要:これを行わないと無限ループやエラーになる)
rng.Collapse Direction:=wdCollapseEnd
Loop
End With
Application.ScreenUpdating = True
MsgBox “隠し文字のクリーニングが完了しました。”, vbInformation
End Sub
このコードの「設計思想」
1. `Application.ScreenUpdating = False`: Wordの再描画を抑制する。これがないコードは、プロの現場では「未完成」とみなす。
2. `rng.Collapse`: `Delete`した後のポインタを適切に制御することで、再検索の際に同じ箇所を永遠にループする事故を防いでいる。
3. 明示的な`.ClearFormatting`: Word VBAは以前の検索設定を記憶する。次に呼び出す時、あるいは他のマクロが実行された時に誤作動しないよう、検索開始時に環境をクリーンにするのが鉄則だ。
—
3. 実運用における「落とし穴」と対策
このツールを業務に組み込む際、以下の点に注意せよ。
1. 「表示・非表示」のトグル切り替え
削除する前に「何が隠されているか」を確認したい場合があるだろう。その場合は以下の1行をプロシージャに組み込め。
ActiveWindow.View.ShowHiddenText = Not ActiveWindow.View.ShowHiddenText
これをボタンに登録しておけば、開発者やレビュアーが即座に隠し文字を可視化できる。
2. データベースや他ファイル連携の罠
もしこの処理を外部のExcelファイルから呼び出す場合、`Word.Application`のインスタンス管理を徹底すること。
- `Set wdApp = New Word.Application` で起動した後は、必ず `wdApp.Quit` を行うこと。
- 特に隠し文字を削除するような破壊的処理を行う場合は、必ず `doc.SaveAs2` で別名保存し、原本を汚さない設計にせよ。
3. トラッキング変更(変更履歴)への配慮
文書に「変更履歴の記録」がオンになっている場合、隠し文字を削除すると全て「削除」として記録が残る。これが許容される環境か、あるいは削除前に履歴を確定させる必要があるかを、ビジネス要件として必ず確認すること。
—
最後に:エンジニアとしての矜持
VBAはレガシーと言われることもあるが、Wordという巨大なモンスターを制御する上では、これほど強力で直接的な武器はない。隠し文字一つとっても、それを「なんとなく」扱うのではなく、オブジェクトのライフサイクルを理解し、パフォーマンスを考慮して書く。
その小さな積み重ねが、チーム全体の業務効率を劇的に改善する。さあ、このコードをあなたのツールボックスに加え、文書管理の「呪縛」を解き放て。
何か疑問があれば、いつでも聞いてほしい。コードの先にある「アーキテクチャの真実」を語ろう。
