Word VBAの真髄:なぜ「プロパティの個別操作」は遅いのか?
こんにちは。Word VBAの世界へようこそ。
もしあなたが今、100ページあるドキュメントのフォントを一つずつ変えようとして、`.Font.Name = “Meiryo”` といったコードをループさせているなら――今日でその非効率なやり方は卒業しましょう。
Wordのオブジェクトモデルにおいて、個別のプロパティ(FontやParagraphFormat)を一つずつ書き換えるのは、「1枚ずつ手紙を書いて郵便局へ行く」ようなものです。処理が重いのは当然。なぜなら、そのたびにWordは画面の再描画やレイアウト計算を裏で走り回らせているからです。
今日は、プロが現場で使う「魔法の杖」、`FormattedText`プロパティを用いた高速一括処理の奥義を授けます。
—
1. なぜ `FormattedText` なのか?
Wordにおける「Range(範囲)」は、単なるテキストの箱ではありません。それは、書式情報という「重たい荷物」を背負った特別なオブジェクトです。
もしあなたが、ある見出しの書式を別の見出しにコピーしたいなら、わざわざフォントサイズ、色、太字設定……と指定する必要はありません。「書式そのもの(FormattedText)」を丸ごとコピーして貼り付ける。これが、Word VBAにおける「最速の美学」です。
基本的な考え方
- 悪い例: `Range.Font.Size = 14`, `Range.Font.Bold = True`, `Range.ParagraphFormat.Alignment = wdAlignParagraphCenter` …(遅い!)
- 良い例: `TargetRange.FormattedText = SourceRange.FormattedText` (一瞬!)
—
2. 実践:書式コピーの極意
それでは、実際に「テンプレートとなる書式」を別の場所に適用するコードを見てみましょう。この手法を覚えれば、どんな複雑なドキュメントでも瞬時にフォーマットを統一できます。
Sub ApplyFastFormat()
‘ Wordのレイアウト計算を止めて爆速化するおまじない
Application.ScreenUpdating = False
Dim doc As Document
Set doc = ActiveDocument
‘ 1. 「お手本」となる範囲を定義
Dim sourceRange As Range
Set sourceRange = doc.Paragraphs(1).Range ‘ 1段落目を「書式の見本」とする
‘ 2. 「適用先」となる範囲を定義(例:2段落目から末尾まで)
Dim targetRange As Range
Set targetRange = doc.Range(doc.Paragraphs(2).Range.Start, doc.Content.End)
‘ 3. 【奥義】FormattedTextで一括転送
‘ これだけで、フォント、段落、タブ、箇条書き設定まで全てコピーされます
targetRange.FormattedText = sourceRange.FormattedText
‘ 画面の再描画を元に戻す
Application.ScreenUpdating = True
MsgBox “高速書式適用が完了しました!”
End Sub
コードの解説
- `Application.ScreenUpdating = False`: これを忘れるとWordは処理のたびに画面を更新しようとします。大規模処理の鉄則です。
- `FormattedText`: これはRangeオブジェクトの「書式を含んだ全データ」を保持しています。これを代入先にぶつけることで、Wordは内部的な書式情報を一括で書き換えます。個別にプロパティを叩くより、圧倒的に負荷が低いです。
—
3. 陥りやすい罠:ここだけは注意!
初学者がよくやるミスが、「対象のRangeとコピー元のRangeのサイズ」に関する勘違いです。
- 罠1:Rangeの範囲が狭すぎる
`FormattedText`は、コピー元の「段落記号」まで含んでコピーします。もしコピー先に段落記号が含まれていない場合、意図しない場所で改行が入ったり、逆に詰められたりすることがあります。
- 対策: `Range`を定義する際は、必ず `Paragraphs(n).Range` のように段落単位で捉える癖をつけましょう。
- 罠2:オブジェクトの解放を忘れる
マクロが終了しても、メモリ上にRangeオブジェクトが残ることがあります。簡単なマクロなら問題ありませんが、数千回ループさせるような処理では `Set targetRange = Nothing` を明示的に行うのが、プロのたしなみです。
—
まとめ:ここをクリアすれば「脱・初心者」
今回学んだ `FormattedText` による一括処理は、Word VBAにおける「最適化」の第一歩です。
1. 個別のプロパティを操作しない(箱ごと動かす)
2. ScreenUpdatingを制御する(Wordに余計な仕事をさせない)
3. Rangeオブジェクトの範囲を正しく捉える
これさえ守れば、あなたのマクロは驚くほど速くなり、Wordという巨大なアプリケーションを自由自在に操れるようになります。
「マクロの記録」で生成された冗長なコードを捨てて、この美しいオブジェクトモデルの世界へようこそ。次は、さらに一歩進んだ「検索と置換」を組み合わせた動的な書式制御の世界でお会いしましょう。
何か詰まったら、いつでも聞いてください。応援しています!
