Quantcast
Channel: いつも隣にITのお仕事
Viewing all articles
Browse latest Browse all 2076

エクセルVBAでコレクション化したインスタンスを取り出す方法

$
0
0

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

「初心者でもわかるエクセルVBAのクラスモジュール」をテーマにシリーズでお送りしております。

前回の記事はこちら。

クラスから生成したインスタンスをコレクション化する方法についてお伝えしました。

エクセルVBAでインスタンスの集合をコレクション化する方法
「初心者でもわかるエクセルVBAのクラスモジュール」をテーマにシリーズ連載をしております。今回は、エクセルVBAでCollectionオブジェクトを使ってインスタンスの集合をコレクション化する方法をお伝えします。

それで、コレクションにしたはいいのですが、そこから要素を取り出してクラスのメンバーを活用できるのかを説明していませんでしたね…

ということで、今回はエクセル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メソッドを使います。

書式はこちらのように、引数としてインデックスを指定します。

Collectionオブジェクト.Item(インデックス)

Itemメソッドは既定のメンバーなので、以下のように省略した記述をしてもOKです。

Collectionオブジェクト(インデックス)

例えば、以下のようにすれば、インデックスが2の要素を取り出して、そのFirstNameプロパティを出力できます。

Debug.Print myPersons(2).FirstName

ただ…どのインスタンスが、どのインデックスに対応しているか…別途記録しておかないとイマイチ分かりづらいですよね。

キーを使う

そこで、Collectionオブジェクトからキーを使って要素を取り出すという手があります。

ほら、myPersonsに要素を追加するときに、以下のようにインスタンス自身のIdプロパティをキーに設定していたのでした。

myPersons.Add p, p.Id

それで、CollectionオブジェクトのItemメソッドは引数として、キーを指定することもできます。

Collectionオブジェクト.Item(キー)

同様に、以下のように省略できます。

Collectionオブジェクト(キー)

誰がどのIdであるかは事前にわかっていますもんね。

以下のようにすれば、Idプロパティが「a03」のPersonオブジェクトのBirthdayプロパティを取得できます。

Debug.Print myPersons("a03").Birthday

なお、Personクラスの仕様では、FirstNameプロパティとGenderプロパティ、Birthdayプロパティは変更が可能です。

キーを使って取り出して、プロパティを変更するということもできるわけですね。

ループを回して各インスタンスを操作する

コレクション化のもう一つのメリットとしては、反復を行うステートメントを使えるようになるということですね。

例えば、For Each~Next文を使えば、以下の構文で各要素についてループさせることができますね。

For Each 変数 In Collectionオブジェクト
 ’処理
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でクラスを作ろう

名前は聞いたことあるけどよくわからない「クラスモジュール」。本シリーズでは、初心者でも少しずつ丁寧にその作り方と便利さについてお伝えしていきますよ!
  1. 【初心者でもできる】エクセルVBAで最も簡単なクラスを作る方法
  2. エクセルVBAでクラスに最も簡単なプロパティを追加する方法
  3. エクセルVBAで自作クラスをインスタンス化する方法
  4. エクセルVBAでクラスに最も簡単なメソッドを追加する方法
  5. エクセルVBAで表の1行分のデータを表すクラスを作成する方法
  6. エクセルVBAでProperty Getプロシージャを使って簡単なプロパティを作成する方法
  7. エクセルVBAでプロパティを他のモジュールからアクセスできないようにする方法
  8. エクセルVBAでProperty Letプロシージャを使ってプロパティ設定をする方法
  9. エクセルVBAでPropety Getプロシージャを使ってプライベート変数にアクセスする方法
  10. エクセルVBAでクラスのインスタンス生成時に初期データを格納するメソッドを作る方法
  11. エクセルVBAでインスタンスの集合をコレクション化する方法

Viewing all articles
Browse latest Browse all 2076

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>