みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
「初心者でもわかるエクセルVBAのクラスモジュール」についてシリーズでお伝えしております。
前回の記事はこちら。

エクセルVBAで独自のコレクションを作る方法をお伝えしました。
とは言っても、ただクラスモジュールにパブリック変数でCollectionオブジェクトのオブジェクト変数を宣言しただけでしたね…。
ということで、この独自のコレクションをパワーアップしていきますよ。
Collectionオブジェクトは生成が必要なので、独自コレクションのインスタンスを生成したときに、それも自動でやっちゃいたいですね…
ということで、今回はエクセルVBAでインスタンスを生成したときに自動で処理を実行するイベントプロシージャClass_Initializeの使い方です。
では、行ってみましょう!
前回までのおさらい
では、前回までのおさらいからです。
まず、エクセルシート上には以下のような表があります。
このデータをクラス化して取り扱いたいのですが、その一行分を取り扱うのが、以下のクラス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
色々とメンバーを追加してきまして、一通りの実装は完了しています。
そして、その一行分のデータを表すオブジェクトを集合として便利に取り扱えればな~ということで、手をつけはじめたのが、以下の独自コレクションPersonsです。
Public Items As Collection
まだ、Collectionオブジェクト型のパブリック変数Itemsの宣言が一つあるだけですね…。
でも、これでPersonオブジェクトをコレクションとして扱うことができると言えばできます。
それを検証しているのが、以下の標準モジュール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
それで、標準モジュールModule1で、クラスPersonsのインスタンス生成は仕方ないんですが、Itemsプロパティとして持っているCollectionオブジェクトの生成までやっちゃっているんですね。
これは、どうせいつも必要な処理なので、標準モジュールではなくて、クラスモジュールPersonsに寄せていきたいというのが今回のお題です。
イベントプロシージャClass_Initializeとは
そんなときに便利なのが、イベントプロシージャClass_Initializeです。
このプロシージャ名でクラスモジュールにプロシージャを作成すると、インスタンス生成時に自動で走ってくれます。
つまり、イベントプロシージャClass_Initializeはインスタンスの生成時に呼び出されるので、コンストラクタ的な役割になります。
インスタンス生成時にデータを渡せないのが大変残念なのですが…というのを以下の記事でもお伝えしております。

イベントプロシージャClass_Initializeを挿入する
では、イベントプロシージャClass_Initializeを作成していきましょう。
まず、クラスモジュールPersonsを開いてください。
そこでプロシージャ名を指定すればよいのですが、イベントプロシージャはオブジェクトボックスとプロシージャボックスからでも作れます。
まず、コードペインの左上がオブジェクトボックスですが、そこで「Class」を選択します。
すると、右側の「プロシージャボックス」の選択が自動で「Initialize」になり、クラスモジュールにイベントプロシージャ「Class_Initialize」が挿入されます。
このようにすれば、イベントプロシージャ名を覚えていなくても正確に挿入できます。
イベントプロシージャClass_Initializeを作成する
あとはClass_Initializeプロシージャの中身を書いていけばOKです。
Personsのインスタンス生成時に、Itemsプロパティが表すCollectionオブジェクトを生成したいので、以下のようにします。
Private Sub Class_Initialize() Set Items = New Collection End Sub
インスタンスが生成されたら、パブリック変数Items(つまりItemsプロパティ)に、Collectionオブジェクトのインスタンスを生成してセットするわけですね。
イベントプロシージャClass_Initializeの動作を確認する
では、イベントプロシージャClass_Initializeの動作を確認してみましょうか。
標準モジュール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
myPersonsのItemsプロパティへのSetステートメントをコメントアウトしただけですね。この部分は、イベントプロシージャがやってくれるはず…!
実行をして、Stop時のローカルウィンドウを確認すると…
無事に動いています。つまり、Class_Initializeプロシージャも動いているということです。
まとめ
以上、エクセルVBAでインスタンス生成時に自動で処理を実行するイベントプロシージャClass_Initializeについてお伝えしました。
おそらく、このイベントプロシージャはクラスモジュールを使うならかなりお世話になるはず…!
さて、次回は標準モジュールの処理をもっともっとクラスモジュール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