【上級者向け】Wordの「段落」書式設定をJSONで外部管理し、設定変更を容易にする究極の設計
開発者の皆さん、そしてWord VBAによる業務効率化ツール開発に情熱を燃やす皆さん。プロジェクトリーダーの視点から、今日は皆さんが日々直面しているであろう、ある「非効率」な開発手法にメスを入れ、より洗練された、プロダクションレベルの設計思想をお伝えしたいと思います。
それは、Word VBAにおける「段落」の書式設定を、コードの中に直接書き込む(ハードコーディングする)というアプローチです。一見、手っ取り早く見えますが、これは保守性の低下、バグの温床、そして何よりも「変更への弱さ」を招く、開発プロジェクトの癌になりかねません。
「いや、でも、そんなに頻繁に変わるものではないだろう?」
そう思われたあなた。まさにその考え方が、変化の激しいビジネス環境において、あなたの開発したツールを「陳腐化」させるのです。仕様変更、デザイン改訂、あるいは単に「この行間、もう少しだけ狭くしたい」という些細な要望が、VBAコードの無数の箇所を修正する地獄絵図へとあなたを誘います。
そこで本日は、この問題を根本から解決する、JSONファイルによる段落書式設定の外部管理というアプローチを、その設計思想から実践的なコード例まで、徹底的に解説していきます。これは、単なる「テクニック」ではなく、変化に強く、保守性が高く、そして何よりも「開発者の時間を解放する」ための、戦略的な設計手法です。
—
なぜハードコーディングは「非効率」なのか?
まず、なぜ段落の書式設定をVBAコード内に直接記述することが問題なのか、その理由を明確にしましょう。
- 保守性の低下:
- 変更コストの増大: 書式設定に変更があった場合、VBAコードの該当箇所を全て探し出し、修正する必要があります。これは、コード量が増えるほど、そのコストは指数関数的に増加します。
- 属人化の促進: コードが複雑化し、書式設定の意図がコードから読み取りにくくなると、担当者以外が修正するのが困難になり、プロジェクトの属人化を招きます。
- バグの温床:
- 修正漏れ・誤修正: 多数の箇所に同じ書式設定が散らばっていると、一部の修正漏れや、意図しない書式設定の誤修正が発生しやすくなります。
- デバッグの困難さ: 書式設定が原因で意図しないレイアウトになる場合、コードのどこに問題があるのかを特定するのに膨大な時間を費やすことになります。
- 変更への弱さ:
- 仕様変更への対応遅延: デザインチームやクライアントからの「ちょっとこのフォントサイズを変えてほしい」「行間を調整したい」といった軽微な要望にも、VBAコードの再コンパイルや再配布が必要になる場合があります。これは、開発サイクルの遅延に直結します。
- 可読性の低下:
- コードの意図不明瞭化: `With Selection.ParagraphFormat` の羅列は、コードの主要なロジックから切り離され、コード全体の可読性を著しく低下させます。
これらの問題を解決するために、私たちは「設定」と「ロジック」を分離する、より疎結合な設計を採用すべきです。
—
疎結合設計の王道:JSONによる書式設定の外部管理
ここで登場するのが、JSON (JavaScript Object Notation) です。JSONは、軽量で、人間が読みやすく、そして機械が解析しやすいデータ交換フォーマットであり、現代のソフトウェア開発において、設定ファイルやAPIレスポンスの形式として広く採用されています。
このJSONの特性を活かし、Word VBAの段落書式設定をJSONファイルで管理することで、以下のようなメリットを享受できます。
- 設定とロジックの完全分離: 書式設定はVBAコードから完全に切り離され、JSONファイルで一元管理されます。
- 容易な変更: 書式設定の変更は、VBAコードを一切触ることなく、JSONファイルを編集するだけで完了します。
- 再配布の容易さ: VBAコードの再コンパイルや再配布は不要。JSONファイルを更新するだけで、即座に新しい書式設定が適用されます。
- 複数ドキュメントへの適用: 同じJSONファイルを複数のWord文書やVBAプロジェクトで共有し、一貫した書式設定を適用できます。
- 可読性と保守性の向上: VBAコードは本来のロジックに集中でき、JSONファイルは人間が理解しやすい形式で書式設定を記述できます。
JSON構造の設計思想
では、どのようなJSON構造にすれば、Word VBAから効率的に読み込めるでしょうか。重要なのは、「何を」「どう」設定したいのかを明確にし、それをJSONのキーと値で表現することです。
例として、段落のフォント設定と行間設定を管理するJSONを考えてみましょう。
{
“styles”: {
“heading1”: {
“font”: {
“name”: “メイリオ”,
“size”: 20,
“bold”: true,
“italic”: false,
“color”: “0000FF” // RGB 16進数 (例: 青)
},
“paragraph”: {
“spaceBefore”: 12, // ポイント
“spaceAfter”: 6, // ポイント
“lineSpacing”: 1.5, // 倍数 (1.0 = シングル, 1.5 = 1.5行)
“alignment”: “wdAlignParagraphCenter” // Word VBA定数
}
},
“bodyText”: {
“font”: {
“name”: “游ゴシック”,
“size”: 10.5,
“bold”: false,
“italic”: false,
“color”: “000000”
},
“paragraph”: {
“spaceBefore”: 0,
“spaceAfter”: 3,
“lineSpacing”: 1.2,
“alignment”: “wdAlignParagraphLeft”
}
}
// 他のスタイル定義を追加可能
}
}
設計のポイント:
- `styles` ルートオブジェクト: 全てのスタイル定義を格納します。
- スタイル名 (例: `heading1`, `bodyText`): 適用したい段落のスタイル名や識別子をキーとします。
- `font` オブジェクト: フォントに関する設定(フォント名、サイズ、太字、斜体、色)をまとめます。
- `paragraph` オブジェクト: 段落書式に関する設定(前後の間隔、行間、配置)をまとめます。
- Word VBA定数の活用: `alignment` のように、VBAの定数名を文字列で格納し、VBA側で `Evaluate` 関数などを使って実際の定数値に変換します。これにより、VBAコードの移植性が高まります。
- 色の表現: RGB値を16進数文字列で格納するのが一般的です。VBA側で `RGB(HexToInt(color))` のような関数で変換します。
—
VBAでのJSON解析と書式設定の適用
JSONファイルをVBAで扱うには、JSONパーサーライブラリが必要です。標準で提供されているものはありませんが、Microsoft Scripting Runtime の `Dictionary` オブジェクトや、外部ライブラリ(例: VBA-JSON)を利用するのが一般的です。
ここでは、より手軽に始められるよう、`Dictionary` オブジェクトと、簡単なJSON解析ロジックを組み合わせて実装する例を示します。もし、より複雑なJSON構造を扱う場合は、VBA-JSONのような専用ライブラリの導入を強く推奨します。
1. JSONファイルの読み込みと解析関数
まず、JSONファイルを読み込み、それをVBAの `Dictionary` オブジェクトに変換する関数を作成します。
‘==============================================================================
‘ Module: modJsonParser
‘ Description: JSONファイルをDictionaryオブジェクトに変換するユーティリティ
‘==============================================================================
Option Explicit
‘ JSONファイルを読み込み、Dictionaryオブジェクトに変換する関数
‘ 簡易的な解析ロジックです。複雑なJSON構造には専用ライブラリを推奨します。
Public Function LoadJsonToDictionary(filePath As String) As Object
Dim fileContent As String
Dim jsonParser As Object ‘ VBA-JSONなどのライブラリを使用する場合はここで宣言
Dim jsonString As String
‘ ファイルが存在するかチェック
If Dir(filePath) = “” Then
MsgBox “指定されたJSONファイルが見つかりません: ” & filePath, vbCritical
Set LoadJsonToDictionary = Nothing
Exit Function
End If
‘ ファイルの内容を読み込む
On Error GoTo ErrorHandler
fileContent = ReadTextFile(filePath)
On Error GoTo 0
‘ ここでJSON文字列を解析し、Dictionaryオブジェクトに変換します。
‘ VBA-JSONライブラリを使用する場合の例:
‘ Set jsonParser = JsonConverter.Parse(fileContent)
‘ Set LoadJsonToDictionary = jsonParser
‘ — 簡易解析ロジック (Dictionaryオブジェクトのみを使用) —
‘ この簡易ロジックは、ネストされたオブジェクトや配列には対応していません。
‘ より堅牢な解析が必要な場合は、VBA-JSONなどのライブラリを導入してください。
‘ 以下は、あくまで概念を示すためのプレースホルダーです。
‘ 実際には、より高度な文字列解析や、外部ライブラリの利用が必要です。
MsgBox “簡易JSON解析ロジックは、この例では実装されていません。” & vbCrLf & _
“実際の開発では、VBA-JSONなどのライブラリを使用するか、”, vbInformation _
“より堅牢なカスタムパーサーを実装してください。”
‘ プレースホルダーとして、空のDictionaryを返す
Set LoadJsonToDictionary = CreateObject(“Scripting.Dictionary”)
‘ ——————————————————-
Exit Function
ErrorHandler:
MsgBox “JSONファイルの読み込みまたは解析中にエラーが発生しました: ” & Err.Description, vbCritical
Set LoadJsonToDictionary = Nothing
End Function
‘ テキストファイルを読み込むヘルパー関数
Private Function ReadTextFile(filePath As String) As String
Dim fso As Object
Dim ts As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.OpenTextFile(filePath, 1) ‘ 1 = ForReading
ReadTextFile = ts.ReadAll
ts.Close
Set ts = Nothing
Set fso = Nothing
End Function
‘ RGB 16進数文字列をVBAのRGB値に変換するヘルパー関数
Public Function ConvertHexToRgb(hexColor As String) As Long
Dim r As Integer, g As Integer, b As Integer
On Error Resume Next
r = Val(“&H” & Mid(hexColor, 1, 2))
g = Val(“&H” & Mid(hexColor, 3, 2))
b = Val(“&H” & Mid(hexColor, 5, 2))
If Err.Number <> 0 Then
ConvertHexToRgb = -1 ‘ エラーを示す値
Err.Clear
Else
ConvertHexToRgb = RGB(r, g, b)
End If
On Error GoTo 0
End Function
‘ VBA定数名文字列を実際の定数値に変換するヘルパー関数
Public Function EvaluateVbaConstant(constantName As String) As Variant
On Error Resume Next
EvaluateVbaConstant = Application.Evaluate(constantName)
If Err.Number <> 0 Then
‘ 定数が見つからなかった場合や、不正な名前の場合
MsgBox “VBA定数 ‘” & constantName & “‘ が見つかりません。”, vbExclamation
EvaluateVbaConstant = Null ‘ または適切なデフォルト値
Err.Clear
End If
On Error GoTo 0
End Function
注意点: 上記の `LoadJsonToDictionary` 関数は、簡易的な実装のプレースホルダーです。実際の開発では、VBA-JSONライブラリのような信頼できるJSONパーサーの利用を強く推奨します。VBA-JSONの導入方法については、別途検索していただくか、プロジェクトの要件に応じてカスタムパーサーを実装してください。
2. 段落書式を適用するメインルーチン
次に、解析したJSONデータを使って、選択中の段落(または指定した範囲の段落)に書式設定を適用するVBAコードを作成します。
‘==============================================================================
‘ Module: modParagraphFormatter
‘ Description: JSON設定に基づき段落書式を適用する
‘==============================================================================
Option Explicit
‘ JSONファイルパス (必要に応じて変更)
Const JSON_CONFIG_PATH As String = “C:\Your\Path\To\paragraph_styles.json” ‘ ★★★ 実際のパスに変更してください ★★★
‘ 指定されたスタイル名で段落書式を適用する
Public Sub ApplyParagraphStyleFromJson(styleName As String)
Dim jsonConfig As Object
Dim styleSettings As Object
Dim fontSettings As Object
Dim paragraphSettings As Object
Dim rng As Range
‘ 選択範囲を取得 (あるいは、特定のRangeオブジェクトを指定)
If Selection.Type = wdSelectionIP Then ‘ 挿入ポイントのみの場合
Set rng = ActiveDocument.Range(Selection.Start, Selection.Start)
Else ‘ 範囲が選択されている場合
Set rng = Selection.Range
End If
‘ JSON設定ファイルを読み込む
Set jsonConfig = LoadJsonToDictionary(JSON_CONFIG_PATH)
If jsonConfig Is Nothing Then
MsgBox “JSON設定の読み込みに失敗しました。”, vbCritical
Exit Sub
End If
‘ 指定されたスタイル設定を取得
If Not jsonConfig.Exists(styleName) Then
MsgBox “JSON設定ファイルにスタイル ‘” & styleName & “‘ が見つかりません。”, vbExclamation
Exit Sub
End If
Set styleSettings = jsonConfig(styleName)
‘ フォント設定と段落設定を取得
If styleSettings.Exists(“font”) Then
Set fontSettings = styleSettings(“font”)
Else
Set fontSettings = Nothing
End If
If styleSettings.Exists(“paragraph”) Then
Set paragraphSettings = styleSettings(“paragraph”)
Else
Set paragraphSettings = Nothing
End If
‘ — 書式設定の適用 —
‘ 注意: Selection.ParagraphFormat は、選択範囲の最初の段落のみに影響することがあります。
‘ 複数の段落に適用するには、RangeオブジェクトのParagraphsコレクションをループする必要があります。
‘ 段落設定の適用 (選択範囲の各段落に適用)
If Not paragraphSettings Is Nothing Then
Dim p As Paragraph
For Each p In rng.Paragraphs
‘ 段落前後の間隔
If paragraphSettings.Exists(“spaceBefore”) Then
p.SpaceBefore = paragraphSettings(“spaceBefore”)
End If
If paragraphSettings.Exists(“spaceAfter”) Then
p.SpaceAfter = paragraphSettings(“spaceAfter”)
End If
‘ 行間
If paragraphSettings.Exists(“lineSpacing”) Then
p.LineSpacingRule = wdLineSpacingMultiple ‘ 倍数指定
p.LineSpacing = paragraphSettings(“lineSpacing”)
End If
‘ 配置
If paragraphSettings.Exists(“alignment”) Then
Dim alignmentValue As Variant
alignmentValue = EvaluateVbaConstant(paragraphSettings(“alignment”))
If Not IsNull(alignmentValue) Then
p.Alignment = alignmentValue
End If
End If
Next p
End If
‘ フォント設定の適用 (選択範囲の各段落のフォントに適用)
‘ 注意: 段落全体ではなく、選択範囲内のフォントを直接変更したい場合は、
‘ rng.Font プロパティを使用します。ここでは段落のデフォルトフォントを想定。
If Not fontSettings Is Nothing Then
Dim pFont As Paragraph
For Each pFont In rng.Paragraphs
‘ フォント名
If fontSettings.Exists(“name”) Then
pFont.Range.Font.Name = fontSettings(“name”)
End If
‘ フォントサイズ
If fontSettings.Exists(“size”) Then
pFont.Range.Font.Size = fontSettings(“size”)
End If
‘ 太字
If fontSettings.Exists(“bold”) Then
pFont.Range.Font.Bold = fontSettings(“bold”)
End If
‘ 斜体
If fontSettings.Exists(“italic”) Then
pFont.Range.Font.Italic = fontSettings(“italic”)
End If
‘ フォント色
If fontSettings.Exists(“color”) Then
Dim rgbColor As Long
rgbColor = ConvertHexToRgb(fontSettings(“color”))
If rgbColor <> -1 Then ‘ 変換成功時
pFont.Range.Font.Color = rgbColor
Else
MsgBox “無効なカラーコードです: ” & fontSettings(“color”), vbExclamation
End If
End If
Next pFont
End If
MsgBox “スタイル ‘” & styleName & “‘ を適用しました。”, vbInformation
End Sub
‘ — 実行例 —
‘ Sub TestApplyStyle()
‘ ‘ 現在選択されている範囲に ‘heading1’ スタイルを適用
‘ Call ApplyParagraphStyleFromJson(“heading1”)
‘
‘ ‘ 現在選択されている範囲に ‘bodyText’ スタイルを適用
‘ ‘ Call ApplyParagraphStyleFromJson(“bodyText”)
‘ End Sub
コードの解説と注意点:
1. JSONパスの指定: `JSON_CONFIG_PATH` 定数に、作成したJSONファイルの絶対パスを指定してください。
2. 範囲の取得: `Selection.Range` を使用して、現在選択されている範囲を取得します。必要に応じて、特定の `Range` オブジェクトを渡すように `ApplyParagraphStyleFromJson` プロシージャを修正してください。
3. JSON読み込み: `LoadJsonToDictionary` 関数(または導入したJSONパーサー)を呼び出し、JSONデータをVBAのオブジェクト(`Dictionary` など)に変換します。
4. スタイル設定の取得: JSONオブジェクトから、指定された `styleName` に対応する設定を取り出します。`.Exists()` メソッドでキーの存在を確認し、エラーを防ぎます。
5. 書式設定の適用:
- `rng.Paragraphs` コレクションをループし、選択範囲内の各段落に書式設定を適用します。これにより、複数行にわたる選択範囲でも正しく書式が適用されます。
- `p.SpaceBefore`, `p.SpaceAfter`, `p.LineSpacingRule`, `p.LineSpacing` など、Word VBAの `Paragraph` オブジェクトのプロパティにJSONから読み込んだ値を設定します。
- `p.Alignment` のような定数値で表されるプロパティには、`EvaluateVbaConstant` 関数を使用してVBAの定数値を評価・適用します。
- フォント設定は、`pFont.Range.Font` プロパティを通じて適用します。
6. エラーハンドリング: ファイルが見つからない場合、指定されたスタイルが存在しない場合、JSONの解析に失敗した場合など、考えられるエラーに対して適切なメッセージを表示し、処理を中断するようにしています。
7. 堅牢な設計: `.Exists()` によるキーの存在チェック、`On Error` ステートメントによるエラーハンドリング、`EvaluateVbaConstant` による定数評価など、バグを未然に防ぐための工夫を凝らしています。
—
ファイル・データベース連携における注意点
JSONファイルを外部管理することで、開発は格段に容易になりますが、実運用においてはいくつかの注意点があります。
ファイル連携の注意点
- JSONファイルの配置場所:
- 実行環境への配布: VBAマクロを含むWord文書を配布する場合、JSONファイルも同じフォルダ、あるいは指定されたパスに配置する必要があります。
- パスの管理: 相対パスではなく、絶対パスで指定するか、あるいはWord文書からの相対パスを計算するロジックを組み込むことを検討してください。
- バージョン管理: JSONファイルもコードと同様に、Gitなどのバージョン管理システムで管理することを推奨します。
- ファイルロックと同時アクセス:
- 複数のユーザーが同時に同じJSONファイルを編集・適用しようとすると、ファイルロックの問題が発生する可能性があります。
- 対策:
- JSONファイルを読み取り専用として配布し、設定変更は管理者のみが行えるようにする。
- VBA側でJSONファイルを一時的な場所にコピーしてから読み込む。
- より高度なシステムでは、データベースや共有設定サーバーを利用します。
- 文字コード:
- JSONファイルはUTF-8エンコーディングで保存するのが一般的です。VBAで読み込む際に、文字化けが発生しないように注意してください。`FileSystemObject` の `OpenTextFile` メソッドは、デフォルトでシステム既定のANSIコードページを使用するため、UTF-8ファイルを正しく読み込むには、`OpenTextFile(filePath, 1, True)` のように `Unicode` パラメータを `True` に設定するか、`ADODB.Stream` など別の方法で読み込む必要があります。
データベース連携の注意点
JSONファイルよりもさらに堅牢な管理が必要な場合、データベース(SQL Server, MySQL, SQLiteなど)に書式設定情報を格納することも検討できます。
- メリット:
- 強力な同時アクセス制御: データベースシステムがトランザクション管理やロック機構を提供します。
- 柔軟なクエリ: 特定の条件で書式設定を検索・取得できます。
- 一元管理: 複数のアプリケーションやVBAプロジェクトから共通の設定を管理できます。
- デメリット:
- 導入・管理コストの増加: データベースサーバーのセットアップ、管理、セキュリティ対策が必要になります。
- VBAからの接続: ADO (ActiveX Data Objects) などを利用してデータベースに接続する必要があります。これはVBAコードをより複雑にします。
- VBAからのアクセス:
- `ADODB.Connection` オブジェクトを使用してデータベースに接続し、SQLクエリを実行して書式設定データを取得します。
- 取得したデータを、JSONと同様のロジックでVBAの `Dictionary` オブジェクトに変換して利用します。
—
プロダクションコード例:保守性とコピペの容易さを両立
ここまで解説してきた内容を基に、すぐにでも開発現場で活用できる、保守性の高いプロダクションコード例を以下に示します。JSONパーサーには、汎用性の高いVBA-JSONライブラリの利用を前提とします。
前提:
- `VBA-JSON` ライブラリが参照設定されていること。 (GitHubなどから `JsonConverter.bas` をダウンロードし、VBAエディタの「ツール」->「参照設定」で追加してください。)
- JSONファイル (`paragraph_styles.json`) が、VBAコードと同じフォルダ、あるいは指定されたパスに存在すること。
`paragraph_styles.json` の例:
{
“styles”: {
“sectionTitle”: {
“font”: {
“name”: “メイリオ”,
“size”: 16,
“bold”: true,
“italic”: false,
“color”: “2E8B57” // SeaGreen
},
“paragraph”: {
“spaceBefore”: 18,
“spaceAfter”: 9,
“lineSpacing”: 1.2,
“alignment”: “wdAlignParagraphCenter”
}
},
“normalText”: {
“font”: {
“name”: “游ゴシック”,
“size”: 10.5,
“bold”: false,
“italic”: false,
“color”: “000000”
},
“paragraph”: {
“spaceBefore”: 0,
“spaceAfter”: 3,
“lineSpacing”: 1.5,
“alignment”: “wdAlignParagraphJustify”
}
},
“listItem”: {
“font”: {
“name”: “游ゴシック”,
“size”: 10.5,
“bold”: false,
“italic”: false,
“color”: “000000”
},
“paragraph”: {
“spaceBefore”: 3,
“spaceAfter”: 0,
“lineSpacing”: 1.2,
“alignment”: “wdAlignParagraphLeft”
}
}
}
}
VBAコード:
‘==============================================================================
‘ Module: modAdvancedParagraphFormatter
‘ Description: JSON設定に基づき段落書式を適用する (VBA-JSONライブラリ使用)
‘==============================================================================
Option Explicit
‘ — 設定 —
‘ JSON設定ファイルのパス (Word文書と同じフォルダを想定)
‘ 必要に応じて絶対パスに変更してください。
Private Const DEFAULT_JSON_FILENAME As String = “paragraph_styles.json”
‘ — メインプロシージャ —
‘ 指定されたスタイル名で、選択中の段落書式を適用する
Public Sub ApplyStyleFromJson(styleName As String, Optional filePath As String = “”)
Dim jsonConverter As Object ‘ VBA-JSON の JsonConverter インスタンス
Dim jsonConfig As Variant ‘ 解析されたJSONデータ (DictionaryまたはCollection)
Dim styleSettings As Variant
Dim rng As Range
Dim paragraphApplier As New clsParagraphFormatter ‘ 書式適用クラスのインスタンス
‘ 1. JSONファイルのパスを決定
Dim actualFilePath As String
If filePath = “” Then
‘ Word文書と同じフォルダパスを取得
If ActiveDocument Is Nothing Then
MsgBox “アクティブなWord文書がありません。”, vbCritical
Exit Sub
End If
actualFilePath = GetDocumentFolderPath(ActiveDocument) & “\” & DEFAULT_JSON_FILENAME
Else
actualFilePath = filePath
End If
‘ 2. JSONファイルの存在チェック
If Dir(actualFilePath) = “” Then
MsgBox “JSON設定ファイルが見つかりません: ” & actualFilePath, vbCritical
Exit Sub
End If
‘ 3. VBA-JSONライブラリによるJSON解析
On Error GoTo JsonParseError
Set jsonConverter = CreateObject(“JsonConverter”) ‘ JsonConverter.bas を参照設定
jsonConfig = jsonConverter.Parse(ReadTextFile(actualFilePath))
Set jsonConverter = Nothing ‘ 不要になったら解放
On Error GoTo 0
‘ 4. スタイル設定の取得
If Not jsonConfig.Exists(“styles”) Then
MsgBox “JSON設定ファイルに ‘styles’ ルートが見つかりません。”, vbCritical
Exit Sub
End If
If Not jsonConfig(“styles”).Exists(styleName) Then
MsgBox “JSON設定ファイルにスタイル ‘” & styleName & “‘ が見つかりません。”, vbExclamation
Exit Sub
End If
Set styleSettings = jsonConfig(“styles”)(styleName) ‘ Variant型で取得
‘ 5. 選択範囲の取得
If Selection.Type = wdSelectionIP Then ‘ 挿入ポイントのみの場合
Set rng = ActiveDocument.Range(Selection.Start, Selection.Start)
Else ‘ 範囲が選択されている場合
Set rng = Selection.Range
End If
‘ 6. 書式設定の適用
paragraphApplier.ApplySettings rng, styleSettings
MsgBox “スタイル ‘” & styleName & “‘ を適用しました。”, vbInformation
Exit Sub
JsonParseError:
MsgBox “JSONファイルの解析中にエラーが発生しました。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical
If Not jsonConverter Is Nothing Then Set jsonConverter = Nothing
End Sub
‘ — ヘルパープロシージャ —
‘ 指定されたドキュメントのフォルダパスを取得する
Private Function GetDocumentFolderPath(doc As Document) As String
Dim folderPath As String
folderPath = doc.Path
If folderPath <> “” Then
GetDocumentFolderPath = folderPath
Else
‘ ドキュメントが保存されていない場合(一時的なパス)
‘ この場合は、デフォルトのJSONファイルパスを上書きするか、
‘ ユーザーに保存を促すなどの処理が必要になります。
‘ ここでは、Windowsの一時フォルダを仮定します。
GetDocumentFolderPath = Environ(“TEMP”)
MsgBox “ドキュメントが保存されていません。” & vbCrLf & _
“JSONファイルは一時フォルダ ‘” & GetDocumentFolderPath & “‘ を検索します。”, vbInformation
End If
End Function
‘ テキストファイルをUTF-8で読み込むヘルパー関数 (ADODB.Streamを使用)
Private Function ReadTextFile(filePath As String) As String
Dim stream As Object
Set stream = CreateObject(“ADODB.Stream”)
stream.Charset = “UTF-8”
stream.Open
stream.LoadFromFile filePath
ReadTextFile = stream.ReadText
stream.Close
Set stream = Nothing
End Function
‘ — 実行例 —
Sub TestApplySectionTitle()
Call ApplyStyleFromJson(“sectionTitle”)
End Sub
Sub TestApplyNormalText()
Call ApplyStyleFromJson(“normalText”)
End Sub
Sub TestApplyListItem()
Call ApplyStyleFromJson(“listItem”)
End Sub
‘ — 外部JSONファイルパスを指定して適用する例 —
‘ Sub TestApplySpecificJson()
‘ Call ApplyStyleFromJson(“normalText”, “D:\MyConfigs\custom_styles.json”)
‘ End Sub
書式適用ロジックをクラスに分離 (`clsParagraphFormatter.cls`):
‘==============================================================================
‘ Class: clsParagraphFormatter
‘ Description: JSONから読み込んだ設定に基づき、段落書式を適用するクラス
‘==============================================================================
Option Explicit
‘ JSON設定 (Variant型, DictionaryまたはCollection) を受け取り、
‘ 指定されたRangeオブジェクトの段落に書式を適用する
Public Sub ApplySettings(targetRange As Range, styleSettings As Variant)
Dim paragraphSettings As Variant
Dim fontSettings As Variant
Dim p As Paragraph
Dim rgbColor As Long
Dim alignmentValue As Variant
‘ 段落設定の取得と適用
If styleSettings.Exists(“paragraph”) Then
Set paragraphSettings = styleSettings(“paragraph”)
For Each p In targetRange.Paragraphs
‘ 段落前後の間隔
If paragraphSettings.Exists(“spaceBefore”) Then
p.SpaceBefore = paragraphSettings(“spaceBefore”)
End If
If paragraphSettings.Exists(“spaceAfter”) Then
p.SpaceAfter = paragraphSettings(“spaceAfter”)
End If
‘ 行間
If paragraphSettings.Exists(“lineSpacing”) Then
p.LineSpacingRule = wdLineSpacingMultiple ‘ 倍数指定
p.LineSpacing = paragraphSettings(“lineSpacing”)
End If
‘ 配置
If paragraphSettings.Exists(“alignment”) Then
‘ VBA定数名を評価して実際の値を取得
alignmentValue = Application.Evaluate(paragraphSettings(“alignment”))
If Not IsError(alignmentValue) And IsNumeric(alignmentValue) Then
p.Alignment = CLng(alignmentValue)
Else
Debug.Print “警告: 無効な配置定数 ‘” & paragraphSettings(“alignment”) & “‘”
End If
End If
Next p
End If
‘ フォント設定の取得と適用
If styleSettings.Exists(“font”) Then
Set fontSettings = styleSettings(“font”)
For Each p In targetRange.Paragraphs
‘ フォント名
If fontSettings.Exists(“name”) Then
p.Range.Font.Name = fontSettings(“name”)
End If
‘ フォントサイズ
If fontSettings.Exists(“size”) Then
p.Range.Font.Size = fontSettings(“size”)
End If
‘ 太字
If fontSettings.Exists(“bold”) Then
p.Range.Font.Bold = fontSettings(“bold”)
End If
‘ 斜体
If fontSettings.Exists(“italic”) Then
p.Range.Font.Italic = fontSettings(“italic”)
End If
‘ フォント色
If fontSettings.Exists(“color”) Then
rgbColor = ConvertHexToRgb(fontSettings(“color”))
If rgbColor <> -1 Then ‘ 変換成功時
p.Range.Font.Color = rgbColor
Else
Debug.Print “警告: 無効なカラーコード ‘” & fontSettings(“color”) & “‘”
End If
End If
Next p
End If
End Sub
‘ RGB 16進数文字列をVBAのRGB値に変換するヘルパー関数
Private Function ConvertHexToRgb(hexColor As String) As Long
Dim r As Integer, g As Integer, b As Integer
ConvertHexToRgb = -1 ‘ デフォルトはエラー値
If Len(hexColor) = 6 Then
On Error Resume Next
r = Val(“&H” & Mid(hexColor, 1, 2))
g = Val(“&H” & Mid(hexColor, 3, 2))
b = Val(“&H” & Mid(hexColor, 5, 2))
If Err.Number = 0 Then
ConvertHexToRgb = RGB(r, g, b)
Else
Err.Clear
End If
On Error GoTo 0
End If
End Function
このプロダクションコード例のポイント:
- クラスモジュールの活用: 書式設定の適用ロジックを `clsParagraphFormatter` クラスに分離することで、メインモジュールがスッキリし、コードの再利用性・保守性が向上します。
- VBA-JSONライブラリ: `CreateObject(“JsonConverter”)` でインスタンス化し、`.Parse()` メソッドでJSON文字列を解析します。`JsonConverter.bas` をプロジェクトに追加するだけで利用できます。
- UTF-8対応: `ADODB.Stream` を使用してJSONファイルをUTF-8で確実に読み込みます。
- ドキュメントパスの自動取得: `GetDocumentFolderPath` 関数により、Word文書と同じフォルダにJSONファイルがあれば自動的に検出します。
- エラーハンドリングの強化: JSON解析エラー、ファイル未検出エラー、スタイル未検出エラーなど、各段階で丁寧なエラーメッセージを表示します。`Application.Evaluate` の結果も `IsError` でチェックします。
- コメントによる解説: 各コードブロックの意図や動作を明確にするためのコメントを豊富に記述しています。
- コピペ容易性: モジュールごとにコードが分かれており、必要なモジュールとクラスをプロジェクトに追加し、JSONファイルを指定すればすぐに動作します。
—
まとめ:変化に強い設計こそ、開発者の武器となる
ハードコーディングされた書式設定は、短期的な「手軽さ」という甘い誘惑に過ぎません。それは、数ヶ月後、あるいは数年後には、あなた自身を苦しめる「技術的負債」へと姿を変えます。
今回ご紹介したJSONによる外部管理というアプローチは、
- 設定変更の劇的な容易化
- コードの可読性と保守性の向上
- バージョン管理の簡便化
- 複数プロジェクト間での設定共有
といった、計り知れないメリットをもたらします。
これは単なる小手先のテクニックではありません。変化を前提とし、疎結合で拡張性の高いシステムを設計するという、現代の開発における本質的な考え方です。この考え方をWord VBA開発に適用することで、皆さんの開発するツールは、より「知的」で、「強く」、そして何よりも「使い続けられる」ものへと昇華するでしょう。
ぜひ、この設計思想をあなたの次のWord VBAプロジェクトに取り入れてみてください。きっと、開発プロセスが劇的に改善され、あなたの貴重な時間を、より創造的なタスクへと振り向けることができるはずです。
それでは、次回の開発でお会いしましょう。
