こんにちは!Word VBAの世界へようこそ。
マクロの記録ボタンを押すだけのステップから抜け出し、「自分の手で自由自在にドキュメントを操りたい」と感じ始めているなら、あなたはすでに中級者の扉を開けています。
Wordの「置換(Replace)」機能は非常に強力ですが、実際に実務で使ってみると、こんなジレンマにぶ1つや2つぶつかったことはありませんか?
- 「『Word』という単語を『Microsoft Word』に一括置換したい。でも、すでに『Microsoft Word』と書いてある部分まで重複して『Microsoft Microsoft Word』になってしまう……!」
- 「会社名の略称を正式名称に直したいけど、特定の部署名の中にある略称だけは除外したい……」
一括置換は便利すぎるゆえに、「ここを変えたらダメなのに!」という部分まで容赦なく書き換えてしまう暴君です。
今回は、この暴君を完璧に手なずけるための技術、「配列を使った除外リスト付き・スマート置換エンジン」の作り方を伝授します。ここをクリアすれば、あなたのWord VBAのスキルは間違いなく一段階上のステージに到達しますよ。
—
1. なぜ「一括置換(`Execute Replace:=wdReplaceAll`)」ではダメなのか?
Word VBAで最もよく使われる置換コードはこれですね。
‘ ズボラな一括置換の例(危険!)
Selection.Find.ClearFormatting
Selection.Find.Text = “Word”
Selection.Find.Replacement.Text = “Microsoft Word”
Selection.Find.Execute Replace:=wdReplaceAll
このコードは一瞬で仕事を終わらせてくれますが、「条件付きの判断」が一切できません。
検索にヒットした瞬間、Wordは機械的に文字を書き換えてしまいます。すでに「Microsoft Word」となっている箇所も、「Word」が含まれているため二重に置換されてしまうのです。
解決のアプローチ:1件ずつ「目視」ならぬ「コードによる判定」を行う
これを防ぐには、一括置換 (`wdReplaceAll`) を使うのをやめ、「1件ずつ検索してヒットさせ、それが除外リストに含まれていなければ置換する」というループ処理(個別置換)を実装する必要があります。
—
2. 実装の全体像:スマート置換エンジンの設計図
今回作成するマクロのアルゴリズムは以下の通りです。とてもシンプルですが、実務で猛威を振るう堅牢な仕組みです。
1. 除外リスト(配列)の定義:置換したくないキーワードをあらかじめ用意する。
2. ループ検索の開始:文書の先頭から「検索ワード」を探す。
3. 除外判定:ヒットした箇所の周辺(またはそのもの)が、除外リストに一致するかチェックする。
4. アクションの分岐:
- 一致するなら → 「スキップ!」(何もしないで次の検索へ)
- 一致しないなら → 「置換実行!」
5. 文書末尾に到達するまで繰り返す。
—
3. 実践!除外リスト付き置換エンジンのVBAコード
それでは、実際の開発現場でそのままコピペして使える完全版のコードをお見せします。
今回は例として、「Word」を「Microsoft Word」に置換する際、「Microsoft Word」とすでに書かれている部分はスキップするという処理を作ってみましょう。
Sub SmartReplaceWithExcludeList()
Dim rngTarget As Range
Dim searchWord As String
Dim replaceWord As String
Dim excludeList() As String
Dim i As Long
Dim isExclude As Boolean
‘ — 1. 設定エリア —
searchWord = “Word”
لreplaceWord = “Microsoft Word”
‘ 除外したいキーワードのリストを配列で定義します
‘ ここに含まれている文字列にヒットした場合は置換をスルーします
excludeList = Split(“Microsoft Word,Visual Basic for Word”, “,”)
‘ — 2. 検索範囲(ストーリー)の取得 —
Set rngTarget = ActiveDocument.Content
‘ 検索条件の初期化
With rngTarget.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = searchWord
.Forward = True
.Wrap = wdFindStop ‘ 文書の最後まで来たら終了する
.Format = False
.MatchCase = False
.MatchWholeWord = True
End With
‘ — 3. 1件ずつヒットを確認しながらループ処理 —
Do While rngTarget.Find.Execute
‘ デバッグ用(イミディエイトウィンドウにヒットした位置を表示)
‘ Debug.Print “ヒット: ” & rngTarget.Text
‘ 初期化
isExclude = False
‘ — 4. 除外リストとの照合チェック —
For i = LBound(excludeList) To UBound(excludeList)
‘ ヒットした箇所の「前後の文脈」を含めて除外判定したい場合は
‘ rngTargetの拡張や周辺テキストの取得を行います。
‘ 今回はシンプルに「ヒットしたテキスト自体、あるいはその周辺」を想定
‘ ※より厳密に「すでにMicrosoft Wordとなっている場合」を弾くため、
‘ ヒットしたレンジの前後を含めた文字列で判定するテクニック
Dim checkRange As Range
Set checkRange = rngTarget.Duplicate
‘ 前後に文字を少し広げて確認する(必要に応じて調整)
checkRange.Start = checkRange.Start – 10
checkRange.End = checkRange.End + 10
‘ 除外ワードが含まれているか?
If InStr(1, checkRange.Text, excludeList(i), vbTextCompare) > 0 Then
isExclude = True
Exit For ‘ リストのチェックを抜ける
End If
Next i
‘ — 5. 除外フラグに応じた処理 —
If isExclude Then
‘ 除外対象なので置換をスキップし、検索位置をヒット箇所の後ろに進める
rngTarget.Collapse wdCollapseEnd
‘ Debug.Print ” -> 【スキップしました】”
Else
‘ 除外対象外なので置換を実行
rngTarget.Text = replaceWord
‘ 置換した文字の末尾へレンジを移動(無限ループ防止)
rngTarget.Collapse wdCollapseEnd
‘ Debug.Print ” -> 【置換しました】”
End If
Loop
MsgBox “スマート置換が完了しました!”, vbInformation
End Sub
—
4. コードの深掘り:ここがエンジニアのこだわりポイント
初心者が陥りがちな罠と、それを回避するためのプロの知見をいくつか解説しておきます。
① `wdFindStop` と `Collapse` のコンボが命綱
ループ処理の中で `.Execute` を使うとき、`Wrap` の設定を `wdFindContinue`(文書の最後まで行ったら先頭に戻る)にしていると、無限ループの悪夢にハマります。
「見つかったら範囲を後ろに折りたたむ(`Collapse wdCollapseEnd`)」ことで、常に「いま見つかった場所の直後」から検索を再開させることが、バグを防ぐ鉄則です。
② `Split` 関数による柔軟な除外リスト
今回のコードでは、
excludeList = Split(“Microsoft Word,Visual Basic for Word”, “,”)
という書き方をしています。これなら、除外したいワードが増えたときも、カンマ区切りで文字列を追加するだけで配列に格納されるため、メンテナンス性が劇的に向上します。
③ 前後関係(文脈)を読む `checkRange` のテクニック
単に「Word」という単語を探すだけだと、「Microsoft Word」の中にある「Word」の直前だけを見て判断するのは難しい場合があります。
プロのテクニックとして、ヒットしたレンジの前後数文字を含めた `checkRange` を一時的に作り、その中に「Microsoft Word」という文字列が丸ごと含まれていないかを `InStr` 関数でチェックしています。これにより、誤爆を完全に防ぐことができます。
—
最後に:ここをクリアすれば、Word VBAは怖くない!
お疲れ様でした!一括置換の便利さと危険性を理解し、それをコードによる制御でコントロールする手法は、業務自動化において非常に強力な武器になります。
「ただ動くコード」から「意図通りに安全に動くロジック」へ。
この視点を持てたあなたなら、どんなに複雑な社内フォーマットの整形や、大量のドキュメント修正も、自信を持って自動化できるはずです。
もし実際に動かしていて「ここはどういう意味?」「こういうケースはどう書けばいいの?」という疑問が出てきたら、ぜひご自身の環境でアレンジを重ねてみてください。試行錯誤の数だけ、あなたのエンジニアとしての血肉になりますよ。
それでは、快適なWord VBAライフを!
