こんにちは!Word VBAの世界へようこそ。
「マクロの記録」ボタンを押してコードを覗いてみたものの、生成された呪文のようなコードの多さに圧倒されて挫折しそうになっていませんか?
大丈夫、ここをクリアすればWord VBAの基本はバッチリですよ。今日は、多くの人がつまずく「文書のレイアウト制御」、特にセクションごとに段落の間隔をダイナミックに自動調整するテクニックを一緒にマスターしていきましょう。
実務で「最初のページは表紙だから詰めたい」「第1章の本文はゆったり読ませたい」「付録のデータ部分は隙間をなくしたい」といった要望に直面したことはありませんか?これを手動でやっていたら、ページ数が変わるたびに発狂してしまいますよね。
Word VBAの本質を知り尽くしたアーキテクトの視点から、美しく、かつ安全にこれを自動化する極意を伝授します!
—
なぜ「セクションごとの段落調整」は難しいのか?
Wordのドキュメントは、ただの「文字の羅列」ではありません。実は、「ストーリー(本文やヘッダーなど)」の中に「セクション」という部屋があり、その部屋の中に「段落」という家具が並んでいるという階層構造(オブジェクトモデル)をしています。
初心者が陥りがちな罠がこれです。
- 「文書全体の段落を一律に変えるマクロ」は書けるけど、セクションごとに変えられない。
- `Selection`(選択範囲)を使ってカーソルを移動させながら色々と変えようとして、処理が重くなったりエラーで止まったりする。
プロのエンジニアは `Selection` を使いません。目に見えないバックグラウンドで高速かつ正確にデータを操る `Range`(レンジ) や コレクションのループ を使います。
—
押さえておくべきWord VBAの基本設計
今回のコードを書くにあたり、頭に入れておくべき重要ファクトが3つあります。
1. セクションの境界を知る
Wordの各セクションには `Range` プロパティがあります。つまり、「セクション1の始まりから終わりまで」という範囲をピンポイントで取得できるのです。
2. 段落の間隔はプロパティで一発制御
段落の上下の隙間は、それぞれ `SpaceBefore`(段落前)と `SpaceAfter`(段落後)というプロパティで管理されています。単位は「pt(ポイント)」です。
3. セクションごとのルールをどう定義するか
今回は分かりやすく、「奇数セクションはゆったり(間隔広め)」「偶数セクションはコンパクト(間隔狭め)」というルールをコードに組み込んでみましょう。
—
実践!セクション自動調整マクロの全コード
それでは、開発の現場でそのままコピペして使える実用的なコードを公開します。VBAエディタ(Alt + F11)を開き、標準モジュールに貼り付けて実行してみてください。
Sub AdjustParagraphSpacingBySection()
‘ 変数の宣言(型を明示するのがプロの作法です)
Dim sec As Section
Dim para As Paragraph
Dim targetRange As Range
Dim changedCount As Long
‘ 画面描画をストップして処理速度を爆発的に上げる(お約束のテクニック)
Application.ScreenUpdating = False
changedCount = 0
‘ 文書内のすべてのセクションを順番にループする
For Each sec In ActiveDocument.Sections
‘ セクションの範囲(Range)を取得
Set targetRange = sec.Range
‘ デバッグ用:現在のセクション番号を確認(イミディエイトウインドウに出力)
Debug.Print “処理中: セクション ” & sec.Index
‘ セクション内にある段落をすべて走査する
For Each para In targetRange.Paragraphs
‘ 【ロジック】セクション番号が奇数か偶数かで間隔を変える
If sec.Index Mod 2 <> 0 Then
‘ 奇数セクション:ゆったりモード(段落前 6pt / 段落後 12pt)
para.SpaceBefore = 6
para.SpaceAfter = 12
Else
‘ 偶数セクション:コンパクトモード(段落前 0pt / 段落後 3pt)
para.SpaceBefore = 0
para.SpaceAfter = 3
End If
changedCount = changedCount + 1
Next para
Next sec
‘ 画面描画を再開
Application.ScreenUpdating = True
‘ 完了メッセージ
MsgBox “処理が完了しました!” & vbCrLf & _
“調整した段落の総数: ” & changedCount & ” 個”, vbInformation, “自動レイアウト調整”
End Sub
—
ジックリとコードの重要ポイントを解説しましょう。
1. `Application.ScreenUpdating = False` の魔力
Word VBAで何百、何千という段落をループさせるとき、画面が1行ごとにパチパチ切り替わると、処理がものすごく遅くなります。最初に画面描画を止め、最後に `True` に戻す。これだけで実行速度が数倍〜数十倍変わります。プログラミングの基本にして最大の極意です。
2. `sec.Range.Paragraphs` のスマートさ
「セクションの中にある段落」を特定するために、セクションの `Range` オブジェクトから直接段落コレクションを取得しています。これによって、文書全体の余計な部分を巻き込まず、意図したセクション内だけを正確に料理できます。
3. Mod演算子による条件分岐
`sec.Index Mod 2` は、セクション番号を2で割った余りを求めています。これを使うことで、「奇数番目か、偶数番目か」をスマートに判定できます。実務ではここに `Select Case sec.Index` などを使って、「セクション1は表紙だから別設定、セクション2以降は本文…」といったカスタendar(条件分岐)を組み込むと、さらに実用的になりますよ。
—
陥りやすいエラーと回避の知見
最後に、現場でよくあるトラブルと回避策をシェアします。
- エラー:「インデックスが有効範囲にありません」
→ セクションが1つしかない文書で、存在しないセクションを操作しようとした時によく起きます。`ActiveDocument.Sections.Count` でセクション数を確認するガード節を入れましょう。
- 「マクロを実行したのに見た目が変わらない…」
→ すでに「スタイル」で段落間隔がガチガチに固定されている場合、直接プロパティ(`SpaceAfter`など)を変更しても上書きされないことがあります。その場合は、段落のスタイルそのものを書き換えるか、直接書式(Direct Formatting)として強制適用するロジックが必要になります。
—
まとめ
いかがでしょうか?
「セクションごとに段落の間隔を自動制御する」という一見難しそうなテーマも、オブジェクトの階層構造(`ActiveDocument -> Sections -> Paragraphs`)を理解してしまえば、たった数十行の美しいコードで実現できてしまいます。
`Selection` に頼らず、裏側で `Range` をスマートに操る感覚がつかめれば、あなたのWord VBAスキルは間違いなく「初級者」から「中級者(プロの入り口)」へとステップアップしています。
ぜひ、日々のドキュメント作成業務でこのコードを試して、自動化の爽快感を味わってみてくださいね。それでは、次回の極限知見でお会いしましょう!
