Home > Mobile >  Excel vba - class constructor method not working, debug error
Excel vba - class constructor method not working, debug error

Time:04-05

i have this class and i am trying to make a class constructor or factory method (not sure how's the right name in VBA). When i try to run it i get a dialog with written debug error, and ig highlights the set row of the test module. What's wrong? What is the right way to instantiate the collection in the constructor? is it better to use the keyword this when using let/get ?

Class Address

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 Person

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

test Module

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

CodePudding user response:

You have several errors

  1. Your anonymous new is for GiantCorp and Not Person
  2. You have no self method to return the Me Instance created by the With New Person 3 No idea what 'instance' is doing.
  3. Your address class does not manage a collection of addresses, nor does you person class

Here is updated code for your person class. Don't feel too bad, Factory classes in VBA are actuall a tricky subject when you first encounter them.

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

You will also need to set the PredeclaredId attribute. This involves either exporting you class, editing the relevant attribute and reimporting, or, much more conveniently, using the attribute annotation '@PredecaredId provided by the free and fantastic Rubberduck add in for VBA.

Good luck in creating an addresses collection class to manage you addresses. Lots of examples are available of how to wrap a collection to produce a collection class.

CodePudding user response:

Another option for creating a factory method is to use another class:

PersonFactory Class

Option Explicit

Public Function Create(ByVal Name As String, ByVal Surname As String) As Person
   Set Create = New Person
   Create.Name = Name
   Create.Surname = Surname
End Function

Test Module

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