エクセルVBAでインスタンスの集合をコレクション化する方法


collection

photo credit: Skolnik Collection Euphorbia via photopin (license)

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

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

前回の記事はこちら。

エクセルVBAでクラスのインスタンス生成時に初期データを格納するメソッドを作る方法
「初心者でもわかるエクセルVBAのクラスモジュール」についてシリーズでお伝えしています。今回は、エクセルVBAでクラスのインスタンス生成時にデータを簡単に格納する、つまりコンストラクタ的なメソッドを作る方法です。

クラスのインスタンスを生成時に初期データをセットするメソッドを作成しました。

さて、これまではエクセル表の1行分のデータをクラスとして表す方法をお伝えしてきたのですが、エクセル表には複数行があるのです。

では、この複数行をまとめて取り扱う方法はないものか…

ということで、コレクションです。

今回は、エクセル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

クラスPersonには色々なメンバーを追加してきましたね。

そして、その動作を検証するためのSubプロシージャを以下のModule1に記述しています。

Sub MySub()

Dim i As Long: i = 2
Dim p As Person: Set p = New Person
With Sheet1
    p.Initialize .Range(.Cells(i, 1), .Cells(i, 4))
End With

Stop
'p.Greet

End Sub

エクセル表の1行分についてインスタンスの生成をして、クラスPersonのInitializeメソッドを使って初期データをセットしています。

やりたいこと:生成したインスタンスを「集合」として取り扱いたい

さて、エクセル表には複数のデータがあります。

ですから、これを表のすべてのデータについてループを回して、インスタンスの生成を初期データのセットを行えばよいわけですね。

それで、その生成したインスタンスの集合…どんなふうに取り扱えばよかったでしたっけ?

エクセルVBAでデータの集合を扱う仕組み

エクセルVBAでは、データの集合を扱う方法として

  • 配列
  • コレクション
  • 辞書

などといった方法があります。

配列は他言語ではメジャーなのですが、VBAでは扱う要素の数を増減させたい場合には、ちょっと融通が効きづらいところがあって、正直使いづらいです(個人の感想含む)。

辞書は、Dictionaryオブジェクトを使いますが、使用するためにはライブラリの参照が必要ですね。以下の記事から始まるシリーズで紹介しています。

【エクセルVBA】リスト処理に便利!Dictionaryオブジェクトをコードで使うための準備
VBAでリストの重複を排除するのって、ループ文が複数出てきたり、処理速度が落ちたりして、ちょっと躊躇してしまいませんか?Dictionaryオブジェクトを使えば、重複排除もスマートにできるかもしれませんよ。エクセルVBAのDictionaryオブジェクトを、コードで使用するための前準備を紹介しています。

一方で、要素の数の増減に柔軟さを持っているコレクションという仕組みが非常に扱いやすいのです(個人の感想含む)。

ということで、このシリーズでは、コレクションを使ってインスタンスの集合を取り扱う方針で進めていきます。

コレクションとそのメンバー

コレクションは、既存のCollectionオブジェクトとして提供されているので、Newしてインスタンスを生成すれば、すぐに使用をすることができます。

Collectionオブジェクトには、以下のようなメンバーが既に用意されていて、それらを活用することでデータの集合を扱います。

  • Addメソッド: 要素を追加する
  • Countメソッド: 要素の数を取得する
  • Itemメソッド: コレクション内の要素を取得する
  • Removeメソッド: 要素を削除する

Collectionオブジェクトを使用する

まず、Collectionオブジェクトを使用するには、以下のDimステートメントとSetステートメントが必要です。

Dim 変数 As Collection
Set 変数 = New Collection

Collectionオブジェクトを格納するオブジェクト変数を宣言し、それにインスタンスを生成します。

例えば、以下のようなコードを作成して、複数のPersonオブジェクトを扱う、CollectionオブジェクトmyPersonsを用意します。

Dim myPersons As Collection
Set myPersons = New Collection

Addメソッドで要素を追加する

インスタンスを生成した時点では、Collectionオブジェクトは何の要素もない空っぽの状態なので、要素を追加していく必要があります。

Collectionオブジェクトに要素を追加するには、Addメソッドを使います。

Collectionオブジェクト.Add 要素, キー

追加する要素は、今回はPersonオブジェクトです。

キーは、その要素を呼び出すときに使えるキーワードのようなものです。

今回の場合は、一意に定められているIdプロパティの値などを使うと呼び出すときに便利そうです。

ですから、インスタンス生成から、初期データのセット、そしてコレクションへの追加の一連の流れは以下のように作ればよさそうです。

Dim p As Person: Set p = New Person
p.Initialize .Range(.Cells(i, 1), .Cells(i, 4))
myPersons.Add p, p.Id

インスタンスの集合のコレクション化

では、確認用のSubプロシージャの全体を作って、動作確認をしてみましょう。

こちらです。

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

Stopステートメントで中断しているときに、ローカルウィンドウで確認をすると、コレクションmyPersonsの内容を確認することができます。

インスタンスのコレクションについてローカルウィンドウで内容を確認

まとめ

以上、エクセルVBAでインスタンスの集合をコレクション化する方法をお伝えしました。

  • Collectionオブジェクトとは
  • Addメソッドでコレクションに要素を追加する方法

インスタンスの集合に限らず、いろいろなところで活躍しますので、ぜひ覚えておいてくださいね。

次回は、インスタンスのコレクションについて参照したり、操作をしたりしてみたいと思います。

エクセルVBAでコレクション化したインスタンスを取り出す方法
「初心者でもわかるエクセルVBAのクラスモジュール」をテーマにシリーズでお送りしております。今回は、Itemメソッドを使ってエクセル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でインスタンスの集合をコレクション化する方法
  12. エクセルVBAでコレクション化したインスタンスを取り出す方法
  13. エクセルVBAでクラスモジュールを使って独自のコレクションを作る方法
  14. エクセルVBAでインスタンス生成時に自動で処理を実行するイベントプロシージャClass_Initialize
  15. エクセルVBAで自作コレクションのインスタンス生成時に初期データも投入する方法
  16. エクセルVBAで自作コレクションの要素を取得するプロパティの作り方
  17. エクセルVBAで自作のコレクションに要素を追加するメソッドを作成する
  18. エクセルVBAで自作コレクションの要素を削除するメソッドの作り方
  19. エクセルVBAでエクセル表のデータを反映するメソッドとクラスを使うメリット

タイトルとURLをコピーしました