こんにちは! Word VBAの世界へようこそ。
マクロの記録ボタンを押してコードを眺めてみたものの、生成された大量の呪文のようなコードに圧倒されていませんか?「なんだか難しそう…」と挫折しそうになっているあなた、ご安心ください。
今回は、実務で絶対に直面する「箇条書きのインデント崩れ」という悩ましい問題を通じて、Word VBAの本質を優しく、そして深く学んでいきましょう。ここをクリアすれば、あなたももう「マクロの記録頼み」の初心者ではありません。一歩進んだ自動化エンジニアへの扉を開きませんか?
—
なぜ、Wordの箇条書きはレイアウトが崩れるのか?
企画書やマニュアルを作っていて、こんなイライラを経験したことはありませんか?
- 「10.」や「11.」のように桁数が増えた途端、数字と本文の間がパカッと空いてしまう。
- 箇条書きの階層が深くなると、行頭がガタガタになってカッコ悪い。
Wordには「ぶら下げインデント」という素晴らしい機能があり、これを適切に設定すれば美しいレイアウトが保てます。しかし、項目の文字数や桁数に合わせて手動でインデントを調整するのは、気が遠くなるような作業です。
「だったら、Wordくんに自動で文字数を数えさせて、最適なインデント幅を計算させればいいじゃないか!」
これが今回挑むテーマです。プログラミングの醍醐味である「面倒な計算はコンピュータに丸投げする」を、Word VBAで実現してみましょう。
—
まず押さえたい!Word VBAにおける「段落(Paragraph)」の正体
コードを書く前に、Word VBAの心臓部である「オブジェクト階層」の基本を押さえましょう。Wordの世界は、以下のようなロシア人形(マトリョーシカ)構造になっています。
Application(Wordアプリ)
└─ Document(文書)
└─ Paragraphs(段落の集まり)
└─ Paragraph(個別の段落)
└─ Range(文字そのもの)
私たちが操作したい「インデント」は、この中の `Paragraph` オブジェクト が持っているプロパティ(属性)です。
特に今回重要なのが、以下の2つのプロパティです。
1. `LeftIndent`(左インデント): 段落全体の左からの距離
2. `FirstLineIndent`(1行目のインデント): 段落の1行目だけを動かす距離(ぶら下げの場合はマイナス値を設定します)
—
【実践】項目数と文字数に応じてインデントを自動計算するマクロ
それでは、実際のコードを見てみましょう。
今回は、選択している段落、または文書全体の中から「箇条書き(または番号付きリスト)」の段落を自動で判定し、数字の桁数(文字数)に応じてぶら下げインデントの幅をピタリと美しく自動調整するプロシージャです。
開発タブの「Visual Basic」を開き、標準モジュールに以下のコードを貼り付けてみてください。
Sub AutoAdjustHangingIndent()
‘ =========================================================================
‘ 目的:箇条書きや番号付きリストの桁数に合わせて、ぶら下げインデントを自動計算・調整する
‘ 対象:選択中の段落(選択がない場合は文書全体)
‘ =========================================================================
Dim rngTarget As Range
Dim para As Paragraph
Dim listString As String
Dim charCount As Long
‘ 1. 処理対象のレンジを決定(選択範囲か、ドキュメント全体か)
If Selection.Type = wdSelectionIP Then
Set rngTarget = ActiveDocument.Content
Else
Set rngTarget = Selection.Range
End If
‘ 2. 対象範囲内の段落をひとつずつスキャンする(イテレーション)
For Each para In rngTarget.Paragraphs
‘ リスト書式(箇条書き・段落番号)が設定されている段落かチェック
‘ ListStringプロパティは、自動付与されている「1.」や「・」などの文字列を返します
If para.Range.ListFormat.ListType <> wdListNoNumbering Then
‘ リストマークの実際の文字列を取得(例: “10.” や “(1)” など)
listString = para.Range.ListFormat.ListString
‘ リストマークの文字数をカウント
charCount = Len(listString)
‘ — 【ここがエンジニアの知見ポイント!】 —
‘ 文字数(桁数)に応じて、最適なぶら下げインデント幅を動的に計算します。
‘ 標準フォント(例: 10.5pt)の場合、1文字あたりの幅は約10.5ポイント。
‘ 桁数が増えても綺麗に収まるよう、余白を含めて動的に調整します。
With para
‘ 左インデントは、文字数 × 基準幅(ここでは約12pt換算=1文字分強)に設定
.LeftIndent = Application.CentimetersToPoints(0.7) (charCount \ 2 + 1)
‘ 1行目をマイナスに引き戻すことで「ぶら下げインデント」を作る
.FirstLineIndent = -.LeftIndent
End With
End If
Next para
‘ 3. 完了メッセージ
MsgBox “インデントの自動調整が完了しました!”, vbInformation, “処理成功”
End Sub
—
コードの注目ポイントをやさしく解説
初心者の方でも「どこがどう動いているのか」がイメージできるように、重要なポイントを3つに絞って解説します。
1. 賢い処理対象の切り替え (`Selection.Type`)
> `If Selection.Type = wdSelectionIP Then …`
ユーザーがテキストを「選択」しているときはその部分だけを処理し、何も選択していない(カーソルが点滅しているだけ=インсерションポイント)ときは文書全体を対象にする、という実用的な配慮を組み込んでいます。こういう「かゆいところに手が届く」配慮が、優れたマクロの条件です。
2. Wordの内部エンジンを覗き見る (`ListFormat.ListString`)
> `listString = para.Range.ListFormat.ListString`
ここがこのコードの最もスマートな部分です。Wordが自動で振っている「1.」や「(1)」「イ.」といった文字を、VBAの力で直接取得しています。これにより、「今、何文字分の幅が必要か」をプログラムが正確に把握できるようになります。
3. 単位変換の魔法 (`CentimetersToPoints`)
> `.LeftIndent = Application.CentimetersToPoints(0.7) …`
VBAの内部で使われる数値の単位は「ポイント(Point)」という、WebやDTPの世界の単位です(1インチ=72ポイント)。人間には直感しにくいため、`CentimetersToPoints`メソッドを使って「0.7センチ」のように直感的な指定をしています。この手法を覚えておくと、レイアウト崩れを防ぐ頑健なコードが書けるようになります。
—
陥りやすいエラーと、その対策
VBAを書き始めると、必ずいくつかの「壁」にぶつかります。よくあるエラーと回避策をあらかじめ知っておきましょう。
- エラー「実行時エラー 424: オブジェクトが必要です」
- 原因: 変数の宣言漏れ(`Dim` 忘れ)や、オブジェクトのセット時に `Set` キーワードを書き忘れたときによく起こります。
- 対策: モジュールの最上部に必ず `Option Explicit`(変数の宣言を強制する)を書き、文法ミスの芽を摘む習慣をつけましょう。
- 「処理が途中で止まってしまう / 固まる」
- 原因: 非常に大きな文書(数百ページのドキュメント)を処理するとき、すべての段落を舐めるループ処理はWordに負荷をかけます。
- 対策: 今回のように `For Each` を使う場合は、処理対象が「リスト書式を持つ段落」に限定されているため無駄な負荷をスキップできますが、さらに高速化したい場合は画面の描画を一時停止する `Application.ScreenUpdating = False` を冒頭に入れると効果的です。
—
ここをクリアすれば、Word VBAの基本はバッチリですよ!
お疲れ様でした!
今回は「段落」というオブジェクトを相手に、文字数をフックにしてプロパティを動的に書き換えるという、中級者へのステップアップにふさわしいロジックを解説しました。
「マクロの記録」では絶対に作れない、『状況を判断して自ら計算し、美しく整えるコード』。これを自分の手で動かせたなら、あなたのWord VBAスキルは確実に次のステージへと進んでいます。
業務効率化の武器を手に入れた自信を持って、ぜひ明日の仕事のドキュメント作成にこのコードを役立ててみてください。
それでは、また次の知見でお会いしましょう!
