Word VBAの「表」を支配せよ:改ページ制御でレイアウト崩れを根絶する設計論
業務自動化の現場において、Wordの表は最も「予測不可能」な挙動を示すオブジェクトだ。特に、データソースから動的に行を流し込む際、改ページ位置を制御できずにレイアウトが崩れ、PDF出力でクライアントに恥を晒す――そんな経験はないだろうか。
多くの初心者は、Wordの「行の途中で改ページする」設定をUIから弄るだけで満足する。しかし、プロのエンジニアが目指すべきは、「コードで改ページ位置を確定的に支配する」ロジックだ。
今日は、Word VBAを用いて、ページ跨ぎの制御を堅牢に実装するための極意を伝授する。
—
1. なぜ「自動改ページ」に頼ってはいけないのか
Wordのエンジンは、最後の一瞬までレイアウトを再計算する。動的に行を挿入する場合、`Range`オブジェクトの座標計算は極めて不安定だ。
特に、以下の条件下ではロジックが破綻する。
- 行の高さが可変: セル内のテキスト量によって行高が変わると、ページ末尾の計算が狂う。
- テーブルプロパティの干渉: 「行の途中で改ページする」設定がオンのまま、中途半端な位置でページが切れる。
私たちは、「物理的な改ページ(Manual Page Break)」をコードで挿入するタイミングを、データ行数に基づいて計算しなければならない。
—
2. 堅牢な実装のためのアーキテクチャ
単に「何行目で改ページ」と決め打つのは悪手だ。実務では「ヘッダー行の高さ」や「フォントサイズ」が変更される可能性がある。
設計の肝は、「データ行を流し込む際、行数カウンターを監視し、閾値を超えた瞬間に `Range.InsertBreak` を発行する」ことにある。
プロダクションコード:改ページ制御付きテーブル生成
以下のコードは、単なるコピペ用コードではない。テーブルのライフサイクルを管理するためのテンプレートだ。
‘ @description: 指定行数で強制改ページするテーブル構築エンジン
‘ @param targetDoc: 操作対象のドキュメント
‘ @param dataArray: 流し込む2次元配列データ
Public Sub GenerateControlledTable(ByRef targetDoc As Document, ByRef dataArray As Variant)
Dim tbl As Table
Dim i As Long, j As Long
Dim maxRowsPerPage As Integer: maxRowsPerPage = 20 ‘ 物理的な限界行数
Dim currentRowCount As Integer: currentRowCount = 0
‘ 1. 表の初期化
Set tbl = targetDoc.Tables.Add(Range:=targetDoc.Range(0, 0), NumRows:=1, NumColumns:=3)
‘ 2. データ流し込みと行制御
For i = LBound(dataArray, 1) To UBound(dataArray, 1)
‘ ページ跨ぎの判定ロジック
If currentRowCount >= maxRowsPerPage Then
‘ 現在位置に手動改ページを挿入
tbl.Range.Characters.Last.InsertBreak Type:=wdPageBreak
currentRowCount = 0 ‘ カウンターリセット
End If
‘ 行追加とデータセット
If i > 1 Then tbl.Rows.Add
For j = 1 To 3
tbl.Cell(i, j).Range.Text = dataArray(i, j)
Next j
currentRowCount = currentRowCount + 1
Next i
‘ 3. 後処理:不要な装飾の排除
tbl.Rows(1).HeadingFormat = wdToggle ‘ ヘッダー行を次ページに引き継ぐ
End Sub
—
3. 実務で「詰まない」ための3つの鉄則
① `HeadingFormat` を制せよ
ページが跨ぐ際、見出し行が消えてしまってはドキュメントとして機能しない。必ず `Rows(1).HeadingFormat = wdToggle` を設定すること。これにより、Wordは改ページ時に自動的にヘッダーを複製してくれる。
② `Range` オブジェクトの再定義に注意せよ
`Range` を操作した直後、Wordは内部的にオブジェクトの参照を更新する。特に `InsertBreak` を実行した後は、直前の `Range` が無効になる可能性があるため、必ず変数に `Set` し直す習慣をつけろ。
③ データベース連携時の落とし穴
外部DBから取得したデータをそのまま流し込むのは危険だ。「文字数過多によるセル崩れ」が発生した瞬間、行高が跳ね上がり、計算した改ページ位置がズレる。
- 対策: セルの `AutoFitBehavior` を `wdAutoFitFixed` に固定し、文字数制限(Truncate)を設けること。レイアウトの崩れは、往々にしてデータの内容から始まる。
—
結論:エンジニアとしての矜持
VBAは「汚いコードを書きやすい」言語だ。しかし、Wordという巨大で曖昧なレンダリングエンジンを制御する以上、我々は数学者のような緻密さでDOM(Document Object Model)を扱わねばならない。
「動けばいい」という考えは捨てろ。「なぜこの行数で改ページされるのか」を理論的に説明できるコードこそが、真に保守可能な資産となる。
次にあなたが構築するツールが、誰かの業務時間を劇的に短縮し、かつ、数年後もメンテナンス可能なコードであることを期待している。健闘を祈る。
