みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
「初心者でもわかるエクセルVBAのクラスモジュール」をテーマにシリーズ連載をしております。
前回の記事はこちら。
クラスのインスタンスを生成時に初期データをセットするメソッドを作成しました。
さて、これまではエクセル表の1行分のデータをクラスとして表す方法をお伝えしてきたのですが、エクセル表には複数行があるのです。
では、この複数行をまとめて取り扱う方法はないものか…
ということで、コレクションです。
今回は、エクセル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オブジェクトを使いますが、使用するためにはライブラリの参照が必要ですね。以下の記事から始まるシリーズで紹介しています。
一方で、要素の数の増減に柔軟さを持っているコレクションという仕組みが非常に扱いやすいのです(個人の感想含む)。
ということで、このシリーズでは、コレクションを使ってインスタンスの集合を取り扱う方針で進めていきます。
コレクションとそのメンバー
コレクションは、既存のCollectionオブジェクトとして提供されているので、Newしてインスタンスを生成すれば、すぐに使用をすることができます。
Collectionオブジェクトには、以下のようなメンバーが既に用意されていて、それらを活用することでデータの集合を扱います。
- Addメソッド: 要素を追加する
- Countメソッド: 要素の数を取得する
- Itemメソッド: コレクション内の要素を取得する
- Removeメソッド: 要素を削除する
Collectionオブジェクトを使用する
まず、Collectionオブジェクトを使用するには、以下のDimステートメントとSetステートメントが必要です。
Set 変数 = New Collection
Collectionオブジェクトを格納するオブジェクト変数を宣言し、それにインスタンスを生成します。
例えば、以下のようなコードを作成して、複数のPersonオブジェクトを扱う、CollectionオブジェクトmyPersonsを用意します。
Dim myPersons As Collection
Set myPersons = New Collection
Addメソッドで要素を追加する
インスタンスを生成した時点では、Collectionオブジェクトは何の要素もない空っぽの状態なので、要素を追加していく必要があります。
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で最も簡単なクラスを作る方法
- エクセル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でエクセル表のデータを反映するメソッドとクラスを使うメリット