【入門編】【中級者向け】表の列幅をミリ単位で厳密に制御し、印刷時のレイアウト崩れを防ぐ – Word VBA解析バイブル

スポンサーリンク
スポンサーリンク

【極限の知見】Word VBAで表のレイアウトを「ミリ単位」で完全支配する —— 印刷崩れを根絶する設計思想

「マクロで表を作ったときは綺麗だったのに、いざ印刷すると列の幅がズレている……」
「特定の列をもう少し広くしたいだけなのに、なぜか表全体がページからはみ出してしまう」

もしあなたが今、そんな現象に頭を抱えているとしたら、おめでとうございます。あなたは今、「Word VBAの基礎」から「プロフェッショナルな自動化」へと脱皮する境界線に立っています。

こんにちは。今日は、マクロの記録から一歩踏み出し、業務システムとしての「堅牢なWord文書」を構築するための、極めて重要なテクニックをお伝えします。テーマは「表の列幅をミリ単位で厳密に制御する」ことです。

1. なぜ、あなたの表は「崩れる」のか?

結論から言いましょう。原因は、「人間が使う単位」と「Wordが理解する単位」の乖離(かいり)にあります。

私たちは日常的に「幅30mm」や「5cm」という単位を使います。しかし、Wordの内部エンジン(オブジェクトモデル)が列幅を管理する際に採用しているのは、「ポイント(Point)」という単位です。

> [知見] ポイントとは?
> 1インチ(25.4mm)を72等分した単位です。
> つまり、1mmは約2.83ポイントになります。

この「2.83」という中途半端な数字を、感覚でコードに書き込んでいませんか?
`Columns(1).Width = 85` と書いたとき、それは85mmではなく、わずか30mm程度の幅しか確保できていません。この僅かな誤差が、セルのテキスト溢れや、ページ端でのレイアウト崩れを引き起こす「真犯人」なのです。

2. 武器を手に入れる:単位変換の魔法

プロフェッショナルは、決して「勘」で数値を入力しません。Wordが用意してくれている変換関数を使い、「設計図(mm)」を「実行命令(Points)」に変換します。

ここで登場するのが、以下の2つのメソッドです。

  • `MillimetersToPoints(mm)`: ミリメートルをポイントに変換する(列幅を指定するときに使う)
  • `PointsToMillimeters(pt)`: ポイントをミリメートルに変換する(現在の幅を確認するときに使う)

これらを使いこなすことで、あなたのコードは「人間が読める論理的な設計」へと昇華されます。

3. 実践:レイアウト崩れを許さない「完璧な表生成」コード

それでは、実際に「列幅をミリ単位で指定して、データが流し込まれても崩れない表」を作成するコードを見てみましょう。

単に幅を指定するだけでは不十分です。Wordの「自動調整機能(AutoFit)」という、良かれと思ってレイアウトを壊す「お節介機能」を封じ込める工程が不可欠です。

Sub CreateStrictLayoutTable()
    Dim doc As Document
    Dim tbl As Table
    Dim targetWidths As Variant
    Dim i As Integer
    Dim totalWidthMM As Single
    Dim pageWidthMM As Single
    
    Set doc = ActiveDocument
    
    ' --- 1. 設計図の定義(ミリ単位で直感的に指定) ---
    ' 例:1列目は30mm、2列目は100mm、3列目は40mm
    targetWidths = Array(30, 100, 40)
    
    ' ページ全体の有効幅を計算(ここでは仮にA4横向きを想定して計算する考え方)
    ' ※実際には doc.PageSetup を参照するのがベストです
    pageWidthMM = 190 ' 余白を除いた有効幅(例)

    ' --- 2. 表の生成 ---
    ' 文末に3行3列の表を作成
    Set tbl = doc.Tables.Add(Range:=doc.Content, NumRows:=3, NumColumns:=3)
    
    With tbl
        ' 【重要】自動調整機能をオフにする
        ' これをやらないと、後から文字を入れた瞬間に幅が勝手に変わります
        .AllowAutoFit = False
        
        ' 表全体のレイアウト設定を「固定」にする
        .AutoFitBehavior (wdAutoFitFixed)
        
        ' --- 3. 列幅の厳密な適用 ---
        For i = 1 To .Columns.Count
            ' 配列から設計上の幅を取得(VBAの配列は0始まりなので i-1)
            ' MillimetersToPoints を使い、設計図(mm)をWordの言語(pt)に翻訳する
            .Columns(i).Width = MillimetersToPoints(targetWidths(i - 1))
        Next i
        
        ' --- 4. データの流し込み(テスト) ---
        .Cell(1, 1).Range.Text = "項目名"
        .Cell(1, 2).Range.Text = "詳細説明(長いテキストが入っても崩れません)"
        .Cell(1, 3).Range.Text = "備考"
        
        .Cell(2, 1).Range.Text = "価格"
        .Cell(2, 2).Range.Text = "¥1,200"
        .Cell(2, 3).Range.Text = "税込"
    End With

    MsgBox "設計通りの表を作成しました。", vbInformation, "完了"
End Sub

コードの核心:なぜこの手順なのか?

1. `AllowAutoFit = False`:
これが最大の防波堤です。Wordは「セルの中に長い単語が入ったら、列を広げよう」と気を利かせますが、業務文書においてはそれが「レイアウト崩れ」になります。このプロパティを`False`にすることで、Wordの独断を禁止します。
2. `AutoFitBehavior (wdAutoFitFixed)`:
表の挙動を「コンテンツに合わせる」から「固定幅」へと強制的に切り替えます。
3. `MillimetersToPoints` の活用:
コードを読んだ人が「あ、この列は30mmなんだな」と即座に理解できる。これが保守性の高いコードの条件です。

4. 陥りやすい「罠」と回避策

エンジニアとして、あえて警告しておきます。以下の2点には注意してください。

罠①:セルの余白(Cell Margins)

列幅を30mmに設定しても、セルの中に「左余白 2.5mm、右余白 2.5mm」という設定があると、実際にテキストが書ける幅は25mmになります。
対策: 表全体の余白を制御したい場合は、`tbl.TopPadding` や `tbl.LeftPadding` もミリ単位(変換後)で明示的に指定しましょう。

罠②:合計幅のオーバーフロー

指定した列幅の合計が、ページの有効幅(余白を除いた幅)を超えてしまうと、Wordは強制的に列幅を縮小し、あなたの設計を無視します。
対策: `doc.PageSetup.UsableWidth`(※プロパティ名は環境により異なりますが、有効幅を取得するロジック)を計算に組み込み、合計幅がページ内に収まっているかを事前にチェックするバリデーションを実装するのが、真のアーキテクトの仕事です。

最後に:ここをクリアすれば、あなたはもう初心者ではない

「マクロの記録」で生成されるコードは、常に「その時、その瞬間の状態」を記録するだけの、断片的なものです。
しかし、今回のように「単位を意識し」「オブジェクトの挙動(AutoFit)を制御し」「設計思想を持って数値を扱う」ことができれば、あなたの書くマクロは、どんな環境でも、どんなデータが来ても、寸分違わぬ美しさを保つ「ツール」へと進化します。

一歩ずつ、確実に。
この「単位の制御」をマスターしたあなたは、もうWord VBAの荒波を乗りこなす準備ができています。

さあ、次の自動化へ向かいましょう!

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