48

VBA でクラスメソッドを作成することは可能でしょうか。クラスメソッドとは、クラスのオブジェクトを持たずに呼び出すことができるメソッドを意味します。「static」キーワードは、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'
4

8 に答える 8

46

1.「静的」にする必要があるパブリックメソッドを含む通常のクラスを作成します

2.クラス内の [プライベート] '静的フィールド' を初期化するパブリック メソッド [この '静的' クラス内] を含めます (必要に応じてパラメーターを取ることができます)。

3.ファクトリとして機能するモジュールを作成する

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') を呼び出して「静的」クラスを使用できるようになりました。ファクトリ メソッドによって行われるため、インスタンスを初期化する必要はありません。

5. (オプション)シングルトン インスタンスを強制する場合は、プライベート インスタンス変数とパブリック アクセサー プロパティを含めて、シングルトン コンテナーとして機能するモジュールを作成できます。オプションで、「let」セッターを使用して、シングルトンを新しい [静的] クラスに「置き換える」ことができます (異なるコンストラクターパラメーターを使用 - #2,3 を参照)。セッターに「Let」を使用すると、「set」ala OO言語を使用せずにシングルトンを割り当てることができます

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)
于 2010-11-16T17:19:00.553 に答える
29

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

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

于 2008-12-28T12:36:48.323 に答える
28

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

これは、シングルトンスタイルのクラスが増えることを意味しますが、要件を満たすことができます...

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

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

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

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

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

参考:UtterAccess.com シングルトンの例

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

于 2014-07-04T12:45:44.690 に答える
9

ちょっと遅い時間だけどどうしたの?

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

于 2009-08-27T05:15:16.943 に答える
4

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

With New NotReallyStaticClass
    .PerformNotReallyStatic Method, OnSome, Values
End With
于 2008-12-28T16:29:23.483 に答える
2

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

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

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

'Module PersonFactory
Option Explicit

Public Function Create(ByVal sName As String) As Person

    'Code here

End Function

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

于 2011-09-08T03:59:41.367 に答える
1

同様のクラスのインスタンス化プロパティは、静的クラスで使用できます。そのインスタンス化プロパティ「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 Library Visual Studio 6.0, 'Instancing Property')):

グローバルマルチユース。MultiUse に似ていますが、1 つ追加されています。クラスのプロパティとメソッドは、単なるグローバル関数であるかのように呼び出すことができます。クラスのインスタンスは自動的に作成されるため、最初に明示的に作成する必要はありません。

于 2011-12-07T01:28:34.073 に答える
-3

次のように Set を使用する前に、p2 を宣言する必要があります。

p2 を Person として薄暗くする

これを行ったら、標準の割り当てを使用して Set ステートメントを置き換える必要があります: p2 = Person.Create("Bob")

Function: で「Set」キーワードを削除します...これもエラーの原因となる可能性があります。

私は盲目的に飛んでいますが、論理的にはこれでうまくいくようです。私は VBA でクラス モジュールを使用するのは初めてですが、VB.Net プロパティを使用する場合とそれほど違いはありません。

于 2009-02-19T12:12:45.947 に答える