【入門編】クラスモジュールにおけるPrivate変数のカプセル化とPropertyプロシージャの役割 – Excel VBA解析バイブル

スポンサーリンク

こんにちは!マクロの記録を卒業し、「そろそろ本格的なプログラムを書きたい!」と一歩を踏み出したあなたへ。

今回は、Excel VBAを一段上のレベルへ引き上げるための超重要テーマ「クラスモジュールにおけるカプセル化とPropertyプロシージャ」についてお話しします。

ここをクリアすれば、あなたも「ただ動くコードを書く人」から「保守性の高い美しいコードを書くエンジニア」へ仲間入りです。優しく、そして本質的なところまでしっかりと解説していきますね。ここをクリアすれば、Excel VBAの基本はバッチリですよ!

1. なぜ「普通の変数」だけでは物足りないのか?

Excel VBAで標準モジュール(`Module1`など)を使っているとき、こんな風に変数を宣言していませんか?

Public Age As Long ‘ パブリック変数

これ、どこからでも読み書きできて一見便利ですよね。でも、実務や少し大きなプログラムになると、これが「バグの温床」になります。

  • どこかのコードでうっかり `Age = -99` とマイナスの値を代入してしまった。
  • 別の場所で勝手に `Age = 1000` と書き換えられていた。

「誰が、どこで、いつこの変数を書き換えたんだ…?」と頭を抱えた経験はありませんか?これを防ぐのが、今回学ぶ「カプセル化(Encapsulation)」という概念です。

カプセル化とは?

一言で言うと、「変数を外の世界から隠し、信頼できる専用の窓口(プロシージャ)を通してのみ操作させること」です。カプセル剤をイメージしてください。中の苦い薬(データ)が飛び出さないように、しっかりコーティングされていますよね。アレです。

2. クラスモジュールとPropertyプロシージャの基本

VBAでカプセル化を実現するために登場するのが「クラスモジュール」です。そして、そのクラスの中にある変数と外の世界を繋ぐのが`Property`(プロパティ)プロシージャです。

Propertyには用途に応じて3つの種類があります。

1. `Property Get`:外から値を「読み取る」とき
2. `Property Let`:外から値(数値や文字列など)を「代入する」とき
3. `Property Set`:外から「オブジェクト(ワークシートやrangeなど)」を「代入する」とき

図解風にイメージしてみましょう。

[ 呼び出し側のコード (標準モジュールなど) ]

├─ (代入: Let) ──> [ Property Let 窓口 ] ──> 【不正値チェック!】 ──> [ Private 変数 (隠しデータ) ]

└─ (取得: Get) <── [ Property Get 窓口 ] <────────────────────────┘ 直接変数を触らせず、必ず「窓口(Property)」を通すことで、「おっと、年齢にマイナスは入れさせないよ!」といったガード(バリデーション)を挟むことができるようになります。

3. 実践!安全な「社員クラス」を作ってみよう

百聞は一見にしかず。実際にコードを書いてその動きを体感してみましょう。

手順1:クラスモジュールの挿入と名前の変更

1. VBE(Visual Basic Editor)を開きます。
2. メニューの「挿入」>「クラス モジュール」をクリックします。
3. プロパティウィンドウ(左下)で、このクラスの`(名称)`を `clsEmployee` に変更します。

手順2:クラスモジュールにコードを書く

以下のコードを `clsEmployee` の中にそのまま貼り付けてください。

Option Explicit

‘ 【カプセル化】プライベート変数(外からは直接触れない)
Private m_Name As String
Private m_Age As Long

‘ ==========================================
‘ 1. Nameプロパティ(読み書き用)
‘ ==========================================

‘ 読み取り (Get)
Public Property Get EmployeeName() As String
EmployeeName = m_Name
End Property

‘ 書き込み (Let)
Public Property Let EmployeeName(ByVal Value As String)
‘ 空文字チェックなどのガードを入れられる!
If Trim(Value) = “” Then
MsgBox “エラー: 名前を空にすることはできません。”, vbCritical
Exit Property
End If
m_Name = Value
End Property

‘ ==========================================
‘ 2. Ageプロパティ(年齢:不正値ガード付き)
‘ ==========================================

‘ 読み取り (Get)
Public Property Get Age() As Long
Age = m_Age
End Property

‘ 書き込み (Let)
Public Property Let Age(ByVal Value As Long)
‘ 【重要】不自然な値が入るのをここでブロック!
If Value < 0 Or Value > 120 Then
MsgBox “エラー: 年齢は0から120の間で指定してください。(入力値: ” & Value & “)”, vbCritical
Exit Property
End If

m_Age = Value
End Property

コメント解説:

  • `Private m_Name` のように、プライベート変数には慣習として `m_`(memberのm)を付けることが多いです。これにより「これはクラス内部だけの変数だ」と一目で分かります。
  • `Property Let` の引数 `Value` には、外から渡された値が格納されます。ここに `If` 文を書くことで、データの品質を完全にコントロールできます。

手順3:標準モジュールから呼び出してテストする

次に、通常の標準モジュール(`Module1`など)を挿入し、以下のコードを書いて実行してみましょう。

Option Explicit

Sub TestEmployeeClass()
‘ クラスのインスタンス(実体)を生成
Dim emp As clsEmployee
Set emp = New clsEmployee

‘ 正常な値を代入
emp.EmployeeName = “山田 太郎”
emp.Age = 30

‘ 値を出力してみる
Debug.Print “社員名: ” & emp.EmployeeName
Debug.Print “年齢: ” & emp.Age & “歳”

‘ ————————————
‘ 【実験】不正な値を代入してみよう!
‘ ————————————
MsgBox “次に、不正な年齢(150歳)を代入してみます。”, vbInformation
emp.Age = 150 ‘ ここでProperty Letのガードが発動します!

‘ 不正な値が弾かれているか確認(年齢は変わっていないはず)
Debug.Print “ガード後の年齢: ” & emp.Age & “歳”

‘ メモリの解放
Set emp = Nothing
End Sub

これを実行すると、150歳を代入しようとした瞬間にメッセージボックスでエラーが通知され、内部の `m_Age` は書き換えられずに無事保護されます。これがカプセル化の真骨頂です!

4. 陥りやすい罠・エラーと対策

初心者のうちは、Propertyプロシージャを書くときにいくつかハマりがちなポイントがあります。

罠1:Let と Set の使い所を間違える

  • `Property Let` は、数値、文字列、Booleanなどのプリミティブ型(値型)用です。
  • `Property Set` は、ワークシートや別のクラスなどのオブジェクト型用です。
  • エラーの例:オブジェクトを代入するのに `Property Let` を使ってしまうと、「オブジェクトが必要です」というコンパイルエラー(または実行時エラー)になります。オブジェクトのときは必ず `Set` を使いましょう。

罠2:Read-Only(読み取り専用)にしたいのに Let を書いてしまう

「外から変数を変えられたくない(でも読むことは許可したい)」という場合は、`Property Let`(または Set)を書かなければ自動的に読み取り専用になります。

‘ 読み取り専用プロパティの例(IDなど途中で変えたくないもの)
Private m_ID As String

Public Property Get ID() As String
ID = m_ID
End Property
‘ ※ Property Let ID はあえて作らない!

これによって、外部から `emp.ID = “002”` のように書き換えようとすると、「代入式の左辺には、Let または Set プロシージャを割り当てることはできません」というエラーになり、データの安全性が保たれます。

まとめ

いかがでしたでしょうか?

クラスモジュールとPropertyプロシージャを使いこなせるようになると、VBAのコードは劇的に美しく、そして強靭になります。

  • 変数は隠す(`Private`)
  • 窓口を通す(`Property Get / Let / Set`)
  • 窓口で番人が不正を防ぐ(バリデーション)

この3つのルールを守るだけで、あなたの書くプログラムの信頼性はプロのレベルへと一気に引き上げられます。ぜひ今日の業務から、マクロの記録の次のステップとしてクラスモジュールを取り入れてみてくださいね。

あなたのVBAライフが、より快適で創造的なものになりますように!

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