VBAでクラスメソッドを作成できるかどうかは疑問です。クラスメソッドとは、クラスのオブジェクトを持たずに呼び出すことができるメソッドを意味します。 「静的」キーワードは、C++およびJavaでそのトリックを行います。
次の例では、静的なファクトリメソッドを作成しようとしています。
例:
'Classmodule Person'
Option Explicit
Private m_name As String
Public Property Let name(name As String)
m_name = name
End Property
Public Function sayHello() As String
Debug.Print "Hi, I am " & m_name & "!"
End Function
'---How to make the following method static?---'
Public Function Create(name As String) As Person
Dim p As New Person
p.m_name = name
Set Create = p
End Function
'Using Person'
Dim p As New Person
p.name = "Bob"
p.sayHello 'Works as expected'
Set p2 = Person.Create("Bob") 'Yields an error'
それ(「パブリック共有」)はVB.Netでのみ機能します。
VBA(またはVB)でクラスメソッドを定義する方法はありません。モジュールにパブリック関数を作成することをお勧めします。
1。「静的」にする必要があるパブリックメソッドを含む通常のクラスを作成します
2。クラス内の[プライベート] '静的フィールド'を初期化するパブリックメソッド[この '静的'クラス]を含めます(必要に応じてパラメーターを取得できます)。
。ファクトリーとして機能するモジュールの作成
Public Function CreateStaticClass(parameters for 'constructor') As StaticClass
Dim static As StaticClass
Set static = New StaticClass
Call StaticClass.Constructor(pass in parameters)
Set CreateStaticClass = static
End Function
4。 CreateStaticClass( 'parameters')。MethodName( 'parameters')を呼び出すことで 'static'クラスを使用できるようになりました。ファクトリメソッドによって行われるようにインスタンスを初期化する必要はありません。
5。(オプション)シングルトンインスタンスを適用する場合は、シングルトンコンテナとして機能するモジュールを作成できます。プライベートインスタンス変数とパブリックアクセサプロパティを含めます。オプションで、「let」セッターを使用して、シングルトンを新しい[static]クラスで「置換」できるようにすることができます(異なるコンストラクターパラメーターを使用-#2,3を参照)。セッターに「Let」を使用して、「set」を使用せずにシングルトンを割り当てることができますala OO languages
Private curStaticClass as StaticClass
Public Property Get CurrentStaticClass() As StaticClass
If curStaticClass Is Nothing Then Set curStaticClass = CreateStaticClass
Set CurrentStaticClass = curStaticClass
End Property
Public Property Let CurrentStaticClass(value As StaticClass)
If Not (curStaticClass Is Nothing) Then Set curStaticClass = Nothing
Set curStaticClass = value
End Property
6。シングルトンを割り当てるには:
CurrentStaticClass = CreateStaticClass(parameters)
7。シングルトンを使用するには:
[value = ] CurrentStaticClass.MethodName(parameters)
静的にしたいクラスのVB_PredeclaredId
属性をTrue
に設定してみてください。これにより、フォームがVBAで機能するのとほぼ同じ方法でクラスのデフォルトインスタンスが作成されます(インスタンスを作成せずに直接参照できることに注意してください。これはベストプラクティスではありませんが可能です)。
これは、シングルトンスタイルのクラスをより多く持つことを意味しますが、要件を満たすことができます...
これをVBA IDE自体から直接設定することはできませんが、次の手順を実行できます。
1。静的にしたいクラスをフォルダにエクスポートします。
2。お気に入りのテキストエディターでエクスポートした.cls
ファイルを開き、VB_PredeclaredId
のエントリを変更して、VB_PredeclaredId = True
。
3。ファイルを保存し、VBAに再インポートします。
その後、クラスをインスタンス化することなく、クラスのパブリックメソッドを呼び出すことができます。 Initialize
メソッドは、クラスメソッドの実行/クラスプロパティへの最初のアクセス時にのみ呼び出され、Terminate
メソッドは呼び出されないことに注意してください。したがって、独自のコンストラクターを作成し、必要に応じて明示的にデストラクターを呼び出すこともできます。
少し遅いですが、一体何
VB6/VBAにはクラスメソッドも静的メソッドもありません。ただし、モジュールの名前を明示的に指定できます。同じ名前のモジュールとクラスを持つことはできませんが、似たような名前を付けることができます。
したがって、EmployeeというクラスとEmployeeUtilというモジュールを作成して、次のように記述できます。
Dim emp As Employee
Dim code As String
Set emp = EmployeeUtil.Create( "Smith", "John", 21-Feb-1988)
code = "123XY"
If EmployeeUtil.IsCodeValid( code) Then
emp.Code = code
Else
emp.Code = EmployeeUtil.DefaultCode
EndIf
はい、値はハードコーディングされており、コード処理はおそらくプロパティセッターの下にあるはずですが、それは私がしようとしているポイントではありません。 EmployeeUtilは、本質的に非インスタンスメンバーのプレースホルダーです。
この方法でCreateメソッドを実行すると、Employeeクラスの擬似的なコンストラクターが得られます。その機能は、Employeeのインスタンスを作成し、プロパティセッターを介してパラメーターを割り当て、インスタンスを返すだけです。オブジェクトのインスタンスを多くの場所に構築する場合、これにより多くのコードを節約できます。
知っている限り、最も近い(そしてそれほど近くはない)のは、「匿名」インスタンスを使用することです。したがって、次のようになります。
With New NotReallyStaticClass
.PerformNotReallyStatic Method, OnSome, Values
End With
これは質問そのものに対する厳密な答えではありませんが、マイクウッドハウスの解決策は避けるべきであることを指摘したいと思います。オブジェクトの新しいインスタンスを作成するたびにパフォーマンスが低下し、実際には元の問題を解決しません。静的オブジェクトを作成せず、静的メソッドも提供しません。
VBAにはクラス関数の概念がないため、最も近いものはモジュール内の関数を使用することです。
ファクトリメソッドについては、モジュールが作成するクラスの名前にWord Factoryを追加してモジュールを作成することをお勧めします。何かのようなもの:
'Module PersonFactory
Option Explicit
Public Function Create(ByVal sName As String) As Person
'Code here
End Function
これは他の言語の静的メソッドの概念とはほど遠いですが、少なくともプロジェクトで使用できるパターンを提供します。
同様のクラスのインスタンス化プロパティは、静的クラスで使用できます。インスタンスのプロパティ 'GlobalMultUse'を指定する必要があります。
静的クラスの例:
' Error Class in ClassInstancing ActiveDLL project
Option Explicit
Private m_errorID As Integer
Private m_Description As String
Public Property Get ErrorID() As Integer
ErrorID = m_errorID
End Property
Public Property Let ErrorID(ByVal vNewValue As Integer)
m_errorID = vNewValue
End Property
Public Property Get Description() As string
Description = m_Description
End Property
Public Property Let Description(ByVal vNewValue As string)
m_Description = vNewValue
End Property
Public Function Error() As Error
Dim errorInstance As New ClassInstancing.Error
With errorInstance
.ErrorID = Me.ErrorID
.Description = Me.Description
End With
Set Error = errorInstance
End Function
Public Sub RaiseError(ByVal pErrorID As Integer, ByVal errorSource As String, ByVal errorDesc As String)
Err.Raise pErrorID, errorSource, errorDesc
End Sub
Public Sub ShowError()
MsgBox "Error ID: " & CStr(Me.ErrorID) & vbCrLf & _
"Desc: " & Me.Description
End Sub
GlobalMultiUse Instancingプロパティを使用して、クラスをセットとして指定します...
他の標準EXEプロジェクトでのこのグローバル(静的!)クラスの使用例:
Private Sub Command1_Click()
ClassInstancing.Description = "Sample-1 error using !"
ClassInstancing.ErrorID = 9990
'Dim multiuseClass As ClassInstancing.Error
'Set multiuseClass = ClassInstancing.Error
MsgBox ClassInstancing.Error.ErrorID & vbCrLf & ClassInstancing.Error.Description, vbInformation, "Sample Usage 1"
ClassInstancing.Description = "Sample-2 error using !"
ClassInstancing.ErrorID = 1110
ClassInstancing.ShowError
End Sub
最後に、MSDNのメモ((MSDNライブラリVisual Studio 6.0、「インスタンスプロパティ」)):
GlobalMultiUse。 MultiUseに似ていますが、1つ追加されています。クラスのプロパティとメソッドは、単にグローバル関数であるかのように呼び出すことができます。自動的に作成されるため、最初にクラスのインスタンスを明示的に作成する必要はありません。