Property Let と Set の違い

にメンテナンス済み

VBA でクラスを作成し、 プロパティ(メンバー変数) を取り扱う際に作成する Property メソッドには Get, Set, Let があります。

一般的に、VBA 以外の言語では、プロパティ(メンバー変数)に設定するのは Getter と Setter のみです。

そのため、VBA での プロパティの定義を初めて見た時違和感を覚える方もいらっしゃるかと思います。

今回は VBA の Property Set と Property Let の違いについてまとめます。

Property Set と Property Let の違い

結論を言ってしまうと、

  • 変数の代入時に Set が必要なものは Set
  • それ以外は Let

この認識で問題ないかと思います。

解説

参照型の変数に値を代入する際は、Set を付けないとエラーとなります。

ワークシートで言えば、

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)

といった場合です。

これはクラスにおける Property でも、同様のことが言えます。

クラスのプロパティに値をセットしたいとき、

' Class1 モジュール

Private m_ws As Worksheet

' Worksheetクラスは参照型なので、Setで定義
Public Property Set ws(ByRef received As Worksheet)

    ' プロパティに設定する場合もSetが必要
    Set m_ws = received
End Property
' 標準モジュール

Dim c1 As Class1
Set c1 = New Class1

' 呼び出した先でもSetが必要
Set c1.ws = ThisWorkbook.Worksheets(1)

一つでも Set がないとエラーとなってしまいます。

とても面倒ですが、**VBA では変数定義時の Set の概念が、Property にも適用されている。**と理解していただいて差支えないかと思います。

実行テスト

' Class1 モジュール
Private m_ws As Worksheet

Public Property Set ws(ByRef received As Worksheet)
    Set m_ws = received
End Property

Public Property Get ws() As Worksheet
    Set ws = m_ws
End Property
' 標準モジュール

Public Sub test()

    Dim c1 As Class1
    Set c1 = New Class1

    Set c1.ws = ThisWorkbook.Worksheets(1)

    Debug.Print c1.ws.Cells(1, 1).Value
End Sub

イミディエイトウィンドウにブックの最初のシートの先頭セルの値が表示されます。

Let で代用できないの?

できます。代用できてしまいます。

先ほどのコードを使用した場合ですと、

' Class1 モジュール

Private m_ws As Worksheet

' SetをLetに変える所以外はそのまま
Public Property Let ws(ByRef received As Worksheet)

    ' プロパティに設定する場合のSetは、Letの場合でも必要
    Set m_ws = received
End Property
' 標準モジュール

Dim c1 As Class1
Set c1 = New Class1

' 呼び出す際のSetが必要なくなる
c1.ws = ThisWorkbook.Worksheets(1)

これで同様の結果が得られてしまいます。

ですので実質、プロパティ(メンバー変数)の設定は Get と Let だけで事足りる。

ということになってしまいます。例外的にできないケースもあるのかもしれませんが、なぜここがこんなに柔軟な仕様となっているのかは、よく分かりません・・・

最後に

今更 VBA、と感じられる方もいらっしゃるかもしれませんが、SaaS 時代には時代なりの Excel 運用方法があります。

そのうちの一つが、VBA からクラウドサービスの API の利用です。

当ウェブサイトでもいくつか紹介していますので、よろしければ目を通していただけますと幸いです。

#VBA #Excel