こんにちは!Word VBAの世界へようこそ。
マクロの記録ボタンを押してコードを作ってみたものの、「あれ?なんだか不要な記述が多すぎるぞ」「本当に置換したい部分だけが変わらない…」と悩んでいませんか?
今回は、中級者へのステップアップとして絶対に避けて通れない「書式を保持したまま、特定の条件を満たす段落内だけを狙い撃ちして文字列を置換する技術」を解説します。
ここをクリアすれば、Word VBAの挙動の裏側にある「オブジェクトの意思」が手に取るようにわかるようになりますよ。しっかりついてきてくださいね!
—
なぜ「ふつうの置換」ではダメなのか?
Wordの「検索と置換(Ctrl + H)」は非常に強力ですが、VBAでこれを単純に自動化しようとすると、次のような壁にぶつかります。
- 「特定のフォントサイズやスタイルが適用されている段落の中だけ」という条件をつけたい
- 文字列は変えたいけれど、そこに元々設定されていた太字や文字色の書式はそのまま維持したい
マクロの記録をそのまま使うと、ドキュメント全体が対象になってしまったり、余計な選択(Selection)処理が入って処理が極端に遅くなったりします。
そこで登場するのが、Word VBAの真骨頂である `Find` オブジェクトの高度な条件設定 です。
—
極意:Findオブジェクトの「書式フィルター」を使いこなす
Word VBAでスマートに検索・置換を行うための鉄則は、画面上のカーソル(Selection)を動かさないことです。`Range` オブジェクトを背後で静かに操作するのが、プロのエンジニアのやり方です。
今回のテーマを実現するためには、以下の2つのステップを踏みます。
1. 検索条件(Find)に「特定の書式」というフィルターをかける
2. ヒットした範囲(Range)のなかで、文字列だけを書き換える
実装コード:条件付き・書式保持置換マクロ
それでは、実際の現場でそのまま使える実用コードを公開します。VBAエディタ(Alt + F11)を開き、標準モジュールに貼り付けてみてください。
Sub ReplaceTextWithFormatting()
Dim rngTarget As Range
Set rngTarget = ActiveDocument.Content ‘ ドキュメント全体の範囲を取得
‘ 検索・置換条件を設定するFindオブジェクトの準備
With rngTarget.Find
.ClearFormatting ‘ 前回の検索条件を必ずクリアする(※重要!)
.Replacement.ClearFormatting
‘ — 1. 検索する条件の設定 —
.Text = “古い文字列” ‘ 探したいキーワード
‘ 【重要】ここで「特定の書式」を指定します
‘ 例として、フォント名が「メイリオ」に限定して検索する場合
.Font.Name = “メイリオ”
‘ — 2. 置換する内容の設定 —
.Replacement.Text = “新しい文字列”
‘ — 3. 動作の実行オプション —
.Forward = True
.Wrap = wdFindStop ‘ 文書の最後まで来たら終了する
.Format = True ‘ 書式を検索・置換の条件に含める(超重要!)
.MatchCase = False
.MatchWildcards = False
.MatchWholeWord = False
‘ 一括置換を実行(条件に合致するものだけが置換される)
.Execute Replace:=wdReplaceAll
End With
MsgBox “指定された書式内の文字列置換が完了しました!”, vbInformation
End Sub
—
コードの核心を解説:初心者が陥る「3つの罠」
上記のコードには、Word VBA特有の「知っていないと絶対にハマる罠」を防ぐためのノウハウが詰まっています。
罠1:`.ClearFormatting` を忘れて前回のゴミを引き継ぐ
Wordの検索機能は、一度設定した「フォント」や「段落書式」の記憶をずっと保持し続けます。コードの最初に `ClearFormatting` を入れない場合、「前回検索したときの不要な条件が残ったままになり、1件もヒットしない」という怪奇現象が起きます。必ずセットで書きましょう。
罠2:`.Format = True` を書き忘れる
「コードに `.Font.Name = “メイリオ”` って書いたんだから動くはず!」と思っていませんか?
実は `.Format = True` というスイッチを明示的にONにしないと、Wordは書式条件を無視して文字列だけに反応してしまいます。ここが中級者への分かれ道です。
罠3:Selection頼みでパフォーマンスが崩壊する
`Selection.Find` を使ってしまうと、画面の描画(スクロール)が発生するため、ページ数が多い文書だと数分かかる場合があります。今回のコードのように `Range.Find` を使えば、メモリ上で高速に処理が完結するため、数万行の文書であっても一瞬で終わります。
—
応用編:特定の「段落スタイル」に限定したい場合
もし「フォント」ではなく、Wordにあらかじめ登録されている「段落スタイル(例: 見出し 1)」の中だけを置換したい場合は、先ほどのコードの検索条件部分を次のように書き換えます。
‘ 検索条件のフォント指定の代わりに、スタイルを指定する
.Style = ActiveDocument.Styles(“見出し 1”)
.Format = True ‘ スタイルを指定する場合もFormat = Trueが必要
これだけで、「『見出し 1』スタイルが適用されている段落の中に含まれる特定のキーワードだけ」を、その書式を一切崩さずに書き換えることができます。マニュアルのバージョンアップや用語の統一作業で、これほど頼りになる相棒はいません。
—
おわりに
お疲れ様でした!今回は「書式を保持したまま、特定の条件下で文字列を置換する」という、実務で直面しがちな難題をクリアするためのアプローチを解説しました。
- `Range` オブジェクトを使って画面をチラつかせずに処理する
- `.ClearFormatting` と `.Format = True` で検索条件をコントロールする
この2点を押さえておけば、Wordの自動化で怖いものはありません。
ぜひご自身の業務データで試して、その圧倒的なスピードと確実性を体感してみてください。あなたの事務作業の景色が、今日からガラッと変わるはずですよ!
