【入門編】Word VBAにおける『Range.FormattedText』による書式付きテキストの高速コピー – Word VBA解析バイブル

スポンサーリンク

こんにちは! Word VBAの世界へようこそ。
マクロの記録ボタンを押して「なんだかよくわからないけれど動いた!」という感動を味わった次は、「もっと処理を速くしたい」「思い通りにテキストを操りたい」という壁にぶ当たるころですね。

大丈夫、ここをクリアすれば、あなたのWord VBAスキルは「初学者」の領域を抜け出し、一気にプロのアーキテクトへと近づきます。

今回は、Word VBAにおける最大のパフォーマンスハックの一つ『Range.FormattedText』について、魂を込めて解説します。クリップボードの呪縛から解放され、爆速で書式付きテキストをコピーする方法を一緒にマスターしましょう!

1. なぜ「マクロの記録」のコピー&ペーストは遅いのか?

Wordでテキストと書式を別の場所にコピーしたいとき、マクロの記録を使うと大体こんなコードが出力されますよね。

‘ 【アンチパターン】マクロの記録が吐き出す典型的なコード
Selection.Copy
Selection.GoTo What:=wdGoToBookmark, Name:=”TargetArea”
Selection.Paste

一見、問題なく動くように見えますが、プロの視点から言うと「絶対にやってはいけないアンチパターン」です。

なぜなら、このコードは目に見えないところで「Windowsのクリップボード」を経由しているからです。
人間が「コピー&ペースト」をする感覚と同じように、WordがわざわざOSのクリップボード領域にデータを書き込み、それを別の場所に貼り付けるという重い処理を裏で行っています。

さらに、`Selection`(選択範囲)オブジェクトを操作しているため、画面の描き替え(スクリーン・アップデート)が発生し、処理がカクカクと遅くなります。数十回、数百回とこの処理を繰り返すマクロを作ったら……想像するだけで恐ろしいですよね。

2. 救世主『FormattedText』オブジェクトとは?

そこで登場するのが、今回の主役である `FormattedText` プロパティ です。

Word VBAにおける `Range` オブジェクトは、文字だけでなく「フォント名」「サイズ」「太字」「段落書式」といったすべてのスタイル情報(書式)を内包しています。

`FormattedText` を使えば、クリップボードを一切経由せず、メモリ上で直接 `Range` 同士の書式付きテキストをコピー・代入できるのです。

図解イメージ

  • 従来のコピペ(Selection + クリップボード)

`[元Range]` ーー(OSのクリップボードを経由:重い!)ーー> `[先Range]`

  • FormattedText による直結コピー

`[元Range]` ===(メモリ上でダイレクトに転送:爆速!)===> `[先Range]`

画面の書き換えも起きないため、処理速度は文字通り「ケタ違い」になります。

3. 実践!『FormattedText』を使った爆速コード

百聞は一見にしかず。実際にコードを見てみましょう。
ここでは、文書の冒頭にあるタイトル部分(書式付き)を、文書の末尾にある特定の位置へ一瞬でコピーするコードを書きます。

Sub CopyFormattedTextFast()
Dim doc As Document
Set doc = ActiveDocument

Dim rngSource As Range
Dim rngTarget As Range

‘ 1. 画面の描画を停止してさらにパフォーマンスを極限まで上げる
Application.ScreenUpdating = False

On Error GoTo ErrorHandler
オブジェクトのライフサイクルやパフォーマンスを知り尽くした
‘ 2. コピー元(ソース)のRangeを設定(例:先頭の段落)
Set rngSource = doc.Paragraphs(1).Range

‘ 3. コピー先(ターゲット)のRangeを設定(例:末尾の段落の挿入ポイント)
Set rngTarget = doc.Content
rngTarget.Collapse wdCollapseEnd ‘ 文書の最後にカーソルを合わせるイメージ

‘ 4. 【核心】FormattedTextで書式ごとダイレクトに転送!
rngTarget.FormattedText = rngSource.FormattedText

MsgBox “書式付きテキストの転送が完了しました!”, vbInformation

ErrorHandler:
‘ 5. 処理が終わったら必ず画面描画を戻す
Application.ScreenUpdating = True

If Err.Number <> 0 Then
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End If
End Sub

コードのポイント解説

  • `Application.ScreenUpdating = False`: VBAの鉄則です。画面のチラつきを抑え、処理速度を劇的に向上させます。
  • `rngTarget.Collapse wdCollapseEnd`: ターゲットの範囲を「文書の末尾の一点(文字数ゼロの幅)」に折りたたんでいます。これがないと、文書全体のテキストがコピー元のテキストに上書きされて消えてしまうので注意してください。
  • `rngTarget.FormattedText = rngSource.FormattedText`: これが今回のキモです。`Selection`を使わず、見えないところで瞬時に「文字+書式」が流し込まれます。

4. 陥りやすい罠とエラー回避の知見

実務でこの `FormattedText` を使う際、中級者でもハマりがちな罠が一つだけあります。

それは、「コピー先の `Range` の寿命(ライフサイクル)」 です。

`FormattedText` で文字を流し込むと、代入された側の `Range` は「新しく挿入されたテキストを含む範囲」に自動的に拡張されます。もし同じ `Range` オブジェクトに対して連続で代入処理を行おうとすると、予期せぬ場所が書き換わったり、意図しないレイアウト崩れを起こす原因になります。

対策:
連続してテキストや書式を転送する場合は、毎回 `Range` の位置(StartとEnd)を正しく再定義するか、`Collapse` メソッドを使って挿入位置を常に末尾にコントロールする癖をつけましょう。

おわりに:ここをクリアすれば、Word VBAの基本はバッチリです!

お疲れ様でした!
今回は `Selection` から脱却し、メモリ上で効率よくオブジェクトを操作する `FormattedText` の世界をご紹介しました。

  • クリップボードを使わないから速い。
  • 画面を書き換えないからスマート。
  • 余計なオブジェクトを選択しないからバグに強い。

この3つを意識するだけで、あなたが書くWordマクロの質は見違えるほどプロフェッショナルなものになります。ぜひ、日々の業務自動化に取り入れて、その圧倒的なスピードを体感してみてください。

それでは、次回の極限の知見でお会いしましょう!

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