みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
「初心者でもわかるエクセルVBAのクラスモジュール」ということでシリーズでお伝えしております。
さて、前回の記事はこちら。
インスタンスのコレクションからその要素を取り出す方法をお伝えしました。
これで、だいぶ形になってきた感じはあるのですが、もうちょっと欲を出しちゃいましょうか。
それは、独自のコレクションを作るです。
これまでは、既存のCollectionオブジェクトを使ってきたのですが、独自のコレクションを作れたら、集合に対して便利なメソッドやプロパティを追加できますもんね。
ということで、エクセルVBAでクラスモジュールを使って独自のコレクションを作る方法です。
では、行ってみましょう!
前回のおさらい
では、前回のおさらいから…!
まず、以下のようなエクセル表があります。
これをクラスでいい感じに取り扱えるようにしていきたいというのがシリーズの目標です。
それで、これまで作成してきたクラス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
エクセル表のフィールドをプロパティとして持つだけでなく、いくつかの便利なメンバーも独自で追加しています。
上記、クラスはエクセル表の1行分のデータを表すものなので、それをコレクションに格納して取り扱おうと、そしてその参照方法についていくつかテストしているのが、以下の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
今回やりたいこと:独自のコレクションを作る
標準モジュールModule1の処理を見ると、3~13行目はそもそもコレクションの準備として、
- 新規コレクションを生成
- データ行の分だけ繰り返し
- インスタンスを生成
- インスタンスのプロパティに初期データをセット
というような処理をしています。
ていうか、この部分って、どうせいつも必要な処理ですよね?
そしたら、これもクラスに寄せることはできまいか…!?
そう考えると、ふと思い浮かびます。
- WorksheetオブジェクトにはWorksheetsコレクション
- WorkbookオブジェクトにはWorkbooksコレクション
- WindowオブジェクトにはWindowsコレクション
あらかじめ用意されているオブジェクトのいくつかには、その集合を扱うための専用のコレクションが用意されています。
てことは、PersonオブジェクトにはPersonsコレクションがあったらほうが便利じゃね?
それで、Personのコレクションにいつもやるようさ操作は、そっちに機能をもたせたほうがいいんじゃね?
ということになりそうです。トライしてみましょう。
独自のコレクションを作成する
さて、では手探りをしながら、独自コレクションPersonsを作成していきましょう。
新規クラスモジュールを挿入する
独自コレクションとはいいつつも、コレクションはオブジェクトなので、クラスモジュールの挿入からスタートです。
VBEメニューの「挿入」から「クラスモジュール」を選択して、新たなクラスモジュールを挿入します。
そして、プロパティウィンドウの「(オブジェクト名)」を編集して、挿入したクラスモジュールの名前を「Persons」に変更します。
クラスモジュールにCollection型のプロパティを追加する
それで、その新たに作ったまっさらのクラスモジュールPersonsに何を書いていくか…ということなのです。
まず、コレクションを持たせたいので、「データ」としてコレクションを定義しちゃいましょうか。
プロパティとして、Collection型のオブジェクト変数を定義するのです。
クラスモジュールPersonsの宣言セクションに…えい!
Public Items As Collection
これで、PersonsクラスにCollection型のオブジェクトを参照するItemsというプロパティを定義することになります。
Itemsプロパティは以下のようにすることで、Personsクラスのインスタンスが持つCollectionオブジェクトを返します。
Persons.Items
ですから、それに対してAddメソッドやItemメソッドなどが使えるという寸法です。
これで、クラスPersonsにはコレクションを持たせることができるはず…!
独自コレクションの確認するマクロ
いったんこの時点で確認してみましょう。
標準モジュールModule1を以下のように変更しました。
Sub MySub()
Dim myPersons As Persons: Set myPersons = New Persons
Set myPersons.Items = 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.Items.Add p, p.Id
i = i + 1
Loop
End With
Stop
End Sub
1つ目のポイントは4行目ですが、ほらItemsプロパティはCollection型、つまりオブジェクトなので、宣言するだけでは実体化されていません。
なので、Setステートメントで、Newで生成したインスタンスを参照設定してあげる必要があります。
それで、11行目は各インスタンスについて、インスタンス内のCollectionオブジェクトにAddメソッドで追加しているというわけですね。
実行して、Stopの際のローカルウィンドウを確認します。
無事に、データが投入されているのが確認できますね。
まとめ
以上、エクセルVBAでクラスモジュールを使って独自のコレクションを作る方法をお伝えしました。
プロパティとしてCollection型のオブジェクト変数を持たせることで、ひとまず独自コレクションとしての機能は実現できます。
ただ、「myPersons.Items.~」っていちいち書かないといけないので、ちょっとかっこ悪いですね。独自のAddメソッドとか、Itemメソッドがあったら「myPersons.Add」「myPersons.Item」とできますね。
なんとなく、Itemsプロパティはプライベートにしたいですし…
ということで、まず次回は独自コレクションPersonsの初期データ投入について進めていきます。
どうぞお楽しみに!
連載目次:初心者でもわかる!エクセル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でエクセル表のデータを反映するメソッドとクラスを使うメリット