Excel vba - class 构造方法无效,调试错误

Excel vba - class constructor method not working, debug error

我有这个 class,我正在尝试创建一个 class 构造函数或工厂方法(不确定 VBA 中的正确名称)。当我尝试 运行 时,我得到一个包含调试错误的对话框,并且 ig 突出显示了测试模块的设置行。怎么了?在构造函数中实例化集合的正确方法是什么?使用 let/get 时使用关键字 this 是否更好?

Class地址

Private pStreet As String
Private pZip As Integer

Public Property Let Street(val As String)
   pStreet = val
End Property
Public Property Get Street() As String
   Street = pStreet
End Property
Public Property Let Zip(val As Integer)
   pZip = val
End Property
Public Property Get Zip() As Integer
   Zip = pZip
End Property

Class 人

Private pName As String
Private pSurname As String
Private pAddresses As New Collection

Public Property Let Name(val As String)
    pName = val
End Property
Public Property Get Name() As String
    Name = pName
End Property

Public Property Let Surname(val As String)
    pSurname = val
End Property
Public Property Get Surname() As String
    Surame = pSurname
End Property
Private Sub Class_Initialize()
    Set pAddresses = New Collection
End Sub
Private Sub Class_Terminate()
    Set pAddresses = Nothing
End Sub
Public Sub addAddress(ByVal val As Address)
    pAddresses.Add val
End Sub
Public Property Get Addresses() As Collection
    Set Addresses = pAddresses
End Property
Public Property Get Address(ByVal Index As Long) As Address
    Set Address = pAddresses(Index)
End Property

Public Function CreatePerson(ByVal Name As String, ByVal Surname As String) As Person
    With New Person
        .pName = Name
        .pSurname = Surname
        Set CreatePerson = .Self
        instance
    End With
End Function

测试模块

sub test()
Dim x as Person
Set x = Person.CreatePerson("Mike","Jordan")
end sub

你有几个错误

  1. 您的匿名新消息是针对 GiantCorp 而不是个人
  2. 您没有 return With New Person 创建的 Me 实例的 self 方法 3 不知道 'instance' 在做什么。
  3. 您的地址 class 不管理地址集合,您 class
  4. 也不管理

这是您的人的更新代码 class。别难过,VBA 中的工厂 classes 在您第一次遇到它们时实际上是一个棘手的主题。

Option Explicit
'@PredecalredId
'@exposed

Private Type Properties

    Name                As String
    Surname             As String
    Address             As Address
    
End Type

Private p               As Properties


Public Property Let Name(ipName As String)
    p.Name = ipName
End Property
Public Property Get Name() As String
    Name = p.Name
End Property

Public Property Let Surname(ipSurname As String)
    p.Surname = ipSurname
End Property
Public Property Get Surname() As String
    Surame = p.Surname
End Property

' This property will fail as the Address class is not a collection
Public Sub addAddress(ipAddress As Address)
   Set p.Address = ipAddress
End Sub

Public Function CreatePerson(ByVal ipName As String, ByVal ipSurname As String) As Person
    With New Person 'GiantComp  no idea what this GiantComp' class is doing here
        ' Private fields cannot be accessed here, you need to forward them to the self function
        '.pName = ipName
        '.pSurname = ipSurname
        Set CreatePerson = .Self(ipName, ipSurname)
    End With
End Function

Public Function Self(ByVal ipName As String, ByVal ipSurname As String) As Person
' You are now inside the anonymous Person class you created with 'With nEw Person' so you can now access private fields
    p.Name = ipName
    p.Surname = ipSurname
    Set Self = Me
End Function

您还需要设置 PredeclaredId 属性。这涉及导出 class、编辑相关属性并重新导入,或者更方便地使用属性注释 '@PredecaredId,该注释由免费且出色的 Rubberduck 插件提供 VBA.

祝您创建地址集合 class 来管理您的地址。关于如何包装集合以生成集合的示例有很多 class.

创建工厂方法的另一个选择是使用另一个 class:

个人工厂Class

Option Explicit

Public Function Create(ByVal Name As String, ByVal Surname As String, ByVal Street As String, ByVal Zip As Integer) As Person
   Dim a As Address
   
   Set Create = New Person
   Create.Name = Name
   Create.Surname = Surname
   
   Set a = New Address
   a.Street = Street
   a.Zip = Zip
   Create.Addresses.Add a
End Function

测试模块

Private Sub Test()
   Dim pf As PersonFactory
   Dim p As Person
   
   Set pf = New PersonFactory
   Set p = pf.Create("Mike", "Jordan", "my street", 11111)
End Sub