VBAでのクラス定義の基礎はこちらhttps://qiita.com/Kamo123/items/a4c7749fa30d8f68df28
##デフォルトプロパティを設定する
デフォルトプロパティとは、Range
オブジェクトのValue
プロパティなど、プロパティを省略すると取得されるやつです。
自作クラスに設定してみます。
元のクラスとして、以下のPerson
クラスを考えます。
Option Explicit
' プロパティ
Private Name As String
' メソッド
Public Sub SayHello()
MsgBox "Hello, I'm " & Name & "!"
End Sub
' プロパティプロシージャ
Property Get MyName() As String
MyName = Name
End Property
Property Let MyName(namae As String)
If namae = "" Then
' 氏名がブランクならエラー
Err.Raise 10000, , "名前がブランクです"
End If
Name = namae
End Property
まず、このPerson
クラスをエクスポートします。(プロジェクト エクスプローラからドラッグ&ドロップでできます。)
次に、エクスポートした.clsファイルをテキストエディタで開いて、デフォルトにしたいプロパティの先頭行にAttribute Value.VB_UserMemId = 0
と入れます。
Property Get MyName() As String
Attribute Value.VB_UserMemId = 0
MyName = Name
End Property
これでインポートしなおしますと、見た目は変化はありませんが、たしかにデフォルトプロパティに設定されています。
Sub test1()
Dim p As Person
Set p = New Person
p = "taro"
Debug.Print p ' => "taro"
End Sub
##For Eachで回せるようにする
セルをたくさん入れて管理できるクラスを考えます。
Option Explicit
Public Cells As Collection
Private Sub Class_Initialize()
Set Cells = New Collection
End Sub
Public Sub Add(newCell As Range)
Cells.Add newCell
End Sub
Public Function Item(Index As Long) As Range
Set Item = Cells(Index)
End Function
Public Function NewEnum() As stdole.IUnknown
Set NewEnum = Cells.[_NewEnum]
End Function
NewEnum
というのを定義するのが肝です。
このように、For Each
で回したいものをCollection
に入れておき、自作クラスのNewEnum
の中でCollection
の_NewEnum
を呼び出します。
このクラスモジュールをエクスポートしてテキストエディタで開きます。
Public Function NewEnum() As stdole.IUnknown
Attribute NewEnum.VB_UserMemId = -4 ' この行を追加した
Set NewEnum = CellCollection.[_NewEnum]
End Function
こんな感じでAttribute NewEnum.VB_UserMemId = -4
を追加します。
保存後、インポートするとFor Each
で使えるようになります。
Sub test1()
Dim cm As New CellManager
Dim c As Range
Range("A1").Value = "A"
Range("A2").Value = "B"
cm.Add Range("A1")
cm.Add Range("A2")
For Each c In cm
Debug.Print c.Value
Next
End Sub
A
B
なぜか変数cがVariant型でなくてもコンパイルエラーになりませんが、チェックできていないだけのようです。(追記:この部分、誤解していました。コメント欄を参照ください)
IntellisenseでNewEnum
が見えてしまうのが気持ち悪いですが、VBAではどうしようもないです。
##参考サイト
日本語情報でVBAの深いところまで解説しているサイトが少ない中、大変貴重な情報源です。
http://thom.hateblo.jp/entry/2015/02/16/003000
http://d.hatena.ne.jp/miau/20110203/1296706824