みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
「初心者でもわかるエクセルVBAのクラスモジュール」というテーマでシリーズ連載をしております。
前回の記事はこちら。
自作コレクションのクラスPersonsをイベントプロシージャClass_Initializeで初期化する方法をお伝えしました。
さて、この自作コレクションですが、現状だと要素の取得がちょっと回りくどいんです。
ということで、今回はエクセルVBAで自作コレクションの要素を取得するプロパティの作り方です。
では、行ってみましょう!
前回のおさらい
では、前回のおさらいから…!
まず、以下のようなエクセル表があります。
こちらのエクセル表をクラスで取り扱いをしていくというのが目標です。
まず、一行分のデータを扱うために、Personというクラスを作成しました。
Private id_ As String
Public FirstName As String
Public Gender As String
Public Birthday As Date
Public Sub Greet()
MsgBox Me.FirstName & "です、こんにちは!"
End Sub
Public Sub Initialize(ByVal rng As Range)
id_ = rng(1).Value
FirstName = rng(2).Value
Gender = rng(3).Value
Birthday = rng(4).Value
End Sub
Public Property Get IsMale() As Boolean
IsMale = (Me.Gender = "male")
End Property
Public Property Get Id() As String
Id = id_
End Property
Public Property Let Id(ByVal newId As String)
If id_ <> "" Then
Debug.Print "Idは上書きすることはできません"
Else
id_ = newId
End If
End Property
各データを格納するプロパティや、便利なメンバーを追加しています。
そして、このPersonクラスから生成したインスタンスを複数取り扱うコレクションのクラスPersonsがこちら。
Private Sub Class_Initialize()
Set Items = New Collection
With Sheet1
Dim i As Long: i = 2
Do While .Cells(i, 1).Value <> ""
Dim p As Person: Set p = New Person
p.Initialize .Range(.Cells(i, 1), .Cells(i, 4))
Items.Add p, p.Id
i = i + 1
Loop
End With
End Sub
これで、エクセル表のデータ全体を扱うことができるわけです。
前回、上記のコードのよいうに、クラスPersonsのインスタンス生成時にエクセル表のデータを自動で取り込むように作ったんです。
その確認用の標準モジュールがこちら。
Sub MySub()
Dim myPersons As Persons: Set myPersons = New Persons
Stop
End Sub
…超シンプルになりましたね。
独自コレクションにメンバーItemを追加する
さて、実際のPersonオブジェクトたちは、PersonsクラスのCollection型のパブリック変数Itemsに格納されています。
ですから、特定のPersonsオブジェクトを参照しようと思ったら
myPersons.Items.Item(1)
myPersons.Items.Item('a01')
などとする必要があります。
ちょっと回りくどいですし、普段使っているコレクションっぽくないですよね…
例えば、Personsクラス自体に、独自のメンバーとして「Item」を追加したらどうでしょう?
myPersons.Item(1)
myPersons.Item('a01')
と、こんな感じで参照ができて、普段使っているコレクションっぽいですよね。
コレクションの要素を取得するItemプロパティ
では、実際に実装していきましょう。
クラスPersonsにItemプロパティを追加します。
値を返すプロパティでいいので、Property Getプロシージャですね。
そして、引数として整数のインデックスまたは、文字列型のキーかどちらかを受け取る必要があるので、Variant型で引数を受けるようにしましょう。
Public Property Get Item(ByVal key As Variant) As Person
Set Item = Items.Item(key)
End Property
それで、その引数を使って、パブリック変数Itemsが参照するコレクションからItemメソッドを使って要素を取り出して挙げるということです。
自作のItemプロパティで要素を取得する
では、作成したItemプロパティの動作確認をしてみましょう。
標準モジュールをこんなふうに作ってみました。
Sub MySub()
Dim myPersons As Persons: Set myPersons = New Persons
With myPersons
Debug.Print .Item(1).FirstName
.Item("a02").Greet
End With
End Sub
インデックス1の要素のFirstNameを表示、キー「a02」の要素のGreetメソッドを実施ですね。
実行すると以下のように正しく参照できていることを確認できます。
Itemsプロパティを隠蔽する
さて、PersonsコレクションにItemプロパティを追加しました。
そうなると、ここでふとした疑問が…
パブリック変数Itemsですが、これ他のモジュールからアクセスできる必要…あります?
今回追加したItemプロパティや、要素の追加をするAddメソッドなどを用意すれば、Itemsがパブリックである必要はなさそうです。
Itemsプロパティを隠蔽しちゃいましょうか。
パブリック変数をプライベート変数に変更する
まず、Personsクラスのパブリック変数Itemsをプライベート変数に変更します。
プライベート変数なので、頭文字も小文字にしてアンダースコアを付与しました。
Private items_ As Collection
それに合わせて、Personsクラスのコードを置換しましょう。
Ctrl + F で以下の置換ダイアログが表示しますので、検索文字列を「Items」、置換後文字列を「items_」にします。
あと、「大文字と小文字を区別する」にもチェック入れておきましょう。
結果的に、Personsクラスは以下のようになります。
Private items_ As Collection
Private Sub Class_Initialize()
Set items_ = New Collection
With Sheet1
Dim i As Long: i = 2
Do While .Cells(i, 1).Value <> ""
Dim p As Person: Set p = New Person
p.Initialize .Range(.Cells(i, 1), .Cells(i, 4))
items_.Add p, p.Id
i = i + 1
Loop
End With
End Sub
Public Property Get Item(ByVal key As Variant) As Person
Set Item = items_.Item(key)
End Property
これで、他のモジュールからアクセスができなくなります。
ただ、Class_Initializeでの初期データ投入と、Itemプロパティによる参照はできるはずです。
前述の標準モジュールのコードを実行して確認しておきましょうね。
まとめ
以上、エクセルVBAで自作コレクションの要素を取得するプロパティの作り方をお伝えしました。
これで、コレクションっぽく要素を参照できるようになりましたね。
次回は、Personsクラスに要素を追加するAddメソッドを作成していきます。
どうぞお楽しみに!
連載目次:初心者でもわかる!エクセルVBAでクラスを作ろう
名前は聞いたことあるけどよくわからない「クラスモジュール」。本シリーズでは、初心者でも少しずつ丁寧にその作り方と便利さについてお伝えしていきますよ!- 【初心者でもできる】エクセルVBAで最も簡単なクラスを作る方法
- エクセルVBAでクラスに最も簡単なプロパティを追加する方法
- エクセルVBAで自作クラスをインスタンス化する方法
- エクセルVBAでクラスに最も簡単なメソッドを追加する方法
- エクセルVBAで表の1行分のデータを表すクラスを作成する方法
- エクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法
- エクセルVBAでプロパティを他のモジュールからアクセスできないようにする方法
- エクセルVBAでProperty Letプロシージャを使ってプロパティ設定をする方法
- エクセルVBAでPropety Getプロシージャを使ってプライベート変数にアクセスする方法
- エクセルVBAでクラスのインスタンス生成時に初期データを格納するメソッドを作る方法
- エクセルVBAでインスタンスの集合をコレクション化する方法
- エクセルVBAでコレクション化したインスタンスを取り出す方法
- エクセルVBAでクラスモジュールを使って独自のコレクションを作る方法
- エクセルVBAでインスタンス生成時に自動で処理を実行するイベントプロシージャClass_Initialize
- エクセルVBAで自作コレクションのインスタンス生成時に初期データも投入する方法
- エクセルVBAで自作コレクションの要素を取得するプロパティの作り方
- エクセルVBAで自作のコレクションに要素を追加するメソッドを作成する
- エクセルVBAで自作コレクションの要素を削除するメソッドの作り方
- エクセルVBAでエクセル表のデータを反映するメソッドとクラスを使うメリット