はじめに
VBAのクラスモジュールでオブジェクトを作成する際、そのオブジェクトの「データ(属性)」を外部から安全に操作するための窓口となるのが「プロパティ」です。
プロパティを適切に定義することで、以下のような高度な制御が可能になります。
- 値の検証: 不正な値(例: マイナスの価格)が設定されるのを防ぐ。
 - 読み取り専用プロパティ: 内部で計算した結果(例: 税込価格)を、変更不可能な値として外部に提供する。
 - オブジェクトの格納: 
ShapeやRangeなどのオブジェクトをプロパティとして保持する。 
この記事では、VBAクラスの核心機能である Property Let, Property Get, Property Set の使い方を、具体的な例を交えて徹底解説します。
1. 値を扱う Property Let と Property Get
StringやLong、Currencyといった「値」を扱うプロパティには、Let(書き込み)とGet(読み取り)を使います。
Property Let: 外部からオブジェクト.プロパティ = 値の形で値が書き込まれるときに実行されます。Property Get: 外部から変数 = オブジェクト.プロパティの形で値が読み取られるときに実行されます。
クラスモジュール: ClsProduct のコード例
' --- 内部データを保持するプライベート変数 ---
Private p_UnitPrice As Currency
' --- UnitPriceプロパティ ---
' [書き込み用] UnitPriceプロパティに値が設定されるときに呼ばれる
Public Property Let UnitPrice(value As Currency)
    ' 値の検証: 0未満の値が設定されそうになったら、0にする
    If value < 0 Then
        p_UnitPrice = 0
    Else
        p_UnitPrice = value
    End If
End Property
' [読み取り用] UnitPriceプロパティの値が参照されるときに呼ばれる
Public Property Get UnitPrice() As Currency
    UnitPrice = p_UnitPrice
End Property
標準モジュールでの使い方
Sub Test_Let_Get()
    Dim item As New ClsProduct
    
    ' Property Let が呼ばれる
    item.UnitPrice = -500
    
    ' Property Get が呼ばれる
    ' 不正な値-500は検証ロジックで0に変換されている
    Debug.Print "単価: " & item.UnitPrice ' -> イミディエイトウィンドウに「単価: 0」と表示
End Sub
この例では、Property Let の中で、設定されようとしている値 (value) がマイナスでないかをチェックする「バリデーション(値の検証)」ロジックを入れています。これにより、このオブジェクトの単価がマイナスになることを防ぎ、データの整合性を保っています。
2. オブジェクトを扱う Property Set
RangeやWorksheet、Shapeといった「オブジェクト」をプロパティとして扱う場合は、Letの代わりに Set を使います。
Property Set: 外部からSet オブジェクト.プロパティ = オブジェクトの形でオブジェクトがセットされるときに実行されます。
クラスモジュール: ClsProduct のコード例(追加)
' --- 内部データを保持するプライベート変数(追加) ---
Private p_LinkedShape As Shape
' --- LinkedShapeプロパティ(オブジェクト用) ---
' [書き込み用] LinkedShapeプロパティにオブジェクトが設定されるときに呼ばれる
Public Property Set LinkedShape(value As Shape)
    Set p_LinkedShape = value
End Property
標準モジュールでの使い方
Sub Test_Set()
    Dim item As New ClsProduct
    ' Property Set が呼ばれる
    Set item.LinkedShape = ActiveSheet.Shapes(1)
End Sub
3. 読み取り専用のプロパティ
Property Get だけを定義し、Property Let や Property Set を定義しないことで、「読み取り専用」のプロパティを作成できます。これは、内部データから計算される値(例: 税込価格)を提供する場合に非常に便利です。
クラスモジュール: ClsProduct のコード例(追加)
' --- PriceWithTaxプロパティ(読み取り専用) ---
' [読み取り専用] PriceWithTaxプロパティが参照されると、計算結果を返す
Public Property Get PriceWithTax() As Currency
    Const TAX_RATE As Double = 0.1
    PriceWithTax = Round(p_UnitPrice * (1 + TAX_RATE))
End Property
標準モジュールでの使い方
Sub Test_ReadOnly()
    Dim item As New ClsProduct
    item.UnitPrice = 1000
    
    ' Property Get が呼ばれる
    Debug.Print "税込価格: " & item.PriceWithTax ' -> 「税込価格: 1100」と表示
    
    ' 下記のコードはコンパイルエラーになる(書き込みが許可されていないため)
    ' item.PriceWithTax = 1200
End Sub
まとめ
今回は、VBAクラスのプロパティを定義するための Property Let, Get, Set の使い方を解説しました。
- 値の読み書きには 
Property LetとProperty Get - オブジェクトの読み書きには 
Property SetとProperty Get Property Getだけを定義すれば、読み取り専用プロパティになるProperty Let/Set内にバリデーションロジックを組み込むことで、データの整合性を高められる
プロパティを正しく使いこなすことは、カプセル化を実現し、安全で再利用性の高いオブジェクトを作成するための鍵となります。
