【ExcelVBA・マクロ】Property Get/Let/Setの使い方|クラスモジュールで独自プロパティを作る方法【コピペOK】

ExcelVBA

ExcelVBAでクラスモジュールを使い始めると、必ずぶつかるのが「プロパティをどうやって自作するのか」という疑問です。変数をPublicで宣言するだけでも値の出し入れはできますが、それでは「不正な値が入ってきてもチェックできない」「読み取り専用にできない」といった問題が残ります。

この記事では、Property GetProperty LetProperty Setという3つのプロシージャを使って、クラスモジュールに独自のプロパティを作る方法を解説します。入力値のチェックや読み取り専用プロパティの作り方まで、実際に動くコード例を交えて紹介します。

スポンサーリンク
スポンサーリンク

Property Get/Let/Setとは何か

クラスモジュールでは、外部から直接変数を触らせるのではなく、Propertyプロシージャを経由してデータをやり取りするのが基本です。役割は次の3つに分かれています。

  • Property Get:プロパティの値を「取得」するときに呼ばれる
  • Property Let:プロパティに「値(データ型)」を「設定」するときに呼ばれる
  • Property Set:プロパティに「オブジェクト」を「設定」するときに呼ばれる

このように分けることで、値を読み取るときと書き込むときで別々の処理(チェックやログなど)を挟めるようになります。

基本のProperty Get/Letを作る

クラスモジュール「Employee」を例に、名前と給与を管理するプロパティを作ってみます。クラスモジュールの挿入方法は、VBEの「挿入」→「クラスモジュール」から行い、プロパティウィンドウで名前を「Employee」に変更してください。

' クラスモジュール「Employee」

Option Explicit

Private mName As String
Private mSalary As Long

Public Property Get Name() As String
    Name = mName
End Property

Public Property Let Name(ByVal NewValue As String)
    mName = NewValue
End Property

Public Property Get Salary() As Long
    Salary = mSalary
End Property

Public Property Let Salary(ByVal NewValue As Long)
    If NewValue < 0 Then
        MsgBox "給与にマイナスの値は設定できません。"
        Exit Property
    End If
    mSalary = NewValue
End Property

ポイントは、実体となる変数(mNamemSalary)をPrivateで宣言し、外部からはPropertyプロシージャを通してのみアクセスできるようにしている点です。SalaryProperty Letでは、マイナスの値が渡されたときに処理を中断するチェックを入れています。こうすることで、不正な値がそのまま代入されるのを防げます。

標準モジュールから呼び出すコードは次の通りです。

Sub TestEmployee()
    Dim emp As Employee
    Set emp = New Employee

    emp.Name = "山田太郎"
    emp.Salary = 300000

    MsgBox emp.Name & "さんの給与は" & emp.Salary & "円です。"

    emp.Salary = -1000  ' チェックに引っかかりMsgBoxが表示される
End Sub

読み取り専用プロパティを作る

Property Letを用意しなければ、そのプロパティは「読み取り専用」になります。たとえば、社員IDのように一度決まったら変更されたくない値は、Property Getだけを定義します。

Private mEmployeeId As String

Public Property Get EmployeeId() As String
    EmployeeId = mEmployeeId
End Property

Public Sub Initialize(ByVal NewId As String)
    mEmployeeId = NewId
End Sub

この場合、emp.EmployeeId = "E001"のように外部から直接代入しようとするとコンパイルエラーになります。値をセットするにはInitializeのような別のメソッドを用意し、生成時に一度だけ設定する形にすると安全です。

Property Setでオブジェクトを扱う

Property Letは文字列や数値などの「値」を受け取るのに対し、Property SetRangeWorksheetといった「オブジェクト」を受け取るときに使います。

Private mTargetRange As Range

Public Property Get TargetRange() As Range
    Set TargetRange = mTargetRange
End Property

Public Property Set TargetRange(ByVal NewRange As Range)
    Set mTargetRange = NewRange
End Property

呼び出す側では、オブジェクトを代入するためSetキーワードが必要になります。

Sub TestTargetRange()
    Dim emp As Employee
    Set emp = New Employee

    Set emp.TargetRange = Worksheets("Sheet1").Range("A1:A10")

    MsgBox emp.TargetRange.Address
End Sub

Property Get側でもTargetRange = mTargetRangeではなくSet TargetRange = mTargetRangeと書く点に注意してください。オブジェクトを返すプロパティは、Get側もSetが必要です。

まとめ

Property Get/Let/Setを使うことで、クラスモジュールに「安全な入り口」を作ることができます。

  • Property Get:値・オブジェクトを取得する
  • Property Let:値(数値・文字列など)を設定する
  • Property Set:オブジェクト(Range・Worksheetなど)を設定する
  • Property Letを省略すれば読み取り専用プロパティになる

単にPublic変数を並べるよりも一手間かかりますが、入力値のチェックを挟められる、読み取り専用にできるといったメリットは大きいです。自作クラスを設計する際は、まずどのプロパティが「読み書き両方必要か」「読み取り専用でよいか」を整理してから、Property プロシージャを組み立てていくとスムーズです。

スポンサーリンク
スポンサーリンク
ExcelVBA
シェアする
いがぴをフォローする

コメント

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