【実務・中級編】【上級者向け】セルの幅や高さをミリ単位で厳密に制御するレイアウト自動化 – Word VBA解析バイブル

スポンサーリンク

Word VBAにおける「ミリ単位の精密レイアウト」の極意:ピクセルとポイントの呪縛から脱却せよ

Wordのテーブル操作を「なんとなく」の数値で行う時代は終わった。
印刷物や報告書において、1ミリのズレは「素人の仕事」を意味する。しかし、Wordの内部単位は「ポイント(pt)」だ。1インチ=72ポイントという厄介な仕様に振り回され、`Selection.Cells.Width`を調整しては崩れるレイアウトに溜息をつく日々は、今日で終わりにしよう。

今回は、真のプロフェッショナルが実務で採用する、「ミリ単位を絶対値として扱う」ための堅牢な設計手法を伝授する。

—

1. なぜ「ミリ指定」がWordで崩れるのか

Wordのレイアウトエンジンは、基本的に「可変的」である。
`PointsToMillimeters`や`MillimetersToPoints`という標準関数が存在するが、これら単体では不十分だ。なぜなら、「表のプロパティ」における「優先幅」や「自動調整」の設定が、VBAの指定を無効化するからである。

鉄則:レイアウトを制御するなら「自動調整」を殺せ

プログラムで精密に制御する場合、以下の設定を強制することがスタートラインだ。

  • `Table.AllowAutoFit = False`(自動調整をオフにする)
  • `Table.PreferredWidthType = wdPreferredWidthPoints`(幅をポイント単位の固定値にする)

これを怠れば、テキスト量やウィンドウ幅によって、あなたの苦労したレイアウトはものの数秒で崩壊する。

—

2. 【プロダクションコード】ミリ単位・精密テーブル生成器

このコードは、再利用性を極限まで高めたクラス設計の断片である。`Range`を引数に取ることで、ドキュメントのどこにでも精密な表を射出できる。

‘ ———————————————————
‘ 目的: 指定したミリ数で精密にテーブルを生成する
‘ ———————————————————
Public Sub CreatePrecisionTable(targetRange As Range, rows As Long, cols As Long)
Dim tbl As Table
Dim cellWidthPts As Single

‘ ミリをポイントに変換して格納
cellWidthPts = Application.MillimetersToPoints(30) ‘ 幅30mmで固定

‘ 表の追加
Set tbl = targetRange.Tables.Add(targetRange, rows, cols)

‘ 【重要】レイアウト崩壊を防ぐための防御的設定
With tbl
.AllowAutoFit = False ‘ 自動調整を無効化
.PreferredWidthType = wdPreferredWidthPoints
.PreferredWidth = cellWidthPts cols ‘ 全体の幅を固定

‘ セル幅の強制固定
Dim c As Cell
For Each c In .Range.Cells
c.Width = cellWidthPts
c.HeightRule = wdRowHeightExactly ‘ 高さを「固定値」に
c.Height = Application.MillimetersToPoints(10) ‘ 高さ10mmで固定
Next c

‘ 罫線の微調整(必要に応じて)
.Borders.Enable = True
End With
End Sub

—

3. 実務で「詰まない」ための3つの知見

① セル結合の罠を回避する

セルを結合する場合、`Range.Cells.Merge` を使うが、その直後に必ず 「結合後のセル幅の再計算」 を行うべきだ。結合後のセルは、親のテーブルが持つ優先幅の情報を引き継がないことがある。結合後に `Cell.Width` を明示的に再代入するコードを忘れてはならない。

② データ流し込み時の「テキスト溢れ」対策

データベースから文字列を流し込む際、文字数が想定を超えるとレイアウトが押し出される。

  • 対策: `Cell.FitText = True` を設定せよ。これにより、セル幅内に収まるよう文字が自動縮小される。あるいは、文字列の長さを判定し、`Font.Size` を動的に下げるロジックを前段に噛ませるのが、伝説的なエンジニアの流儀だ。

③ データベース連携におけるライフサイクルの管理

ExcelやSQL Serverからデータを取得する場合、`Recordset`や`Collection`を `For Each` で回すだろう。その際、`DoEvents`をループに組み込むことを強く勧める。Wordは巨大なテーブルを生成する際、一時的にフリーズしたような挙動を見せることがある。`DoEvents`はプロセスの応答性を維持し、ユーザーに「止まっていない」という安心感を与える。

—

4. 最後に:コードは「文書」である

私が部下に求めているのは、動くコードではない。「明日、仕様変更があっても一行の修正で済むコード」だ。

今回のミリ単位制御も同様だ。`MillimetersToPoints` を直接コードに埋め込むのではなく、定数として管理し、レイアウトの定義を一つの設定用モジュールに集約せよ。

Word VBAはレガシーと言われることもある。だが、APIの奥底にある「描画エンジン」を制御し、ミリ単位で支配下に置く快感を知れば、これほど強力な自動化武器はないことに気づくはずだ。

さあ、そのテーブルを、美しく、狂いのないものへと進化させたまえ。君のコードで、Wordを「ただの文書作成ツール」から「精密なデータ出力エンジン」へと変えるのだ。

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