web-dev-qa-db-ja.com

VBAのクラス(静的)メソッド

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'
40
Tom

それ(「パブリック共有」)はVB.Netでのみ機能します。

VBA(またはVB)でクラスメソッドを定義する方法はありません。モジュールにパブリック関数を作成することをお勧めします。

30
Thomas

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)
41

静的にしたいクラスのVB_PredeclaredId属性をTrueに設定してみてください。これにより、フォームがVBAで機能するのとほぼ同じ方法でクラスのデフォルトインスタンスが作成されます(インスタンスを作成せずに直接参照できることに注意してください。これはベストプラクティスではありませんが可能です)。

これは、シングルトンスタイルのクラスをより多く持つことを意味しますが、要件を満たすことができます...

これをVBA IDE自体から直接設定することはできませんが、次の手順を実行できます。

1。静的にしたいクラスをフォルダにエクスポートします。

2。お気に入りのテキストエディターでエクスポートした.clsファイルを開き、VB_PredeclaredIdのエントリを変更して、VB_PredeclaredId = True

3。ファイルを保存し、VBAに再インポートします。

その後、クラスをインスタンス化することなく、クラスのパブリックメソッドを呼び出すことができます。 Initializeメソッドは、クラスメソッドの実行/クラスプロパティへの最初のアクセス時にのみ呼び出され、Terminateメソッドは呼び出されないことに注意してください。したがって、独自のコンストラクターを作成し、必要に応じて明示的にデストラクターを呼び出すこともできます。

参照: tterAccess.comシングルトンの例

参照: http://msdn.Microsoft.com/en-us/library/ee199159.aspx

18
i_saw_drones

少し遅いですが、一体何

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のインスタンスを作成し、プロパティセッターを介してパラメーターを割り当て、インスタンスを返すだけです。オブジェクトのインスタンスを多くの場所に構築する場合、これにより多くのコードを節約できます。

8
Swanny

知っている限り、最も近い(そしてそれほど近くはない)のは、「匿名」インスタンスを使用することです。したがって、次のようになります。

With New NotReallyStaticClass
    .PerformNotReallyStatic Method, OnSome, Values
End With
4
Mike Woodhouse

これは質問そのものに対する厳密な答えではありませんが、マイクウッドハウスの解決策は避けるべきであることを指摘したいと思います。オブジェクトの新しいインスタンスを作成するたびにパフォーマンスが低下し、実際には元の問題を解決しません。静的オブジェクトを作成せず、静的メソッドも提供しません。

VBAにはクラス関数の概念がないため、最も近いものはモジュール内の関数を使用することです。

ファクトリメソッドについては、モジュールが作成するクラスの名前にWord Factoryを追加してモジュールを作成することをお勧めします。何かのようなもの:

'Module PersonFactory
Option Explicit

Public Function Create(ByVal sName As String) As Person

    'Code here

End Function

これは他の言語の静的メソッドの概念とはほど遠いですが、少なくともプロジェクトで使用できるパターンを提供します。

2
xxbbcc

同様のクラスのインスタンス化プロパティは、静的クラスで使用できます。インスタンスのプロパティ '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つ追加されています。クラスのプロパティとメソッドは、単にグローバル関数であるかのように呼び出すことができます。自動的に作成されるため、最初にクラスのインスタンスを明示的に作成する必要はありません。

1
fuat aygan