みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
「初心者でもわかるエクセルVBAのクラスモジュール」についてシリーズでお伝えしています。
前回の記事はこちら。
インスタンスの生成時に自動で呼び出されるイベントプロシージャClass_Initializeについて紹介しました。
さて、そのClass_Initializeは自作のコレクションに追加したのですが、実はこのコレクションに初期データを投入する処理を追加もできちゃうんです。
ということで、今回はエクセル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クラスから生成されたインスタンスを集合としてコレクション的に扱うのがこのクラスPersonsです。
Public Items As Collection
Private Sub Class_Initialize()
Set Items = New Collection
End Sub
これで複数のデータ行、すなわちエクセル表全体を扱うことができるわけです。
前回は、イベントプロシージャClass_Initializeを作成して、Itemsプロパティ用Collectionオブジェクトの生成とセットをするようにしました。
そして、その動作を確認するために作ったのが、以下の標準モジュール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
今回の目標:自作コレクションの初期データを投入したい
さて、以前クラスPersonのインスタンスについて初期データを投入する処理を作るという記事を書きました。
その際は、Class_Initializeではなくて、独自のInitializeメソッドというのを作って、初期データの投入をするようにしていました。
上記のModule1のコードでいうと、10行目のところです。
これは、イベントプロシージャClass_Initializeには引数を渡すことができないという仕様から、仕方なく別メソッドにしていたんですね。
では、クラスPersonsはどうです?
クラスPersonは何行目のデータをインスタンス化していいかわからないので引数を渡す必要がありましたが、クラスPersonsは表全体をインスタンス化しちゃっていいですもんね。
引数、いらないんじゃないですかね…?
てことは、イベントプロシージャClass_Initializeにすべて吸収できるのでは…?
検証してみましょう!
イベントプロシージャClass_Initializeで初期データを投入する
標準モジュールModule1の4~14行目の処理をご覧ください。
4行目のCollectionオブジェクト生成とセットは、既にPersonsクラスのClass_Initializeに移設済みなので、コメントアウトしています。
残りの処理はどうでしょう。
- 2行目からすべてのデータ行について
- Personクラスのインスタンスを生成し変数pにセット
- pについてセル範囲を渡してInitializeメソッドを実行、pに初期データをセット
- myPersonsのItemsプロパティ(コレクション)にpを追加
…引数なくても、いけそうです。
自作コレクションのクラスモジュール
では、初期データ投入の処理をクラスPersonsに作成していきます。
Personsクラスのコードを以下のように追加しました。
Private Sub Class_Initialize()
Set 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))
Items.Add p, p.Id
i = i + 1
Loop
End With
End Sub
といっても、上記のModule1の処理のほぼカット&ペーストです。
変更したところと言えば、2行目と9行目。myPersons.Itemとなっていたところを、単にItemsとしただけですね。
自作コレクションへの初期データ投入を確認する
では、Personsクラスの初期データ投入について動作を確認してみましょう。
Module1のコードは以下のように変更しました。
Sub MySub()
Dim myPersons As Persons: Set myPersons = New Persons
Stop
End Sub
…って、ものすごいシンプルになりましたね。
実行して、Stopステートメント中断時のローカルウィンドウを見てみましょう。
まとめ
以上、エクセルVBAで自作コレクションのインスタンス生成時に初期データも投入する方法についてお伝えしました。
標準モジュール…だいぶスッキリしましたよね!
初期データ投入などといういつも発生する処理は、なるべくクラスモジュールのほうで持っていたいですもんね。
さて、では次回は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でエクセル表のデータを反映するメソッドとクラスを使うメリット