【入門編】Word VBAにおける『ストーリー』の階層構造:メインテキスト以外の領域を漏らさず操作する技術 – Word VBA解析バイブル

スポンサーリンク

こんにちは!Word VBAの世界へようこそ。
マクロの記録ボタンを押して、生成されたコードを眺めてみたものの、「なんだこれ、意味がわからない…」「選択(Selection)のオンパレードで動きが遅い!」と挫折しそうになっていませんか?

よく分かります。その壁を突破する鍵が、今回お伝えする「ストーリー(Story)」という概念です。

ここをクリアすれば、あなたも脱・初心者。Wordのドキュメント構造を完全に掌握し、どんな複雑な文書も一瞬で自動化できるようになりますよ。さあ、一緒にWord VBAの奥深い扉を開けていきましょう!

1. なぜ「Selection」だけでは実務で通用しないのか?

Word VBAを書き始めると、誰もが最初に `Selection.TypeText` や `Selection.Find` を使います。画面上でカーソルが動くので、動いている実感がわいて楽しいですよね。

しかし、実務で何百ページもの契約書やマニュアルを一括置換・整形しようとしたとき、この「選択(Selection)」方式は致命的な弱点を露呈します。

1. 圧倒的に遅い:画面の描画を伴うため、処理に時間がかかる。
2. 操作できる範囲が狭い:画面に映っている(アクティブな)本文しか触れない。

実は、Wordの文書(Document)は、私たちが普段目にする「本文」のほかにも、ヘッダー、フッター、テキストボックス、脚注など、いくつもの独立した「部屋」に分かれています。これらをWord VBAの世界では「ストーリー(Story)」と呼びます。

画面で選べるのは、せいぜい一つの部屋の中だけ。だから、ヘッダーの中にある文字を一括置換しようとしても、Selectionのままだとスルーされてしまうのです。

2. Wordの心臓部:「ストーリー」の階層構造を理解する

Wordの文書ファイルは、一枚の紙のペラペラしたキャンバスではありません。実態は、「StoryRanges(ストーリーの集まり)」というコレクション(コンテナ)の集合体です。

イメージとしては、巨大なビルの中にいくつもの独立した部屋(ストーリー)があるようなものです。

  • 本文ストーリー (`wdMainTextStory`)
  • ヘッダー・フッター用ストーリー (`wdPrimaryHeaderStory` など)
  • 脚注・文末脚注ストーリー (`wdFootnoteTextStory` など)
  • シェイプやテキストボックスの中身(これらはまた別の特殊な結びつきを持っています)

一括置換や文書全体のデータ抽出を完璧に行うには、「このビルの全フロア(全ストーリー)の部屋を巡回して、隅々まで掃除(置換・書式変更)して回る」という発想が必要になります。

3. 実践!全ストーリーを網羅して文字列を置換するマクロ

百聞は一見にしかず。それでは、文書内の本文だけでなく、ヘッダーやフッター、テキストボックスの中にある特定のキーワードをもれなく一挙に置換する、プロ仕様のコードをお見せします。

開発タブのVBE(Visual Basic Editor)を開き、標準モジュールに以下のコードを貼り付けてみてください。

Sub ReplaceAllStories()
Dim rngStory As Range
Dim shp As Shape
Dim targetStr As String
Dim replaceStr As String

‘ 置換する文字列の設定
targetStr = “旧会社名”
replaceStr = “新会社名”

‘ 画面描画を停止してマクロの実行速度を爆発的に上げる(超重要テクニック!)
Application.ScreenUpdating = False

‘ 1. 文書内のすべての「基本ストーリー」をループする
For Each rngStory in ActiveDocument.StoryRanges

‘ リンクされているヘッダー/フッター等の重複処理を防ぐためのエラーハンドリング
Do
‘ 各ストーリーのRangeに対して置換を実行
With rngStory.Find
.Text = targetStr
.Replacement.Text = replaceStr
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.Execute Replace:=wdReplaceAll
End With

‘ 連結された次のストーリー(例:セクションごとのヘッダーの続きなど)が存在する場合に移動
Set rngStory = rngStory.NextStoryRange
Loop Until rngStory Is Nothing

Next rngStory

‘ 2. 本文やヘッダーに配置された「テキストボックス・図形(Shape)」の中を走査する
For Each shp in ActiveDocument.Shapes
‘ テキストフレーム(文字が入る領域)を持っているか判定
If shp.TextFrame.HasText Then
With shp.TextFrame.TextRange.Find
.Text = targetStr
.Replacement.Text = replaceStr
.Forward = True
.Wrap = wdFindStop
.Execute Replace:=wdReplaceAll
End With
End If
Next shp

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

MsgBox “すべてのストーリー(本文・ヘッダー・テキストボックス)の置換が完了しました!”, vbInformation

End Sub

コードのここがポイント!

  • `Application.ScreenUpdating = False`

処理中の画面ちらつきを消し、実行速度を何倍にも跳ね上げるプロ必須のお作法です。

  • `ActiveDocument.StoryRanges`

これこそが今回の主役。文書内の主要なストーリーを順番に取得し、`For Each` で総なめにします。

  • `Shape` オブジェクトの罠

実は、ヘッダーや本文に挿入した「テキストボックス(Shape)」は、通常の `StoryRanges` の網から漏れることがあります。そのため、後半のループで `Shapes` を個別に叩き、テキストボックス内の文字列もしっかり網羅しているのが、このコードの最もスマートな部分です。

4. 陥りやすいエラーと知っておくべき極意

最後に、Word VBAを実務で使う上で絶対に知っておいてほしい「つまづきポイント」をいくつか共有しておきますね。

① 「Selection」と「Range」を混同しない

マクロの記録は `Selection` を使いますが、実務のコードでは `Range` オブジェクト を使いましょう。
`Range` は目に見えない「メモリ上のテキストの塊」です。画面を選択しないため、高速で安全、かつ予期せぬカーソル移動によるエラーが起きません。

② セクションが変わるとヘッダーが別物になる

Wordでは「ここから次の章」とセクション区切りを入れると、ヘッダーの「前とおなじ」というリンクが切れることがあります。
今回紹介した `NextStoryRange` を使ったループ構造は、こうした複雑に枝分かれしたヘッダー・フッターの連鎖も漏らさず捉えるための最強の構文です。

まとめ:ここをクリアすれば、Word VBAは怖くない!

お疲れ様でした!今回は少し踏み込んだ「ストーリーの階層構造」について解説しました。

  • Wordは「本文」だけでなく「ヘッダー」や「テキストボックス」という複数の部屋(ストーリー)でできている。
  • 一括処理をするなら、`Selection` ではなく `StoryRanges` と `Range.Find` を使いこなせ。
  • `ScreenUpdating = False` で爆速化させる。

この基本思想さえ腹に落ちれば、もうマクロの記録の呪縛から完全に解放されます。社内の誰もが面倒臭がる大量のドキュメント整形作業も、あなたが書いたたった数行のスマートなコードが一瞬で終わらせてくれるはずです。

ここをクリアできれば、Word VBAの基本はもうバッチリですよ!次の自動化チャレンジも、自信を持って楽しんでいきましょう。

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