【実務・中級編】【中級者向け】段落の「枠線」を、特定のキーワードが含まれる場合にのみ自動描画する強調表示ツール – Word VBA解析バイブル

スポンサーリンク

【Word VBA極意】「目立つ警告」を自動生成せよ:段落解析による動的書式設定のアーキテクチャ

Word VBAで「特定のキーワードが含まれる段落を枠線で囲む」という要件、一見すると簡単そうに見えるだろう。しかし、これを「なんとなく動くコード」で実装すれば、たちまちドキュメントの破壊や、数千ページ規模の文書での劇的なパフォーマンス低下を招く。

私はこれまで、数百の企業でマクロの再構築を行ってきた。その経験から断言する。Wordオブジェクトモデルへのアクセスは「コスト」であると意識せよ。

今日は、プロフェッショナルとして恥ずかしくない、堅牢で拡張性の高い「段落強調エンジン」の設計思想とコードを伝授する。

なぜ「愚直なループ」は死を招くのか

多くの初心者が陥る罠は、`For Each` ループの中で、毎回 `Selection` を動かしたり、`Paragraph.Range.Font` プロパティを個別に何度も叩くことだ。

1. Selectionの排除: `Selection` は画面描画を伴うため極めて低速だ。常に `Range` オブジェクトを直接操作せよ。
2. 画面更新の制御: `Application.ScreenUpdating` を制御しないのはエンジニアとして怠慢である。
3. オブジェクトのキャッシュ: 繰り返し参照するプロパティは変数に退避させる。これがメモリ管理の基本だ。

プロダクションコード:High-Performance Paragraph Highlighter

以下のコードは、単に動くだけではない。エラーハンドリングと処理効率を考慮した、実戦投入レベルの設計だ。

Option Explicit

”’

”’ 指定キーワードを含む段落に枠線を描画するメインルーチン
”’

Public Sub HighlightKeywordsByBorder()
Dim doc As Document
Dim para As Paragraph
Dim targetWords As Variant
Dim i As Long

‘ 処理対象のキーワードリスト
targetWords = Array(“警告”, “注意”, “重要”)

Set doc = ActiveDocument

‘ 画面更新停止:描画コストを抑え、処理速度を劇的に向上させる
Application.ScreenUpdating = False

On Error GoTo Cleanup

For Each para In doc.Paragraphs
‘ 空行や無意味な段落はスキップし、リソースを節約
If Len(Trim(para.Range.Text)) > 1 Then
For i = LBound(targetWords) To UBound(targetWords)
If InStr(para.Range.Text, targetWords(i)) > 0 Then
Call ApplyParagraphBorder(para)
Exit For ‘ 一致した時点で次へ
End If
Next i
End If
Next para

Cleanup:
Application.ScreenUpdating = True
If Err.Number <> 0 Then MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
End Sub

”’

”’ 段落の枠線を適用する抽象化レイヤー
”’

Private Sub ApplyParagraphBorder(ByRef para As Paragraph)
With para.Range.ParagraphFormat.Borders(wdBorderLeft)
.LineStyle = wdLineStyleSingle
.LineWidth = wdLineWidth050pt
.Color = wdColorRed
End With
‘ 四方を囲む場合は .Borders(wdBorderRight) 等を追記
‘ 重要なのは、プロパティを個別に設定すること
para.Range.ParagraphFormat.Borders.Enable = True
End Sub

アーキテクトの視点:堅牢性を高める3つのポイント

1. 範囲操作の分離(Separation of Concerns)

`ApplyParagraphBorder` を別プロシージャに切り出しているのは理由がある。将来、「枠線だけでなく、背景色も変えたい」「フォントを太字にしたい」という要件追加が来た際に、メインのループを汚さずに拡張するためだ。これが「保守性の高いコード」の正体である。

2. 画面更新の制御は必須

`Application.ScreenUpdating = False` を忘れると、Wordはループのたびにレイアウトを再計算する。数ページなら良いが、100ページを超えた瞬間、あなたのPCは「応答なし」の地獄を見ることになる。必ず `Cleanup` ラベルを用意し、エラー時でも必ず画面更新をONに戻す設計にしておくこと。

3. データ連携への布石

もしこれが「外部CSVからキーワードを読み込む」要件へと進化する場合、`targetWords = Array(…)` を `FileSystemObject` を使った外部読み込み関数に差し替えるだけで対応できる。ハードコーディングを避ける設計が、君を将来の残業から救うことになるだろう。

結論:コードは「書く」ものではなく「育てる」ものだ

今回提供したコードは、単なる機能実装ではない。君が今後Word VBAで大規模なツールを開発する際の「テンプレート」として機能するはずだ。

業務効率化とは、一度作って終わりではない。現場の運用に耐えうる「壊れない構造」を作ることこそが、我々エンジニアの真の仕事である。次のタスクでは、さらにスタイル(Style)オブジェクトと連動させ、ドキュメントの構造化まで踏み込んでみることを推奨する。

何か疑問があれば聞こう。技術的な壁は、突き破るために存在する。

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