有没有办法在VBA中重载类的构造函数/初始化过程?

时间:2009-11-13 18:36:03

标签: c# excel ms-access oop vba

在C#中,我知道我可以通过在类的主体中指定它来重载类的构造函数:

public class MyClass()
{
    public MyClass(String s) { ... }
}

这会覆盖默认构造函数(没有参数)并强制使用参数s初始化类。

我知道在VBA中我可以使用Private Sub Class_Initialize()初始化我的类,但我不知道是否有办法强制我的类用参数初始化。可以这样做吗?

4 个答案:

答案 0 :(得分:7)

正如Jtolle所说,这在VBA / VB6中根本不可能。没有完美的解决方法,但我个人所做的是使用我想要的参数创建一个Public / Friend子调用Initialize(在VBA / VB6中使用“可选”参数进行重载)然后快速检查如果您尝试在不运行initialize方法的情况下尝试访问它们,则抛出异常的类的所有公开成员。基本示例可能如下所示:

Option Explicit

Private m_blnInitialized As Boolean
Private m_lngID As Long
Private m_strFirstName As String

Public Sub Initialize(ByVal ID As Long, Optional ByVal someOtherThing As String = vbNullString)
    If m_blnInitialized Then Me.Clear
    m_lngID = ID
    m_strFirstName = SomeLookUp()
    If LenB(someOtherThing) Then
        ''Do something here.
    End If
    m_blnInitialized = True
End Sub

Public Property Get ID() As Long
    If Not m_blnInitialized Then Err.Raise eStandardErrors.eNotInitialized
    ID = m_lngID
End Property

Public Property Get FirstName() As String
    If Not m_blnInitialized Then Err.Raise eStandardErrors.eNotInitialized
    FirstName = m_strFirstName
End Property

Private Function SomeLookUp() As String
    ''perform magic on Me.ID
End Function

Public Sub LoadPicture()
    If Not m_blnInitialized Then Err.Raise eStandardErrors.eNotInitialized
    ''More magic
End Sub

Public Sub Clear()
    If Not m_blnInitialized Then Err.Raise eStandardErrors.eNotInitialized
    m_strFirstName = vbNullString
    m_lngID = 0&
    m_blnInitialized = False
End Sub

这不是很好,但它与VBA / VB6一样好。

答案 1 :(得分:5)

你已经有两个正确的答案;你不能在VBA中有一个带参数的构造函数。

Oorang的解决方法基本上是正确的 - 有一个单独的“init”方法。当我在Excel / VBA中采用面向对象的方法时,我更喜欢在常规函数中隐藏对象创建和init。所以我有mkFoo(parm)并调用它来获取Foo实例。 mkFoo()将创建一个New Foo实例并调用Foo.init()。如果您只是以这种方式创建实例,则无需检查您的实例是否已经反复初始化。

如果您真的想要正确并且没有提供暴露可能现在危险的init()方法的对象,那么您可以拥有由Foo实现的IFoo接口(没有init方法)。然后mkFoo()返回一个IFoo,实际Foo的任何用户都根本看不到init()方法。

当然,现在你有一堆模块只用于Foo - 一个用于IFoo,一个用于每个实际的Foo类,一个用于你的“Foo工厂”功能...因此我的评论这是众多原因之一为什么VBA中的OOP是PITA,即使它有时很有用。

编辑:这是onedaywhen在原始答案后不久编辑的一个编辑,但我刚刚将它单独删除,因为它实际上是一个单独的想法:

说到Excel,您可以将Foo类重定位到.xla加载项中,并使类PublicNotCreateable。公共函数mkFoo(parm)可以驻留在加载项中的标准.bas模块中,因此在C#中有点像静态类。这会强制客户端代码使用mkFoo作为创建Foo实例的唯一方法。毫无疑问,有一个MS Access类似于Excel的.xla加载项。

答案 2 :(得分:1)

不,无法使用VBA中的参数初始化类。这是不合法的,因为Dim ... As New ... statement在首次访问时隐式构造对象。

Dim x As New MyClass

x.Prop = 42 ' Before x.Prop is set, x is implicitly constructed

答案 3 :(得分:0)

类构造函数方法和重载类构造函数 在Visual Basic 6.0中,名为Class_Initialize的类Initialize事件处理程序用于执行在创建对象时需要执行的代码。

在Visual Basic 2005中,将一个或多个构造函数添加到类中以执行代码并初始化变量。构造函数是类中名为New的方法。可以重载New方法,以在同一个类语句中提供名为New的多个构造函数。

有关详细信息,请参阅New (Visual Basic) or Using Constructors and Destructorshttp://msdn.microsoft.com/en-us/library/55yzhfb2(v=vs.80).aspx

相关问题