VBA中的类(静态)方法
我想知道,是否有可能在VBA中创建类方法。我所说的类方法是指不需要类的对象就可以调用的方法。“静态”关键字在C++和java中有这样的技巧。 在下面的示例中,我尝试创建一个静态工厂方法 例如:VBA中的类(静态)方法,vba,static,Vba,Static,我想知道,是否有可能在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 say
'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)中无法定义类方法。我建议在模块中创建一个公共函数。AFAIK,最接近的方法是使用“匿名”实例,如下所示:
With New NotReallyStaticClass
.PerformNotReallyStatic Method, OnSome, Values
End With
必须先声明p2,然后才能使用集合,如下所示: 作为人 执行此操作后,必须使用标准赋值替换Set语句: p2=个人创建(“Bob”) 在函数中: 删除“Set”关键字…这也可能是错误的来源
我在瞎飞,但从逻辑上看,这应该行得通。我不太熟悉在VBA中使用类模块,但它们与使用VB.Net属性没有太大区别。有点晚了,但这又是怎么回事 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
是的,这些值是硬编码的,代码处理可能应该在属性setter下进行,但这不是我想说的重点。EmployeeUtil本质上是非实例成员的占位符
您将注意到,通过这种方式创建方法为Employee类提供了一个伪类构造函数。该函数所做的只是创建Employee的实例,通过属性设置器分配参数,然后返回实例。如果您在很多地方构造对象实例,那么这可以节省大量代码。1。创建一个普通类,其中包含您需要的“静态”公共方法 2.包括一个公共方法[在此“静态”类中],用于初始化类中的[private]“static fields”(如果愿意,可以使用参数) 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')来使用'static'类
不需要初始化实例,因为这是通过工厂方法完成的
5。(可选)如果要强制执行单例实例,可以创建一个充当单例容器的模块-包括一个私有实例变量和一个公共访问器属性。或者,您可以使用“let”setter来允许使用新的[static]类“替换”单例(使用不同的构造函数参数-请参见#2,3)。对setter使用“Let”,这样就可以在不使用“set”语言的情况下分配单例
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)
[value = ] CurrentStaticClass.MethodName(parameters)
7.要使用单例:
CurrentStaticClass = CreateStaticClass(parameters)
[value = ] CurrentStaticClass.MethodName(parameters)
虽然严格来说,这并不是问题本身的答案,但我想指出,应该避免使用Mike Woodhouse的解决方案。每次创建一个对象的新实例都会对性能造成影响,它实际上并不能解决原来的问题——它既不创建静态对象,也不提供静态方法 由于VBA没有类函数的概念,因此最接近的方法是在模块中使用函数 至于工厂方法,我建议创建一个模块,将单词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
GlobalMulti使用实例属性将类指定为一组
此全局(静态!)类在其他standart 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,“实例化属性”)中的注释:
全球通用。类似于MultiUse,还有一点:类的属性和方法可以像调用全局函数一样调用。没有必要先显式地创建类的实例,因为会自动创建一个实例
您可以尝试将希望静态的类的
VB\u PredeclaredId
属性设置为True
。这将创建类的默认实例,其方式与VBA中窗体的工作方式大致相同(请注意,您可以直接引用它们,而无需创建实例。我知道这不是最佳做法,但也是可能的)
这意味着您将拥有更多的单例类,但它可以满足您的需求
您不能直接从VBA IDE本身进行设置,但是,您可以执行以下步骤:
1。将要使其成为静态的类导出到文件夹中
2.打开您在喜爱的文本编辑器中导出的.cls
文件,然后更改
VB\u PredeclaredId
的条目,以便它读取VB\u PredeclaredId=True
3.保存文件并重新导入VBA
然后,您应该能够调用类上的公共方法,而不必实例化该类。请记住,Initialize
方法仅在您第一次执行类方法/访问类属性时被调用,而Terminate
方法从未被调用。因此,您可能希望编写自己的构造函数,并确保在需要时显式调用析构函数
参考:
参考资料:我正在寻找如何在