こんにちは! Word VBAの自動化の世界へようこそ。
マクロの記録ボタンを押すだけのステップから一歩抜け出し、「自分の手で自由自在にドキュメントを操りたい」と感じているあなたへ。
今回は、Word VBA中級者への登竜門であり、避けて通れない重要テーマ「文字の検索・置換(Find & Replace)」、そしてその中で誰もが一度はハマる「検索対象が見つからないエラーのスマートな回避術」について、現場のプロフェッショナル目線で徹底解説していきます。
ここをクリアすれば、あなたの書くマクロは見違えるほど堅牢(ロバスト)になりますよ。さあ、一緒に扉を開けましょう!
—
なぜ、Wordの「置換」はVBAだと機嫌を損ねるのか?
Excel VBAで `Range.Replace` を使ったことがある方なら、「Wordでも `Find.Execute` を使えば一発だろ」と思われるかもしれません。しかし、WordのFindオブジェクトは、Excelのものとは比べ物にならないほど「人間臭く、かつ気難しい」のです。
画面上の「検索と置換」ダイアログを思い出してください。
アレと同じエンジンが裏で動いているため、VBAでコードを書いたとき、こんな現象が起きます。
- 探している文字がないと、マクロが途中でピタッと止まる(あるいは無視される)
- 意図しない場所から検索が始まり、文書全体がめちゃくちゃになる
- 終わりの判定を見誤って、無限ループの沼にハマる
特に、「検索対象が見つからない」ときに `Execute` メソッドが `False` を返す挙動をどう扱うかが、プログラミングのセンスの見せどころです。
—
初学者がやりがちな「危なっかしいコード」
まずは、よくある「やってしまいがちなコード」を見てみましょう。
Sub DangerousReplace()
‘ 【悪い例】エラーハンドリングや終了判定がない
Selection.Find.ClearFormatting
Selection.Find.Text = “旧ワード”
Selection.Find.Replacement.Text = “新ワード”
‘ これだと、見つからなかった時にどうなる…?
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
これ、一見動きそうですが、実務の現場では使い物になりません。「旧ワード」が文書内に1つもなかった場合、Word君は「見つからなかったよ!」と心の中で叫びながら、場合によっては予期せぬ挙動を引き起こします。また、`wdReplaceAll` を使わずに1つずつ置換していくループ処理を書く場合、終了判定をサボると永遠に終わらない呪いのループ(無限ループ)が完成します。
—
解決策:`Execute` の戻り値とスマートに向き合う
Word VBAで安全かつ確実な置換処理を行うための鉄則は、「`Find.Execute` の戻り値(Boolean型)を必ず受け取って判定すること」です。
`Execute` メソッドは、検索・置換が成功すれば `True` を、見つからなければ `False` を返します。これを利用して、「見つかったら処理を続ける、見つからなければ優しく終了する」という分岐を作ります。
実践:安全に単一置換を行うスマートなコード
以下のコードは、文書全体の特定のキーワードを探し、安全に置換処理を行い、その結果をメッセージで教えてくれる優れものです。
Sub SmartReplaceSample()
Dim rngTarget As Range
‘ 1. 処理対象の範囲(ここでは文書全体)をセット
Set rngTarget = ActiveDocument.Content
‘ 2. Findオブジェクトの設定をリセット(前回のゴミを残さない)
With rngTarget.Find
.ClearFormatting
.Replacement.ClearFormatting
‘ 3. 検索条件と置換後の文字を設定
.Text = “株式会社〇〇”
.Replacement.Text = “株式会社××”
‘ 4. 前方に向かって文書全体を検索する設定
.Forward = True
.Wrap = wdFindStop ‘ 文書端に達したら検索をストップ(無限ループ防止の要!)
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcard = False
‘ 5. 実行して、戻り値(True/False)を変数に格納
‘ wdReplaceAll を使わずに、あえて Execute の結果を判定する
Dim isFound As Boolean
isFound = .Execute(Replace:=wdReplaceAll)
End With
‘ 6. 結果に応じたスマートな分岐処理
If isFound Then
MsgBox “置換が正常に完了しました!”, vbInformation, “処理成功”
Else
‘ エラーで止まるのではなく、優しく通知する
MsgBox “指定された検索文字列は見つかりませんでした。”, vbExclamation, “通知”
End If
End Sub
—
ここがエンジニアのこだわり!「無限ループを防ぐ」ための3大ポイント
もしあなたが `wdReplaceAll`(一括置換)ではなく、「見つかったもの一件一件を確認しながら置換したい(Do〜Loopを使う)」という段階に進んでいるなら、以下の3つは絶対に覚えておいてください。
1. `.Wrap = wdFindStop` を必ず指定する
デフォルトのままだと、文書の最後まで検索した後に「最初に戻って検索を続けるか?」という挙動になり、これがVBAのループ内では無限ループの引き金になります。`wdFindStop`(端に来たら止まる)を明示するのがプロの作法です。
2. `Find.ClearFormatting` を怠らない
Wordの検索機能は、直前に行った検索の書体設定(太字だったか、フォントサイズはいくつだったかなど)をネチネチと記憶しています。マクロの最初に必ず `ClearFormatting` を入れ、まっさらな状態からスタートさせましょう。
3. 選択範囲(Selection)ではなく、レンジ(Range)を使う
マクロの記録を使うと `Selection.Find` が生成されますが、画面上のカーソルがチラついて処理が遅くなる原因になります。実務では `ActiveDocument.Content` などの `Range` オブジェクトを裏でこっそり操作するのが、高速かつスマートなモダンVBAの基本です。
—
まとめ:エラーを恐れず、コントロール下に置こう
今回は、Word VBAの置換処理における「検索対象が見つからないエラー」のスマートな回避術を解説しました。
- `Find.Execute` は `True` / `False` を返すので、必ず受け取って判定する。
- `.Wrap = wdFindStop` で無限ループの罠を断ち切る。
- エラーで止まるマクロではなく、優しく結果を伝えるロバスト(堅牢)なコードを書く。
この基本マインドさえ身につければ、どれほど複雑なWord文書の整形であっても、あなたのアバター(マクロ)が完璧にこなしてくれます。
ここをクリアしたあなたなら、もう初学者卒業は目の前です。ぜひ明日の実務から、この「スマートなエラー回避術」を取り入れてみてくださいね。それでは、また次回の知見でお会いしましょう!
