【Word VBA】スパゲッティコードからの脱却:クラスモジュールで構築する「書式設定エンジン」の設計思想
Word VBAのプロジェクトが巨大化する際、最も開発者を苦しめるのは「あとから修正が効かない、散らばった `.Font.Size = 12` の嵐」だ。
「見出しは14pt、太字、青色。ただし特定の条件では赤……」といったロジックが標準モジュールに直書きされている現場を見ると、私は技術的負債の増殖を感じて鳥肌が立つ。Wordの書式設定は、プロパティを個別に叩くべきではない。 書式という「状態」を抽象化し、エンジン化する。これが、大規模文書生成を安定して運用するための唯一の解だ。
今回は、段落書式をオブジェクトとしてカプセル化し、堅牢なドキュメント生成を実現する「Formatterエンジン」の構築手法を伝授する。
—
1. なぜ「個別のプロパティ操作」が死を招くのか
多くの初心者は、以下のようなコードを量産する。
‘ 悪例:保守性ゼロのハードコーディング
With Selection.ParagraphFormat
.LineSpacingRule = wdLineSpace1.5
.SpaceAfter = 12
End With
With Selection.Font
.Name = “Meiryo UI”
.Size = 12
End With
この書き方の罪は、「書式定義」と「適用ロジック」が密結合していることにある。要件変更が起きたとき、あなたは数百行のコードを横断して置換を行うのか? それはエンジニアの仕事ではない。ただの作業だ。
—
2. 書式をオブジェクト化する:クラスモジュールの設計
書式を一つの「設定オブジェクト」として扱えば、再利用性は劇的に向上する。まずは `StyleFormatter` クラスを作成しよう。
クラスモジュール:`StyleFormatter`
Option Explicit
‘ 内部保持用のプロパティ
Private pFontSize As Single
Private pFontName As String
Private pSpaceAfter As Single
‘ プロパティの初期化と設定
Public Sub SetHeadingStyle()
pFontSize = 14
pFontName = “游ゴシック”
pSpaceAfter = 12
End Sub
‘ 段落オブジェクトを受け取り、一括適用するメソッド
Public Sub ApplyTo(ByRef targetPara As Paragraph)
With targetPara
.Format.SpaceAfter = pSpaceAfter
With .Range.Font
.Name = pFontName
.Size = pFontSize
End With
End With
End Sub
—
3. 実践:エンジンとしての運用
クラス化したことで、書式設定は「定義」と「実行」に分離された。これにより、データベース(ExcelやJSON)から設定を読み込み、動的にスタイルを生成することも可能になる。
標準モジュールでの実行例
Sub ApplyDocumentStyles()
Dim formatter As New StyleFormatter
Dim para As Paragraph
‘ 書式エンジンを初期化
formatter.SetHeadingStyle
‘ ドキュメント全体、あるいは特定の範囲に適用
For Each para In ActiveDocument.Paragraphs
‘ 条件分岐をここで行うことで、ロジックを一元管理できる
If para.Style = wdStyleHeading1 Then
formatter.ApplyTo para
End If
Next para
End Sub
—
4. 堅牢な設計のための「鉄則」
現場のリーダーとして、これだけは守ってほしい。
- Rangeオブジェクトの再利用を避ける:
Word VBAにおいて、`Selection`は極めて低速でバグの温床だ。必ず `Paragraph` や `Range` オブジェクトを直接操作せよ。
- イベントの無効化(パフォーマンスの要):
大量の書式変更を行う際は、`Application.ScreenUpdating = False` を忘れてはならない。これを怠ると、Wordは描画更新のたびにリソースを食いつぶし、数千ページの文書ではフリーズする。
- 構造化データの活用:
書式情報をハードコーディングするな。JSONやExcelの構成定義を読み込み、`Formatter`クラスのプロパティに流し込む。これにより、「コードを変えずにドキュメント構成を変える」ことが可能になる。
最後に:エンジニアとしての矜持
VBAはレガシーな言語だと言われる。だが、使い手の設計次第で、それは堅牢なエンタープライズツールへと化ける。
今回紹介した「クラス化」という一手間は、書いている瞬間は面倒に感じるかもしれない。だが、「明日、仕様が全部変わったとしても、一行の修正で完結できる」という状態を作ることこそが、真のエンジニアの価値だ。
あなたのコードが、ただ動くものではなく、誰が触っても壊れない「資産」になることを期待している。
