【Excel VBA】ユーザー定義オブジェクトを初期化する方法

一般的なオブジェクト指向言語にはコンストラクタというオブジェクトを生成して初期化するための機構がありますが、VBAにはありません。ここではオブジェクトの初期化を簡単にする方法を解説します。

この記事の例では次のPersonクラスを使います。最初にクラスモジュールを追加して、Personというクラスを定義しておきます。

Private pName As String
Private pSex As String

Public Property Get Name() As String
    Name = pName
End Property

Public Property Let Name(fullName As String)
    pName = fullName
End Property

Public Property Get Sex() As String
    Sex = pSex
End Property

Public Property Let Sex(mlelOrFemale As String)
    pSex = mlelOrFemale
End Property
目次

VBAにはコンストラクタがない

一般的なオブジェクト指向言語にはオブジェクトを生成して初期化するコンストラクタと呼ばれる特別な関数を定義することが出来ます。コンストラクタには引数を渡すことができ、オブジェクトを適切な値で初期化することが出来ます。

しかし、VBAにはコンストラクタやそれに類する機構がありません。そのためオブジェクトは生成した後、プロパティを適切な値で初期化する必要があります。

次のコードはPersonオブジェクトを生成して適切な値で初期化しています。

Sub sample()
    Dim p1 As New Person
    Dim p2 As New Person
    
    p1.Name = "鈴木一郎"
    p1.Sex = "男"
    p2.Name = "山田花子"
    p2.Sex = "女"
End Sub

Initializeイベントを契機にオブジェクトを初期化する

ユーザーが定義した独自クラスからオブジェクトを生成すると、Initializeイベントが発生します。クラスモジュールにClass_Initializeイベントプロシージャを追加して、オブジェクトが生成されたときにプロパティや変数の初期化処理を実行することが出来ます。

次のClass_InitializeイベントプロシージャをPersonクラスに追加してみましょう。

Private Sub Class_Initialize()
    Me.Name = "名無しの権兵衛"
    Me.Sex = "不明"
End Sub

Class_Initializeイベントプロシージャには、引数を渡すことはできません。

次のコードを実行するとプロパティが初期化されていることがわかります。

Sub sample()
    Dim p As New Person
    MsgBox p.Name & vbLf & p.Sex
End Sub

この方法ではオブジェクトごとに異なる値で初期化することはできません。あくまでもデフォルト値を設定できるだけです。ただし、Singletonオブジェクト(プログラム中で1つだけしか生成されないオブジェクト)であればこの方法でうまく初期化できるかもしれません。

初期化メソッドを定義する

Class_Initializeイベントプロシージャはデフォルト値を設定することはできますが、オブジェクトごとに異なる値を設定することが出来ません。最初の例のように、オブジェクトのプロパティを1つ1つ設定することもできますが、まとめてプロパティを設定できる初期化用のメソッドを用意します。

名前は任意で構いませんが、ここではInitという名前にします。Personクラスに次のようにInitメソッドを追加します。

Public Sub Init(fullName As String, mlelOrFemale As String)
    Me.Name = fullName
    Me.Sex = mlelOrFemale
End Sub

Initメソッドは他のモジュールから呼び出されるので、Publicを付けて定義する必要があります。

次のコードを実行すると、オブジェクトが適切な値で初期化されていることがわかります。

Sub sample()
    Dim p1 As New Person
    Dim p2 As New Person
    
    p1.Init "鈴木一郎", "男"
    p2.Init "山田花子", "女"
    MsgBox p1.Name & vbLf & p1.Sex
    MsgBox p2.Name & vbLf & p2.Sex
End Sub

まとめ

ここでの例では、Class_InitializeイベントプロシージャやInitメソッドの恩恵は少ないかもしれませんが、もっと複雑なオブジェクトであれば、その便利さが実感できるでしょう。

Class_InitializeイベントプロシージャやInitメソッドを追加した最終的なPersonクラスは次のようになります。

Option Explicit

Private pName As String
Private pSex As String

Public Property Get Name() As String
    Name = pName
End Property

Public Property Let Name(fullName As String)
    pName = fullName
End Property

Public Property Get Sex() As String
    Sex = pSex
End Property

Public Property Let Sex(mlelOrFemale As String)
    pSex = mlelOrFemale
End Property

Private Sub Class_Initialize()
    Me.Name = "名無しの権兵衛"
    Me.Sex = "不明"
End Sub

Public Sub Init(fullName As String, mlelOrFemale As String)
    Me.Name = fullName
    Me.Sex = mlelOrFemale
End Sub
よかったらシェアしてね!
  • URLをコピーしました!
目次