【入門編】Wordの『ストーリー』を理解する:ヘッダー・フッター・本文を横断する一括置換 – Word VBA解析バイブル

スポンサーリンク

こんにちは!今日から一緒にWord VBAの奥深い世界を探求していくエンジニアの先輩です。

Excel VBAの経験がある方でも、Word VBAに触れた瞬間に「なんだか勝手が違うぞ…?」「マクロの記録で置換処理を作ったのに、ヘッダーやフッターが置換されない!」という壁にぶつかることがよくあります。

実はそれ、あなたが書いたコードのせいではありません。Wordというアプリケーションが内部で持っている『ストーリー(Story)』という独自のオブジェクト構造が原因なのです。

この記事では、マクロの記録から一歩踏み出し、Word文書のあらゆるテキスト領域(本文、ヘッダー、フッター、脚注など)を完璧に網羅して一括置換するプロフェッショナルな手法を解説します。

ここをクリアすれば、Word VBAの基本構造の理解はバッチリですよ!一緒にマスターしていきましょう。

1. Wordの裏側に広がる「ストーリー」という世界

Excelは「セル(Cell)」の集合体ですが、Wordは「透明な層(レイヤー)が重なり合った構造」をしています。Word VBAの世界では、この各層のことを「ストーリー(Story)」と呼びます。

私たちが普段目にする文書は、1枚の紙に見えて、実は以下のように複数の「独立したテキスト領域」がレイヤーとして重なり合っているのです。

Word文書の立体構造(ストーリー概念図)

┌─────────────────────────────────────────────────────────┐
│ Layer 1: ヘッダー階層 (wdPrimaryHeaderStory) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 社外秘 Documents │ │
│ └───────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ Layer 2: 本文階層 (wdMainTextStory) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 第1章 はじめに │ │
│ │ 本文のテキストがここに入ります… │ │
│ └───────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ Layer 3: 脚注階層 (wdFootnotesStory) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 1 用語の定義について │ │
│ └───────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ Layer 4: フッター階層 (wdPrimaryFooterStory) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Page – 1 – │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

なぜ「マクロの記録」では不十分なのか?

Wordで「置換」を実行するマクロを記録すると、通常は `ActiveDocument.Content`(本文ストーリーのみ)や、操作時の `Selection`(選択領域)に対して置換を行うコードが生成されます。

そのため、どれだけ頑張ってマクロを動かしても、ヘッダーやフッター、脚注、テキストボックスの中身はスルーされてしまうのです。

2. ストーリー走査の決定版:トラップを回避する2重ループ

文書全体を漏れなく一括置換するには、「すべてのストーリーを巡回する」必要があります。

ここで、多くのVBAプログラマーがハマる「最大の落とし穴」が存在します。

🚨 陥りやすい罠:`StoryRanges` の単体 `For Each` では足りない?

Wordの `Document.StoryRanges` コレクションは、各ストーリー種別の「最初の1つ」しか保持していません。

例えば、文書内にセクションが複数あり、ヘッダーが「前と同じ」ではなく独立している場合(セクション1のヘッダー、セクション2のヘッダー…)、単に `For Each rng In doc.StoryRanges` でループを回すだけでは、2つ目以降のセクションのヘッダーを見落としてしまうのです!

これを解決するために、Word VBAでは `NextStoryRange` プロパティを使って数珠つなぎにリンクされたストーリーを辿る2重ループ が必須テクニックとなります。

3. 実践コード:全ストーリー横断・安全確実な一括置換

それでは、現場でそのまま使える「完全全領域置換マクロ」のコードをご覧ください。

Option Explicit

”’

”’ 文書内のすべてのストーリー(本文・ヘッダー・フッター・脚注・テキストボックス等)を
”’ 網羅的に走査し、指定した文字列を全置換します。
”’

Public Sub ReplaceTextInAllStories()
‘ 検索・置換したい文字列を定義
Dim findText As String
Dim replaceText As String

findText = “旧会社名”
replaceText = “新会社名”

‘ 画面描画を停止(処理の高速化とチラつき防止)
Application.ScreenUpdating = False

Dim doc As Document
Set doc = ActiveDocument

Dim targetRange As Range

‘ — 【アプローチ】全ストーリーコレクションをループ —
For Each targetRange In doc.StoryRanges

‘ StoryRangesコレクションから取得したRangeが存在する間ループ
‘ (セクションで分断されたヘッダーなどを NextStoryRange で辿る)
Do While Not targetRange Is Nothing

‘ Findオブジェクトの初期化と置換条件の設定
With targetRange.Find
.ClearFormatting ‘ 検索条件の書式をクリア
.Replacement.ClearFormatting ‘ 置換条件の書式をクリア

.Text = findText ‘ 検索する文字列
.Replacement.Text = replaceText ‘ 置換後の文字列

.Forward = True ‘ 下方向へ検索
.Wrap = wdFindContinue ‘ 範囲末尾に達したら先頭に戻る
.Format = False ‘ 書式検索をオフ
.MatchCase = True ‘ 大文字・小文字を区別する
.MatchWholeWord = False ‘ 単語全体の一致を求めない
.MatchByte = False ‘ 半角・全角を区別する
.MatchWildcards = False ‘ ワイルドカードを使用しない

‘ すべて置換を実行 (wdReplaceAll = 2)
.Execute Replace:=wdReplaceAll
End With

‘ 次の連鎖ストーリー(次のセクションのヘッダーなど)を取得
‘ 存在しない場合は Nothing が返り、Do Loop を抜ける
Set targetRange = targetRange.NextStoryRange

Loop
Next targetRange

‘ 画面描画を再開
Application.ScreenUpdating = True

‘ 完了通知
MsgBox “文書全体の置換処理が完了しました!”, vbInformation, “処理完了”
End Sub

4. プロの視点:コードの解説とポイント

このコードが「なぜ強力で安全なのか」、知的な先輩エンジニアとして3つのポイントに分けて解説しますね。

① `For Each` と `Do While` の黄金タッグ

  • `For Each targetRange In doc.StoryRanges` で、「本文階層」「ヘッダー階層」「脚注階層」といったストーリーのカテゴリ(大枠)を切り替えています。
  • `Do While Not targetRange Is Nothing` 〜 `Set targetRange = targetRange.NextStoryRange` で、同じカテゴリ内で分断されている領域(セクションごとのヘッダーなど)を数珠つなぎに完走しています。

この2段構えにより、Word内の文字情報が存在する「あらゆる隙間」をモグラ叩きのように網羅できるのです。

② `Application.ScreenUpdating = False` の重要性

WordはExcel以上に、画面描画のオーバーヘッド(負荷)が大きいアプリケーションです。ヘッダーやフッターを開いて画面を書き換える動作は非常に重いため、処理前に画面更新をオフにし、最後にオンに戻すのがパフォーマンス維持の鉄則です。

③ `Find.ClearFormatting` の儀式

VBAで検索(`.Find`)を行う前には、必ず `.ClearFormatting` を呼ぶ癖をつけましょう。前回の手動操作で「太字検索」などの条件が残っていると、意図した文字がヒットしなくなる事故を防ぐことができます。

5. 初心者がハマりがちなトラブルQA

Q. テキストボックスの中身も置換されますか?

A. 基本的には置換されます!
Wordの標準的なテキストボックス内のテキストは `wdTextFrameStory` というストーリー種別として扱われるため、このロジックで網羅できます。ただし、図形グループ化(GroupShapes)の中にある複雑なテキストボックスなどは別のオブジェクトモデル操作が必要になる場合があります。まずは今回の基本ロジックで試してみてください。

Q. 実行したら画面が一瞬真っ白になったりチラついたりします

A. 正常な挙動ですが、コードの最後で `ScreenUpdating = True` に戻っているか確認しましょう!
もし途中でエラーが発生してストップした場合、画面更新がオフのままになってしまうことがあります。実務では `On Error GoTo` を使って、エラー発生時でも必ず `ScreenUpdating = True` を通すようにエラーハンドリングを組むと、より完璧なプロのコードになりますよ。

まとめ:Wordの構造を理解すればVBAは怖くない!

今回は、Word VBA最大の山場のひとつである「ストーリー(Story)」概念と全領域置換について解説しました。

  • Word文書は単一のテキストではなく、複数のストーリー(層)の集合体
  • 置換時は `StoryRanges` のループだけでなく、`NextStoryRange` の連鎖を辿る
  • `ScreenUpdating` と `ClearFormatting` でパフォーマンスと安全性を確保

この「ストーリー」という概念さえ頭に入ってしまえば、Word VBAのオブジェクトモデルの半分を掌握したようなものです。もう「マクロの記録」に頼らなくても、自分の意図した通りにWordを動かせる基礎体力が身につきましたね。

「ここをクリアすれば、Word VBAの基本はバッチリですよ!」

ぜひご自身の環境でコードをコピペして動きを試してみてください。もし動かない文書があったり、疑問が湧いてきたりしたら、いつでも遠慮なく聞いてくださいね。応援しています!

タイトルとURLをコピーしました