【実務・中級編】JSON形式の設定ファイルから定数を読み込む:VBAでの外部設定管理の自動化 – Excel VBA解析バイブル

スポンサーリンク

Excel VBAを掌握する極限の知見:JSON設定ファイルによる「脱・ハードコーディング」の極意

こんにちは。開発プロジェクトの現場で、日々数万行のスパゲッティコードや「修正するたびに壊れるマクロ」の絶望と戦ってきたチーフアーキテクトだ。

VBAで業務自動化ツールを開発する際、君たちは接続先のデータベースサーバー名、APIのエンドポイント、あるいはファイル出力先のパスを、どこに書いていらっしゃるかな?
まさか、コード内のあちこちに直接文字列として直書き(ハードコーディング)していないだろうね?

「環境が変わるたびにVBEを開いて書き直す」
「本番環境とテスト環境でコードを切り替えるためにコメントアウトをいじる」

このような開発スタイルは、今すぐ卒業していただきたい。設定値はコードの外へ追い出す。これが、変更に強く、バグを生まないプロフェッショナルなVBA設計の第一歩だ。

今回は、JSON形式の外側で定義された設定ファイルをVBAから動的に読み込み、堅牢な定数として活用する手法を、実務直結のプロダクションコードと共に授けよう。

なぜVBAで「JSON設定ファイル」なのか?

VBAには、標準で `Const` ステートメントによる定数定義機能がある。しかし、これには致命的な弱点がある。「コンパイル時に値が固定されるため、実行時に動的に変更できない」という点だ。

また、設定ファイルとしてINIファイルやCSVファイルを使うアプローチもあるが、階層構造(ネスト)を持つデータや、配列データを扱うには表現力が圧倒的に不足する。現代の開発において、設定ファイルのデファクトスタンダードはJSON(JavaScript Object Notation)だ。

VBAでJSONを扱うためのアプローチは主に2つある。
1. Windows標準の `ScriptControl`(JScript)を利用する(追加ライブラリ不要だが、64bit環境での注意が必要)
2. VBA用の軽量JSONパーサー(VBA-JSON等)を利用する(堅牢で大規模開発向き)

今回は、環境依存を最小限にしつつ、実務で即座に導入できる `ScriptControl` を用いたスマートなJSON解析アプローチを採用する。

現場で即死しないための設計思想

外部ファイルを読み込むシステムを構築する際、プロとアマチュアの決定的な違いは「例外処理とパスの解決」に対する執念の差にある。

1. カレントディレクトリの罠

VBAでよくあるバグの筆頭が、「Excelファイルを開いた場所によって、相対パスの基準が変わる」という現象だ。設定ファイルを読み込む際は、必ず `ThisWorkbook.Path` を基準とした絶対パスを動的に生成しなければならない。

2. 存在しない設定ファイル・不正なJSONへの耐性

ファイルが消されていたり、JSONの構文ミス(カンマの付け忘れなど)があった場合、ツールが容赦なく「実行時エラー」でクラッシュしては業務ツールとして失格だ。必ずエラーハンドリングを挟み、日本語で的確なアラートを出すか、フォールバック値を返す設計にすること。

プロダクションコード:JSON設定読込クラスの全貌

それでは、実務の現場でそのままコピー&ペーストして使える実装コードを公開しよう。

今回は、設定ファイルをカレントディレクトリにある `config.json` と仮定し、それを読み込んでメモリ上に保持、任意のキーで値を取り出せるクラスモジュール(例:`ConfigManager`)を作成する。

準備するJSONファイル (`config.json`)

Excelブックと同じ階層に、以下の内容でUTF-8(またはANSI)のJSONファイルを配置してほしい。

{
“Environment”: “Production”,
“TimeoutSeconds”: 30,
“ApiEndpoint”: “https://api.example.com/v1/process”,
“ExportDirectory”: “C:\\Reports\\Output\\”,
“Notification”: {
“Enabled”: true,
“Email”: “admin@example.com”
}
}

VBAコード:クラスモジュール `ConfigManager`

VBEを開き、新しいクラスモジュールを追加して名前を `ConfigManager` に変更し、以下のコードを貼り付けてくれ。

Option Explicit

‘ =================================================================
‘ クラス名: ConfigManager
‘ 概要: JSON設定ファイルを読み込み、VBAから安全に値を取得するマネージャー
‘ =================================================================

Private pConfigObj As Object ‘ JScriptオブジェクトとしてパースしたJSONを保持
Private pIsLoaded As Boolean

‘ 初期化処理:JSONファイルを読み込んでパースする
Public Function Initialize(Optional ByVal FileName As String = “config.json”) As Boolean
On Error GoTo ErrorHandler

Dim fso As Object
Dim ts As Object
Dim jsonText As String
Dim filePath As String

pIsLoaded = False

‘ 1. ブックのパスを基準とした絶対パスを生成(カレントディレクトリ依存のバグを防ぐ)
filePath = ThisWorkbook.Path & “\” & FileName

‘ 2. ファイル存在チェック
Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FileExists(filePath) Then
Err.Raise vbObjectError + 1000, “ConfigManager”, “設定ファイルが見つかりません: ” & vbCrLf & filePath
End If

‘ 3. テキストファイルとして読み込み(文字コードShift-JIS/UTF-8対応)
‘ ※環境に合わせてOpenTextFileの引数(Tristate等)は調整してください
Set ts = fso.OpenTextFile(filePath, 1, False)
jsonText = ts.ReadAll
ts.Close

‘ 4. ScriptControl (JScript) を使ってJSONをオブジェクト化
‘ ※注意: 64bit Excel環境ではScriptControlが動作しない場合があります。
‘ その場合はVBA-JSON等の外部ライブラリに差し替えてください。
Dim sc As Object
Set sc = CreateObject(“MSScriptControl.ScriptControl”)
sc.Language = “JScript”

‘ JScriptで安全にパースするために括弧で囲む
Set pConfigObj = sc.Eval(“(” + jsonText + “)”)

pIsLoaded = True
Initialize = True
Exit Function

ErrorHandler:
MsgBox “設定ファイルの読み込みに失敗しました。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “致命的なエラー”
Initialize = False
End Function

‘ 設定値取得メソッド(文字列)
Public Function GetString(ByVal Key As String, Optional ByVal DefaultValue As String = “”) As String
If Not pIsLoaded Then
GetString = DefaultValue
Exit Function
End If

On Error GoTo SafeExit
‘ ドット区切り(例: “Notification.Email”)の階層アクセスはScriptControlなら直接可能
Dim val As Variant
val = CallByName(pConfigObj, Key, VbGet)

If IsNull(val) Or IsEmpty(val) Then
GetString = DefaultValue
Else
GetString = CStr(val)
End If
Exit Function

SafeExit:
GetString = DefaultValue
End Function

‘ 設定値取得メソッド(数値)
Public Function GetLong(ByVal Key As String, Optional ByVal DefaultValue As Long = 0) As Long
Dim val As String
val = GetString(Key, “”)
If IsNumeric(val) Then
GetLong = CLng(val)
Else
GetLong = DefaultValue
End If
End Function

‘ 設定値取得メソッド(真偽値)
Public Function GetBoolean(ByVal Key As String, Optional ByVal DefaultValue As Boolean = False) As Boolean
Dim val As String
val = LCase(GetString(Key, “”))
If val = “true” Then
GetBoolean = True
ElseIf val = “false” Then
GetBoolean = False
Else
GetBoolean = DefaultValue
End If
End Function

呼び出し側(標準モジュール)の実装

上記で作成したクラスモジュールを、実際の業務処理からどのように呼び出すかを見てみよう。標準モジュールに以下のように記述する。

Option Explicit

Sub MainProcess()
‘ 設定マネージャーのインスタンス化
Dim config As ConfigManager
Set config = New ConfigManager

‘ 設定ファイルをロード(失敗時は処理を中断)
If Not config.Initialize(“config.json”) Then Exit Sub

‘ 各種設定値を型安全に取得
Dim env As String
Dim timeout As Long
Dim endpoint As String
Dim isNotifyEnabled As Boolean

env = config.GetString(“Environment”, “Development”)
timeout = config.GetLong(“TimeoutSeconds”, 10)
endpoint = config.GetString(“ApiEndpoint”, “”)
isNotifyEnabled = config.GetBoolean(“Notification.Enabled”, False)

‘ 【デバッグ出力】取得した設定値の確認
Debug.Print “— 設定読込完了 —”
Debug.Print “実行環境: ” & env
Debug.Print “タイムアウト: ” & timeout & “秒”
Debug.Print “APIエンドポイント: ” & endpoint
Debug.Print “通知機能有効: ” & isNotifyEnabled

‘ — ここから実際の業務ロジックを展開 —
‘ 例: If env = “Production” Then …

MsgBox “設定ファイルの読み込みと値の取得に成功しました!”, vbInformation, “完了”
End Sub

アーキテクトからの実践的なアドバイスと注意点

1. 64bit Excel環境における `ScriptControl` の制約

今回のコードで使用した `MSScriptControl.ScriptControl` は、32bit版のWindowsコンポーネントであるため、64bit版のExcel環境では動作しない(アクティブ化エラーになる)ケースがある。
もし社内のPCが64bit版Officeで統一されている場合、あるいは将来的な互換性を担保したい場合は、GitHub等で公開されている純粋なVBA製JSONパーサー(例: `VBA-JSON`)にパース部分を差し替えるのが、プロとしての正しい選択だ。設計の枠組み(クラス化して外部から値を取り出すインターフェース)さえ変えなければ、内部のパーサーの変更など容易いことである。

2. コードの「保守性」という最大の果実

このように設定をコードから切り離すことで、以下のメリットが爆発的に向上する。

  • デプロイの簡素化: 本番環境へ移行する際、Excelファイル(xlsm)を差し替えることなく、`config.json` のテキストを書き換えるだけで環境スイッチが可能になる。
  • 非エンジニアへの委譲: 運用担当者がJSONの書式さえ分かっていれば、VBAのコードを一文字も触ることなく設定(メールアドレスや保存先パス)を変更できる。

結び

ハードコーディングされたVBAマクロは、作成者の「技術的な負債」となり、やがて組織全体の足かせとなる。
コードの美しさと堅牢性は、適切な設計思想からしか生まれない。今回紹介した外部設定管理の手法を君たちのツールに組み込み、ワンランク上の「エンジニアリングとしてのVBA」をぜひ体感してほしい。

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