こんにちは!Word VBAの世界へようこそ。
マクロの記録ボタンを押して出てきたコードをそのまま動かしてみたものの、「なぜか思った通りの書式にならない」「スタイルの仕組みが複雑で、どこを直せばいいか分からない」――そんな壁にぶつかっていませんか?
大丈夫。今回は、Word VBAのなかでも一歩進んだ「段落とスタイルの継承関係の解析」というディープなテーマを、優しく、そして本質的に解き明かしていきます。
ここをクリアすれば、あなたはもう「言われたコードを貼り付けるだけの人」ではありません。Wordのドキュメント構造を手の内で操る、真のオートメーション・エンジニアへの扉が開きます。さあ、一緒に深淵を覗いてみましょう!
—
1. なぜ「スタイル」と「フォント」の自動化は難しいのか?
Wordを使っていると、「標準」スタイルをベースにして「見出し1」があり、その中にさらに独自の変更を加えた段落があったりしますよね。
ここで問題です。
「今、目の前にあるこの段落の文字、最終的に何というフォントで表示されているの?」
プログラムから単純に `Range.Font.Name` を見ようとすると、実は罠があります。もしその段落で直接フォントを指定していない場合、Wordは返してくれないか、あるいは「親であるスタイル」の設定を引っ張ってきます。さらにそのスタイルが別のスタイルを継承していたら……?
そう、Wordの書式は「継承のピラミッド構造」になっています。
このピラミッドを根っこ(ベーススタイル)まで遡り、どこでフォント名やサイズが上書きされているかを動的に計算するエンジンを作ること。それが今回のゴールです。
—
2. 【図解】スタイル継承の仕組み
頭の中で、次のような継承ツリーをイメージしてください。
[ 基準のスタイル (Normal / 標準) ]
┗ フォント: “游明朝”, サイズ: 10.5pt
│
▼ 継承 (BasedOn)
[ 見出しベースのスタイル ]
┗ フォント: (指定なし=親を引き継ぐ), サイズ: 14pt
│
▼ 継承 (BasedOn)
[ 独自見出しスタイル ]
┗ フォント: “メイリオ” (ここで上書き!), 太字: True
│
▼ 適用
[ 実際の段落 (Paragraph) ]
┗ 直接設定(ダイレクトフォーマット)で色だけ「青」に変更
私たちが知りたいのは、この複雑な階層をアルゴリズムで遡り、最終的に「この段落のフォントは何なのか?」を正確に割り出すことです。
—
3. 実装:スタイル継承を遡る「フォント解析エンジン」
百聞は一見に如かず。実際に動かせるプロ仕様のVBAコードを書き下ろしました。
このコードをWordのVBAエディタ(Alt + F11)の標準モジュールに貼り付けて実行してみてください。カーソルがある段落のフォントが、どこから継承されて決まったのかをイミディエイトウィンドウに実況中継してくれます。
Option Explicit
‘ =====================================================================
‘ 処理名: 選択中段落のフォント継承解析エンジン
‘ 概要 : スタイルのベース関係を再帰的に遡り、最終的なフォントを算出する
‘ =====================================================================
Sub AnalyzeParagraphFontInheritance()
Dim targetPara As Paragraph
Set targetPara = Selection.Paragraphs(1)
‘ 対象段落に適用されているスタイルを取得
Dim currentStyle As Style
Set currentStyle = targetPara.Style
Debug.Print “=== 【フォント継承解析開始】 ===”
Debug.Print “対象段落のスタイル名: ” & currentStyle.NameLocal
‘ 1. ダイレクトフォーマット(段落・文字に直接かけられた装飾)のチェック
Dim directFontName As String
directFontName = targetPara.Range.Font.Name
If directFontName <> “” Then
Debug.Print ” -> [直接設定発見] フォント: ” & directFontName
End If
‘ 2. スタイル階層を遡るループ
Dim workStyle As Style
Set workStyle = currentStyle
Dim resolvedFontName As String
resolvedFontName = “”
Do While Not workStyle Is Nothing
Debug.Print ” スタイル確認: ” & workStyle.NameLocal
‘ スタイル自体のフォント設定を確認
‘ ※Wordの仕様上、未設定の場合は親やデフォルトの値が入ることがあるため簡易判定
On Error Resume Next
Dim styleFont As String
styleFont = workStyle.Font.Name
On Error GoTo 0
If styleFont <> “” Then
Debug.Print ” -> スタイル「” & workStyle.NameLocal & “」でフォント定義を発見: ” & styleFont
If resolvedFontName = “” Then resolvedFontName = styleFont
End If
‘ 基準となるスタイル(BasedOn)へ遡る
On Error Resume Next
Set workStyle = workStyle.BaseStyle
On Error GoTo 0
‘ 循環参照の防止(万が一の無限ループ対策)
If workStyle Is currentStyle Then Exit Do
Loop
‘ 3. 最終結果の出力
Debug.Print “———————————-”
If directFontName <> “” Then
Debug.Print “【最終判定】ダイレクトフォーマットが優先されます: ” & directFontName
ElseIf resolvedFontName <> “” Then
Debug.Print “【最終判定】スタイル継承により決定されたフォント: ” & resolvedFontName
Else
Debug.Print “【最終判定】Wordのデフォルト(標準スタイル等)に依存します。”
End If
Debug.Print “=== 【解析終了】 ===”
MsgBox “解析が完了しました。[Ctrl + G] でイミディエイトウィンドウを確認してください。”, vbInformation
End Sub
—
4. コードの解説と「初心者がハマりやすい罠」
このコードには、実務でWord VBAを使う上で知っておくべき重要なエッセンスが詰まっています。
① `Selection.Paragraphs(1)` の安全な使い方
初心者の方がやりがちなのが、`Selection.Font` を直接叩いてエラーになるパターンです。Wordの選択範囲(Selection)は文字、段落、図形など様々な状態を取り得るため、「今カーソルがある段落」を明確に特定する(`Paragraphs(1)`)のが、安定稼働させるための鉄則です。
② ダイレクトフォーマットの恐怖
Wordには、「スタイル」とは別に、ユーザーがツールバーから直接「太字」にしたり「フォント名」を変えたりするダイレクトフォーマットという仕組みがあります。
これが厄介なことに、スタイル自体の設定よりもダイレクトフォーマットが優先されるというルールを持っています。
今回のコードでは、まず最初にダイレクトフォーマット(`targetPara.Range.Font.Name`)をチェックし、それが空(何も直接いじられていない)であればスタイルを遡る、という実務的な優先順位を忠実に再現しています。
③ `On Error Resume Next` の正しい使い方
VBAでスタイルオブジェクトのプロパティ(特に言語ごとのフォント設定など)にアクセスすると、環境やWordのバージョンによって予期せぬエラーや空値が返ることがあります。
「エラーでマクロが止まってしまっては困る箇所」に限定して `On Error Resume Next` を挟み、直後に `On Error GoTo 0` でエラー監視を元に戻す。これがプログラミングの作法として非常に美しい書き方です。
—
まとめ:ここをクリアすればWord VBAの基本はバッチリ!
お疲れ様でした!今回は少しハイレベルな「スタイルの継承関係の動的解析」について解説しました。
- Wordの書式は「ダイレクトフォーマット」と「スタイルの継承」の二階建てであること
- `BaseStyle` プロパティを使うことで、スタイルのピラミッドを遡れること
- オブジェクトのライフサイクルや例外(エラー)を想定した堅牢な書き方
これらを理解できたあなたは、もう初級者ではありません。
どんなに複雑な社内フォーマットの文書が持ち込まれても、「この文書の裏側ではどのスタイルがどう継承されているか」をプログラムで完全にコントロールできるようになります。
現場でバリバリと自動化を推し進めるエンジニアを目指して、ぜひこのコードをご自身のプロジェクトに応用してみてくださいね。それでは、また次の知見でお会いしましょう!
