こんにちは!VBAのスキルを次のステップへ引き上げたいあなたへ。
マクロの記録から脱却し、自分でゼロから美しいコードが書けるようになると、Excel仕事の世界がガラリと変わりますよね。
さて、コードを書く量が増えてくると、こんな悩みに出会いませんか?
「あっちの標準モジュールでも、こっちのシートのコードでも、同じ『消費税率』や『ファイル保存パス』を何度も書いているな……。どこか一箇所でまとめて管理できないだろうか?」
ここで多くの人が飛びついてしまうのが、`Public Const` や `Public` 変数による「グローバル定数(どこからでも触れる変数)」の乱用です。しかし、実はこれ、大規模なVBA開発において「絶対に避けるべきアンチパターン(やってはいけない設計)」の一つなのです。
今回は、プロの現場でも使われる「設定用クラス(読み取り専用プロパティ)」を使った、美しく安全な定数の共有テクニックを一緒にマスターしていきましょう!ここをクリアすれば、あなたのVBAコードの設計力は一気に一流エンジニアの領域に近づきますよ。
—
1. なぜ `Public Const` の乱用は危険なのか?
まずは、なぜ「どこからでも書き換えられる変数」や「どこからでも参照できるパブリックな定数」がダメなのか、その理由を知ることから始めましょう。
例えば、標準モジュールにこんなコードを書いたとします。
‘ 標準モジュール: Module1
Public Const TAX_RATE As Double = 0.1
Public OUTPUT_PATH As String = “C:\Work\”
一見、便利に見えますよね。しかし、ここには恐ろしい罠があります。
1. どこで値が変更されたか追えなくなる(特に `Public` 変数の場合)
知らず知らずのうちに、別のプロシージャから `OUTPUT_PATH` を書き換えられてしまい、気づいた時にはバグの温床に……。
2. 「名前の衝突(名前被り)」が起きやすい
プロジェクト全体で名前が共有されるため、うっかり同じ名前の定数を別の場所で定義してしまい、コンパイルエラーや予期せぬ挙動を引き起こします。
3. 依存関係がグチャグチャになる(密結合)
どこからでも中身を覗き見できる状態は、コードの「見通し」を最悪にします。
「定数だから書き換わらないはず……」と思っていても、アプリが大きくなるにつれて、管理不能なスパゲッティコード(絡み合ったコード)へと変貌していくのです。
—
2. 解決策:「設定用クラス」という名の安全地帯
そこで登場するのが、今回の主役である「設定用クラス」です。
オブジェクト指向の考え方を少しだけ借りて、「設定値はクラスの中に閉じ込め、外からは『見るだけ(読み取り専用)』にする」という仕組みを作ります。
イメージ図で表すと、このような関係性です。
[ 呼び出し側 (標準モジュールなど) ]
│
▼ (値を取り出すだけ。書き換えは絶対にできない!)
[ 設定用クラス (ClsAppConfig) ]
├─ Get TaxRate() -> 0.1
└─ Get OutputPath() -> “C:\Work\”
これなら、値の提供者はクラスだけであり、外部からは「読むこと」しかできません。安全性が圧倒的に高まりますよね。
—
3. 実践!設定用クラスを作ってみよう
それでは、実際に手を動かして実装してみましょう。
今回は、消費税率とファイル保存先のパスを管理する「設定用クラス」を作ります。
ステップ1:クラスモジュールの挿入と名前の変更
1. VBE(Visual Basic Editor)を開きます。
2. メニューの `[挿入]` > `[クラス モジュール]` をクリックします。
3. プロパティウィンドウ(F4キー)で、このクラスの `Name` プロパティを `ClsAppConfig` に変更します。
ステップ2:クラスモジュールにコードを書く
新しくできた `ClsAppConfig` の中に、以下のコードを貼り付けてください。
‘ ==========================================
‘ クラスモジュール名: ClsAppConfig
‘ 概要: アプリケーション全体の設定値を管理するクラス
‘ ==========================================
Option Explicit
‘ 内部で保持するプライベートな変数(外部からは直接触れません)
Private pTaxRate As Double
Private pOutputPath As String
‘ クラスがインスタンス化されたときに初期値を設定する
Private Sub Class_Initialize()
‘ ここに設定値を集約します!
pTaxRate = 0.10
pOutputPath = “C:\ExcelData\Output\”
End Sub
‘ — 読み取り専用プロパティ (Property Get) —
‘ 消費税率を取得するプロパティ
Public Property Get TaxRate() As Double
TaxRate = pTaxRate
End Property
‘ 出力パスを取得するプロパティ
Public Property Get OutputPath() As String
OutputPath = pOutputPath
End Property
💡 ここがポイント!
- `Private pTaxRate`:クラスの外から絶対に触れない「隠し金庫」のような変数です。
- `Class_Initialize`:このクラスが呼び出された瞬間に自動で実行される特別なプロシージャです。ここで初期値をセットします。
- `Property Get`:外から値を取り出すための専用窓口です。「Get」しか用意しない(Property Let/Setを作らない)ことで、「外からは絶対に書き換えられない(読み取り専用)」という鉄壁の守りを実現しています。
—
ステップ3:標準モジュールから呼び出してみる
次に、普段の処理を書く標準モジュール(例:`Module1`)を用意し、先ほどのクラスを使ってみましょう。
‘ ==========================================
‘ 標準モジュール名: Module1
‘ 概要: クラスから設定値を安全に呼び出す例
‘ ==========================================
Option Explicit
Sub MainProcess()
‘ 1. 設定用クラスをメモリ上に召喚(インスタンス化)します
Dim config As ClsAppConfig
Set config = New ClsAppConfig
‘ 2. クラスから安全に設定値を取り出して使う
MsgBox “現在の消費税率は ” & (config.TaxRate 100) & “% です。” & vbCrLf & _
“保存先フォルダ: ” & config.OutputPath, _
vbInformation, “設定値の確認”
‘ ※もしここで config.TaxRate = 0.08 のように書き換えようとすると、
‘ 「不正なプロパティの割り当てです」というコンパイルエラーになり、
‘ うっかりミスを未然に防いでくれます!
‘ 3. 使い終わったらメモリを解放(お行儀よく後片付け)
Set config = Nothing
End Sub
このコードを実行してみてください。クラス経由で値が綺麗に取得でき、かつ、外部から書き換えようとするとVBAがしっかり止めてくれることが実感できるはずです。
—
4. 現場で役立つ応用テクニック:シートから設定を読み込む
「コードの中に直接 `0.1` とか書くのもイヤだな。Excelシート(たとえば『設定』シート)のセルから読み込めるようにしたい!」
実務では、そう思うことがほとんどですよね。
安心してください。先ほどの `Class_Initialize` の中身を少し書き換えるだけで、Excelシートの設定値を自動で読み込むクラスに進化させることができます。
Private Sub Class_Initialize()
On Error GoTo ErrorHandler
‘ 「設定」シートのセルから値を取得する
‘ A1セルに消費税率、A2セルに保存パスが入力されている想定
pTaxRate = ThisWorkbook.Sheets(“設定”).Range(“A1”).Value
pOutputPath = ThisWorkbook.Sheets(“設定”).Range(“A2”).Value
Exit Sub
ErrorHandler:
‘ 万が一シートが見つからない場合のフォールバック(初期値)
pTaxRate = 0.1
pOutputPath = “C:\DefaultPath\”
MsgBox “設定シートの読み込みに失敗しました。デフォルト値を使用します。”, vbExclamation
End Sub
このように設計しておけば、呼び出し側のコード(`Module1`など)は一切変更する必要がありません。これが、「モジュール間の結合度を低くする(疎結合)」というプログラミングの醍醐味です。
—
まとめ:今回の極限知見
- `Public Const` やグローバル変数の乱用は、バグの温床になるので今すぐやめよう。
- 設定値は「設定用クラス」に閉じ込め、`Property Get` を使って「読み取り専用」で公開する。
- クラスを使うことで、値の初期化やシートからの読み込みロジックを1箇所に集約でき、保守性が劇的に向上する。
「マクロの記録」から一歩進んだあなたなら、このクラス設計を取り入れることで、他の人が書くVBAとは一味違う「頑丈で美しいコード」を書くことができるはずです。
ぜひ、あなたの次のVBA開発でこの「設定用クラス」を取り入れてみてくださいね。ここをクリアしたあなたなら、もう中級者の扉は完全に開いていますよ!
