
photo credit: verchmarco Strohhüte werden auf dem Markt verkauft via photopin (license)
みなさん、こんにちは!
タカハシ(@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
実行すると、イミディエイトウィンドウには以下のように出力されます。
010 コレクション化したインスタンスの情報をデバッグ出力
まとめ
以上、エクセルVBAでコレクション化したインスタンスを取り出す方法をお伝えしました。
配列でもいいのですが、コレクションだとキーが使えるのがいいですよね。
あと、サイズを気にしなくていいですしね。
さて、次回はこのコレクション…もっと欲張ってみたいと思います。
どうぞお楽しみに!
連載目次:初心者でもわかる!エクセルVBAでクラスを作ろう
名前は聞いたことあるけどよくわからない「クラスモジュール」。本シリーズでは、初心者でも少しずつ丁寧にその作り方と便利さについてお伝えしていきますよ!- 【初心者でもできる】エクセルVBAで最も簡単なクラスを作る方法
- エクセルVBAでクラスに最も簡単なプロパティを追加する方法
- エクセルVBAで自作クラスをインスタンス化する方法
- エクセルVBAでクラスに最も簡単なメソッドを追加する方法
- エクセルVBAで表の1行分のデータを表すクラスを作成する方法
- エクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法
- エクセルVBAでプロパティを他のモジュールからアクセスできないようにする方法
- エクセルVBAでProperty Letプロシージャを使ってプロパティ設定をする方法
- エクセルVBAでPropety Getプロシージャを使ってプライベート変数にアクセスする方法
- エクセルVBAでクラスのインスタンス生成時に初期データを格納するメソッドを作る方法
- エクセルVBAでインスタンスの集合をコレクション化する方法