脱・グローバル変数:設定用クラスモジュールによる「VBAの健全な設計」のススメ
業務自動化ツールを開発していると、必ず突き当たる壁がある。それは「定数や設定値の管理」だ。
「とりあえず標準モジュールに `Public Const` を並べておけばいい」
そう考えているなら、今すぐその設計を捨ててほしい。その安易な実装が、将来あなたのツールを「修正するたびにバグが連鎖する、誰も触りたくないレガシーコード」へと変貌させるからだ。
今回は、グローバル変数の汚染を防ぎ、保守性を劇的に向上させる「設定用クラスモジュール」という設計パターンを授ける。
—
1. なぜ Public Const の乱用は「悪」なのか
標準モジュールでの `Public` 宣言は、名前の通り「どこからでもアクセスできる」という強力な武器だが、同時に「どこで変更されたか(あるいは意図せず書き換えられたか)追跡不能」という致命的な弱点を持つ。
- 依存関係の不可視化: どのモジュールがどの定数に依存しているか分からなくなる。
- 名前空間の衝突: プロジェクトが肥大化すると、名前の重複や管理ミスが多発する。
- テストの困難さ: 単体テストを行う際、外部の設定値を動的に切り替えることができない。
プロのアーキテクトにとって、コードは「書くこと」よりも「読み解くこと」が重要だ。「どこに何があるか」を明確に定義し、アクセスを制御する。 これが堅牢なツールの絶対条件である。
—
2. 解決策:Settingsクラスによる「設定の集中管理」
解決策はシンプルだ。設定値や定数を「インスタンス化されたクラス」として管理する。これにより、設定値は「グローバルな汚染源」から「制御されたオブジェクト」へと昇華する。
実践:Configクラスの実装
まずは、プロジェクトの「設定項目」を保持するための `Config` クラスモジュールを作成しよう。
‘ クラスモジュール名: Config
Option Explicit
‘ 読み取り専用のプロパティとして定義(Property Getのみ)
‘ 直接書き換えを防ぐため、内部変数(m_)を隠蔽する
Private m_DbPath As String
Private m_MaxRetryCount As Long
‘ コンストラクタ(初期化処理)
Private Sub Class_Initialize()
‘ ここでファイルやDBから設定を読み込む
‘ 外部ファイル(JSONやini)から読み込む構造にするとさらに強力
m_DbPath = ThisWorkbook.Path & “\data\master.accdb”
m_MaxRetryCount = 3
End Sub
‘ プロパティ定義
Public Property Get DbPath() As String
DbPath = m_DbPath
End Property
Public Property Get MaxRetryCount() As Long
MaxRetryCount = m_MaxRetryCount
End Property
—
3. 利用側(メイン処理)のスマートな書き方
このクラスを利用する側は、以下のように記述する。
‘ 標準モジュールでの利用例
Sub MainProcess()
‘ 設定クラスをインスタンス化
Dim cfg As New Config
‘ プロパティとして安全にアクセス
Debug.Print “接続先: ” & cfg.DbPath
‘ 以下、処理の呼び出し
Call ExecuteTask(cfg)
End Sub
Sub ExecuteTask(ByRef cfg As Config)
‘ 必要な設定だけを渡すことで、依存関係が明確になる
If cfg.MaxRetryCount > 0 Then
‘ 処理ロジック
End If
End Sub
—
4. プロの視点:この設計がもたらす「3つの恩恵」
このパターンを採用すると、単にコードが綺麗になるだけではない。
1. 動的な環境切り替え: `Class_Initialize` 内のロジックを変えるだけで、本番環境と開発環境の設定を自動的に切り替えられる。`#If` プリプロセッサ地獄から解放されるのだ。
2. 型安全性の担保: 全てが `Variant` になりがちなVBAにおいて、クラスのプロパティを介することで型が強制される。これはバグの温床を未然に潰す強力な防波堤となる。
3. IntelliSenseの恩恵: `cfg.` と打てば設定項目がリストアップされる。ドキュメントを読み返す時間は不要だ。
—
5. 最後に:設計は「未来への投資」である
「小さなツールだから、そこまでしなくても……」と言う者がいる。しかし、優れたエンジニアは、たとえ小さなツールであっても「拡張されること」を前提に設計する。
今日書いた `Public Const` の1行が、1年後の自分を苦しめる負債になるかもしれない。もしあなたがチームの生産性を上げたいと願うなら、今すぐ `Public` 宣言を削除し、クラスモジュールによる管理へと舵を切ってほしい。
コードの品質は、あなたが「妥協しない」と決めた瞬間から向上する。健闘を祈る。
