【入門編】【中級者向け】Wordの「スタイル」が手動で上書きされていないかチェックする監査ツール – Word VBA解析バイブル

スポンサーリンク

こんにちは! Word VBAの世界へようこそ。
マクロの記録ボタンを押して「動いた!」と感動したのもついで、いざ自分でコードを書こうとすると「あれ、思った通りに動かない…」「オブジェクトって何?」と壁にぶつかっていませんか?

大丈夫。今日、その壁を鮮やかに飛び越えてみせましょう。

私たちが向き合うWordというアプリケーションは、Excelのセルとは違い、「段落」「文字」「スタイル」「セクション」といった目に見えない構造が複雑に絡み合う生き物のようなものです。ここを正しく手なずけることができれば、何百ページもあるドキュメントの品質管理だって、一瞬で終わらせることができます。

今回は、実務で絶対に役立つ「スタイルの手動上書き(ローカル書式)を検知する監査ツール」を一緒に作っていきます。
ここをクリアすれば、あなたのWord VBAスキルは間違いなく「中級者の扉」を開けますよ。さあ、深呼吸して、一緒にコードの深淵へ潜りましょう!

なぜ「スタイル監査ツール」が必要なのか?

ドキュメントの品質管理で一番イライラすること、それは何だと思いますか?

「見出し1スタイルが適用されているはずなのに、なぜか一部分だけフォントサイズが手動で変えられている」
「誰かが勝手に文字の色を変えたせいで、全体の見栄えがバラバラになっている」

Wordには「スタイル」という素晴らしい仕組みがあり、これを使えばデザインの統一が簡単です。しかし、人間は魔が差すと、ついつい「選択して、上のリボンからフォントサイズを変更」という手動の化粧(ローカル書式)をしてしまいます。

この「スタイルの隠れ裏切り」を人力で探すのは地獄の作業です。だからこそ、VBAにこう命じるのです。

> 「おいWord、指定したスタイルが適用されているはずの段落を総チェックして、勝手に手動でフォントや色を変えてる不届き者がいたら、全部リストアップして報告してくれ」

これが、今回作成する監査ツールの正体です。

本日のキーパーソン:Wordオブジェクトの構造を理解する

コードを書く前に、Wordの頭の中を少し覗いてみましょう。Word VBAをマスターするための第一歩は、オブジェクトの階層構造(親子関係)を理解することです。

[Application (Word)]
└─ [Document (文書)]
└─ [Paragraphs (段落の集まり)]
└─ [Paragraph (個々の段落)]
├─ .Style (適用されているスタイル)
└─ [Range (段落の中身)]
├─ .Font (フォント情報)
└─ .Duplicate (影武者オブジェクト ※超重要!)

ここでプログラミング初学者が一番最初にハマる罠があります。
「段落のフォント(`Paragraph.Range.Font`)」を調べようとすると、「その段落の中に複数のフォントサイズが混ざっている場合、返ってくる値は `wdUndefined`(不定=ごちゃ混ぜ)になる」という仕様です。

さらに、Wordの `.Font` プロジェクトは、手動で変更されていないプロパティについても「現在の見た目の値」を返してしまいます。これでは「スタイル本来の値」と「手動で変えられた値」の区がつきません。

この難問を解決するのが、伝説のエンジニアたちが愛用するテクニック、「スタイルが本来持っているデフォルトのフォント情報」「実際の段落のフォント情報」の比較です。

実装:スタイル監査ツール・完全版コード

お待たせしました。実際の開発現場でそのままコピペして使える、実用的なマクロコードをプレゼントします。

WordのVBAエディタ(`Alt + F11`)を開き、標準モジュールに以下のコードを貼り付けてください。

Option Explicit

‘ ==============================================================================
‘ 処理名 : 지정したスタイルの手動上書き(ローカル書式)を監査するツール
‘ 概要 : 本文中の指定スタイル(例: “見出し 1″)の段落をスキャンし、
‘ 手動でフォント名やサイズが変更されているものを検出してログ出力する。
‘ ==============================================================================
Public Sub AuditParagraphStyles()

‘ — 1. 変数の宣言 —
Dim targetStyleName As String
targetStyleName = “見出し 1” ‘ ← 監査したいスタイル名をここに指定

Dim doc As Document
Set doc = ActiveDocument

Dim para As Paragraph
Dim targetStyle As Style

Dim mismatchCount As Long
mismatchCount = 0

Dim reportText As String
reportText = “【スタイル監査レポート】” & vbCrLf & _
“対象スタイル: ” & targetStyleName & vbCrLf & _
“—————————————-” & vbCrLf

‘ スタイルが存在するか事前にチェック
On Error Resume Next
Set targetStyle = doc.Styles(targetStyleName)
On Error GoTo 0

If targetStyle Is Nothing Then
MsgBox “指定されたスタイル「 ” & targetStyleName & ” 」が見つかりません。”, vbCritical, “エラー”
Exit Sub
End If

‘ — 2. ドキュメント内の全段落をループ走査 —
Dim checkCount As Long
checkCount = 0

For Each para in doc.Paragraphs
‘ 段落に目的のスタイルが適用されているか?
If para.Style = targetStyleName Then
checkCount = checkCount + 1

‘ 【核心】
‘ スタイルの基本フォント設定と、実際の段落のフォント設定を比較する
‘ ※ Word VBAでは、手動変更がない場合、Fontプロパティはスタイルを継承する
‘ ここでは簡潔かつ堅牢に「サイズ」と「フォント名」の乖離をチェック

Dim isOverridden As Boolean
isOverridden = False

Dim detailMsg As String
detailMsg = “”

‘ フォント名の比較(手動上書きの検知)
‘ 注意: para.Range.Font.Name は手動変更されていなければスタイル名を返す
If para.Range.Font.Name <> targetStyle.Font.Name Then
isOverridden = True
detailMsg = detailMsg & ” [フォント名変更: 設定値=” & targetStyle.Font.Name & ” / 実測値=” & para.Range.Font.Name & “]”
End If

‘ フォントサイズの比較(手動上書きの検知)
‘ Wordのサイズはポイント単位(例: 10.5)で返るため、わずかな誤差を考慮して比較
If Abs(para.Range.Font.Size – targetStyle.Font.Size) > 0.1 Then
isOverridden = True
detailMsg = detailMsg & ” [サイズ変更: 設定値=” & targetStyle.Font.Size & “pt / 実測値=” & para.Range.Font.Size & “pt]”
End If

‘ — 3. 違反が見つかった場合の処理 —
If isOverridden Then
mismatchCount = mismatchCount + 1

‘ 該当段落の先頭から30文字を取得してプレビューにする(長すぎるのを防ぐ)
Dim previewText As String
previewText = Left(Replace(para.Range.Text, vbCr, “”), 30)

reportText = reportText & “・段落番号(おおよそ): ” & checkCount & _
” | 内容: ” & previewText & “…” & vbCrLf & _
” 詳細: ” & detailMsg & vbCrLf & vbCrLf

‘ 目視確認しやすいように、該当段落を一時的に黄色くハイライト(おまけ機能)
‘ para.Range.HighlightColorIndex = wdYellow ‘ 必要に応じてコメントアウトを外す
End If

End If
Next para

‘ — 4. 監査結果の出力 —
reportText = reportText & “—————————————-” & vbCrLf & _
“監査完了: 検査段落数=” & checkCount & “件 / 違反検出数=” & mismatchCount & “件”

‘ 結果をイミディエイトウィンドウに出力
Debug.Print reportText

‘ 結果を新しいWord文書としてポップアップ出力
Dim reportDoc As Document
Set reportDoc = Documents.Add
reportDoc.Content.Text = reportText

MsgBox “監査が完了しました!” & vbCrLf & “検出された違反件数: ” & mismatchCount & “件”, vbInformation, “品質管理完了”

End Sub

コードのここがポイント! 押さえておくべきエンジニアの知見

このコードには、Word VBAの挙動を熟知していなければハマる「罠」を回避するための知見が詰まっています。

1. `Abs(para.Range.Font.Size – targetStyle.Font.Size) > 0.1` の理由
浮動小数点(小数点の計算)は、コンピュータの世界では微小な誤差(例: `10.5` が `10.499999` になるなど)を生むことがあります。そのため、完全一致(`=`)ではなく、「差が0.1ポイント以上あるか」という安全な判定(イプシロン比較)を行っています。
2. `Paragraphs` コレクションの爆発力への配慮
Wordの文書が長大になると、`For Each` による段落走査はわずかに時間がかかります。しかし、オブジェクトのライフサイクルを適切に管理し、不要な画面描画の更新を抑制していれば(今回はシンプルに書いていますが)、数百ページの文書であっても一瞬で終わります。
3. 結果を新しいドキュメントとして吐き出す設計
`Debug.Print` だけだと初心者エンジニアは見落としがちです。そのため、自動で新しいWord文書を作成し、そこにレポートを綺麗に出力する親切設計にしています。現場のディレクターや校正担当者にそのまま渡せるため、実務で非常に重宝されます。

先輩エンジニアからのエール

お疲れ様でした! ここまでコードを読み解き、Wordのオブジェクト構造に思いを馳せたあなたなら、もう「マクロの記録をポチポチ押すだけの人」ではありません立派な自動化エンジニアの卵です。

Word VBAはExcelに比べて情報が少なく、少しとっつきにくいと感じるかもしれませんが、ドキュメントの構造化(スタイル統制)とVBAの組み合わせは、業務効率化において無類の強さを発揮します。

「ここをもっとこうしたい」「こんなエラーが出るんだけど」という疑問が湧いてきたら、それこそが成長の証です。ぜひ、このコードをベースにあなたの現場のルールに合わせてカスタマイズしてみてください。

あなたのVBAライフが、美しく、エラーのないものでありますように。それではまた、次の技術の深淵でお会いしましょう!

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