わーぷろおじさん

WordやOffice関連の小細工の備忘録。

【vba】引数付きコンストラクタの一案

概要

コンストラクタに引数を持たせる方法の一案

コード

Personクラス

Option Explicit
Private mName As String

Public Function Init(Name_ as String) As Person
    mName = Name_
    Set Init = Me
End Function

Init関数を定義し、引数を受け取って自身のインスタンスを返す。

New_モジュール(標準モジュール)

Option Explicit
Public Property Get Person(Name_ As String) As Person
  Dim x___ As New Person
  Set Person = x___.Init(Name_)
End Property

標準モジュール名を「New_」とする。

クラス名と同名の関数(又はプロパティ)を定義し、引数はクラスのInit関数と同じにして、クラスを返す。

関数内でクラスのインスタンスを作成し、Init関数を実行し、引数を受け取った状態のインスタンスを受け取って返す。

※モジュール名は「New」とはできないので、「New_」で妥協した。
※FunctionでもPropertyでもどちらでも同じ挙動となる(と思われる)のでどちらでもよい。個人的にはPublicなFunctionに抵抗がある(結局同じなんだけど)。
※内部の変数名も使い捨てなのでなんでもいい。個人的には、Get PersonとNew Personがきっちり縦に並んでいることと、変数名が見た目の邪魔にならないことが、見やすい(確認しやすい)と思い、上記の記載方法としている。

使用(標準モジュール)

Public Sub test()
  Dim p As Person
  Set p = New_.Person("Taro")
End Sub

補足

New_モジュールは標準モジュールに記載することとしたが、クラスモジュールに記述し、クラス属性「Attribute VB_PredeclaredId = True」とすれば、「New_.」の記述を強制できる。

使用感

メリット

  • 使用する際の記述は明瞭
  • インテリセンスがきちんと働く

デメリット

  • New_モジュールを用意するのが面倒
  • 引数に変更があった場合はNew_モジュール側も追従する必要あり
  • クラスをたくさん作る場合はNew_モジュールがごちゃごちゃになる