みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
「初心者でもわかるエクセルVBAのクラスモジュール」をテーマにシリーズでお送りしております。
前回の記事はこちら。
クラスから生成したインスタンスをコレクション化する方法についてお伝えしました。
それで、コレクションにしたはいいのですが、そこから要素を取り出してクラスのメンバーを活用できるのかを説明していませんでしたね…
ということで、今回はエクセルVBAでコレクション化したインスタンスを取り出す方法についてお伝えします。
では、行ってみましょう!
前回のおさらい
では、まずおさらいから。
以下のようなエクセル表をクラスで管理するということを目指しています。
そして、そのデータの1行分を表す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
プロパティ、メソッドと色々なメンバーが追加されていますね。
そして、エクセル表のデータからインスタンスを生成してコレクション化するという処理を作成しましたが、それが以下のModule1です。
Sub MySub()
Dim myPersons As Collection: Set myPersons = 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))
myPersons.Add p, p.Id
i = i + 1
Loop
End With
Stop
End Sub
myPersonというオブジェクト変数をコレクションとして、そこに生成したインスタンスに初期データを投入したものを、要素として追加していっています。
では、このコレクションmyPersonからインスタンスをどのように参照して、操作できるのか…これについて見ていきましょう。
Collectionオブジェクトから要素を取り出す
まず、Collectionオブジェクトから要素を取り出す方法を見ていきましょう。
インデックスを使う方法と、キーを使う方法の2種類を使用することができます。
インデックスを使う
Collectionオブジェクトの要素を取り出すには、Itemメソッドを使います。
書式はこちらのように、引数としてインデックスを指定します。
Itemメソッドは既定のメンバーなので、以下のように省略した記述をしてもOKです。
例えば、以下のようにすれば、インデックスが2の要素を取り出して、そのFirstNameプロパティを出力できます。
Debug.Print myPersons(2).FirstName
ただ…どのインスタンスが、どのインデックスに対応しているか…別途記録しておかないとイマイチ分かりづらいですよね。
キーを使う
そこで、Collectionオブジェクトからキーを使って要素を取り出すという手があります。
ほら、myPersonsに要素を追加するときに、以下のようにインスタンス自身のIdプロパティをキーに設定していたのでした。
myPersons.Add p, p.Id
それで、CollectionオブジェクトのItemメソッドは引数として、キーを指定することもできます。
同様に、以下のように省略できます。
誰がどのIdであるかは事前にわかっていますもんね。
以下のようにすれば、Idプロパティが「a03」のPersonオブジェクトのBirthdayプロパティを取得できます。
Debug.Print myPersons("a03").Birthday
なお、Personクラスの仕様では、FirstNameプロパティとGenderプロパティ、Birthdayプロパティは変更が可能です。
キーを使って取り出して、プロパティを変更するということもできるわけですね。
ループを回して各インスタンスを操作する
コレクション化のもう一つのメリットとしては、反復を行うステートメントを使えるようになるということですね。
例えば、For Each~Next文を使えば、以下の構文で各要素についてループさせることができますね。
’処理
Next 変数
今回の場合は、以下のようにすれば、各インスタンスのプロパティをデバッグ出力することができます。
For Each p In myPersons
Debug.Print p.Id, p.FirstName, p.Gender, p.Birthday
Next p
コレクション化したインスタンスを取得する
では、以上を踏まえてマクロを実行して確認してみましょう。
まとめて、Module1を以下のように書き換えてみました。
Sub MySub()
Dim myPersons As Collection: Set myPersons = 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))
myPersons.Add p, p.Id
i = i + 1
Loop
End With
Debug.Print myPersons(2).FirstName 'インデックスでの参照を確認
Debug.Print myPersons("a03").Birthday 'キーでの参照を確認
'コレクションの要素についてループ
For Each p In myPersons
Debug.Print p.Id, p.FirstName, p.Gender, p.Birthday
Next p
End Sub
実行すると、イミディエイトウィンドウには以下のように出力されます。
まとめ
以上、エクセルVBAでコレクション化したインスタンスを取り出す方法をお伝えしました。
配列でもいいのですが、コレクションだとキーが使えるのがいいですよね。
あと、サイズを気にしなくていいですしね。
さて、次回はこのコレクション…もっと欲張って、独自のコレクション作りを進めていきます。
どうぞお楽しみに!
連載目次:初心者でもわかる!エクセル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でエクセル表のデータを反映するメソッドとクラスを使うメリット