【Word VBA】固定値インデントは卒業!コンテンツに追従する「動的ぶら下げインデント」の奥義
こんにちは。現場でドキュメントの自動化と戦い続けているエンジニアです。
Wordで資料を作っていて、「箇条書きの改行位置がガタガタで見にくい」「項目によってインデントを微調整するのが面倒」と悩んだことはありませんか?
マクロの記録で生成される固定値のインデント設定は、文字数が変わるたびに崩壊する「脆い設計」の典型です。
今回は、「文字数や項目数に応じて、インデント量をWordに計算させる」という、中級者への登竜門となるテクニックを伝授します。これさえマスターすれば、どんなに長い項目名でも、美しく整列したプロフェッショナルなドキュメントが一瞬で完成します。
—
1. なぜ「固定値」ではいけないのか?
VBAで `Paragraph.Format.CharacterUnitFirstLineIndent = 2` のように書くのは簡単です。しかし、フォントサイズが変わったり、全角・半角が混在したりすると、途端にレイアウトが破綻します。
私たちが目指すべきは、「コンテンツの長さを計測し、それに基づいてインデントを動的に算出する」というロジックです。
ぶら下げインデントの構造
Wordの段落における「ぶら下げインデント」は、主に以下の2つの要素で成り立っています。
- 左インデント(LeftIndent): 行全体の開始位置
- ぶら下げインデント(FirstLineIndent): 2行目以降が開始する位置
今回は、項目名(例:「1. 概要:」)の長さを自動計測し、その幅に合わせたインデントを適用するコードを書いていきましょう。
—
2. 動的インデント適用コードの実装
以下のコードは、選択した段落内の特定の文字列(今回は `:` を区切り文字と想定)を検出し、そこまでの長さを計測してインデントを自動設定するものです。
Sub AutoAdjustHangingIndent()
‘ 選択範囲の段落を対象にする
Dim para As Paragraph
Dim targetText As String
Dim delimiterPos As Long
Dim indentWidth As Single
‘ 画面描画を停止して高速化
Application.ScreenUpdating = False
For Each para In Selection.Paragraphs
targetText = para.Range.Text
‘ “:” の位置を探す(区切り文字)
delimiterPos = InStr(targetText, “:”)
‘ 区切り文字が見つかった場合のみ処理
If delimiterPos > 0 Then
‘ 1. 一時的に文字幅を計測するためのダミー範囲を作成(裏技的アプローチ)
Dim tempRange As Range
Set tempRange = para.Range
tempRange.End = tempRange.Start + delimiterPos
‘ 2. 文字列の幅をポイント単位で取得(ここで正確な長さを算出)
indentWidth = tempRange.Information(wdHorizontalPositionRelativeToTextBoundary) + 20
‘ 3. インデントを適用
With para.Format
.CharacterUnitLeftIndent = 0
.CharacterUnitFirstLineIndent = -2 ‘ ぶら下げの基本設定
.LeftIndent = indentWidth ‘ 計算した幅を左インデントに適用
End With
End If
Next para
Application.ScreenUpdating = True
MsgBox “インデントの最適化が完了しました!”
End Sub
—
3. コードの心臓部を読み解く
このコードには、初心者がマクロの記録では決して到達できない「3つの重要ポイント」が含まれています。
① `Information` プロパティの活用
`tempRange.Information(wdHorizontalPositionRelativeToTextBoundary)`
これが今回のキモです。これを使うことで、「文字数」ではなく「実際の描画幅(ポイント単位)」を計測できます。フォントサイズや種類を問わず、物理的に正しいインデントを弾き出せるのは、このプロパティを知っている者だけです。
② `Application.ScreenUpdating`
大量の段落を操作する場合、画面の再描画は最大のパフォーマンス・キラーです。`False` にすることで、処理速度が劇的に向上します。大規模ドキュメントを扱う際には必須の作法です。
③ インデント設定の数学的アプローチ
`CharacterUnit`(文字単位)と `LeftIndent`(ポイント単位)を組み合わせることで、OSやWordの設定に依存しない、極めて堅牢なレイアウト制御が可能になります。
—
4. 陥りやすい「罠」と対策
- エラー:`Range` が範囲外を指す
段落末尾の改行コード(Chr(13))を含めて計算しようとすると予期せぬ挙動になります。`para.Range.End – 1` を使用するなど、常に範囲の「端」には注意を払いましょう。
- エラー:処理が重すぎる
ドキュメント全体(`ActiveDocument.Paragraphs`)に対して行う場合は、`For Each` ループ内で `DoEvents` を挟むか、処理対象を `Selection` に限定するよう設計するのが賢明です。
—
最後に:エンジニアとしての一歩先へ
今回学んだ「動的な計算」という考え方は、インデントだけでなく、表の列幅調整や図形の配置にも応用できます。
「Wordはマクロの記録で動かすもの」という認識を捨て、「Wordの描画情報を取得し、ロジックで制御する」というエンジニアリングの視点を持ってください。この視点を持つだけで、あなたの自動化ツールは「おもちゃ」から「業務基盤」へと進化します。
もしコードが動かない、あるいはもっと複雑な条件(複数行に渡るインデントなど)を実装したい場合は、ぜひまた聞いてください。あなたの自動化の旅を、全力でサポートします!
