Consulting

Results 1 to 13 of 13

Thread: Classes

  1. #1

    Classes

    Every time I run my test method I get the following error "Run-time error '91' Object variable or With block variable not set"

    What am I doing wrong



    This is the test class to test my person class
     
    Public Sub testClass()
        Dim p As Person
        Set p = New Person
        
        Dim d As Details
        Set d = New Details
        Set p.Details = d
        
        p.Details.Age = 20
        p.Details.Name = "chris"
    End Sub
    This is the Person Class
     
    Private pDetails As Details
    Public Property Get Details() As Details
        Details = pDetails
    End Property
    
    Public Property Set Details(value As Details)
        pDetails = value
    End Property

    This is the Details class
     
    Private pName As String
    Private pAge As Integer
    
    Public Property Get Name() As String
        Name = pName
    End Property
    
    Public Property Get Age() As Integer
        Name = pName
    End Property
    
    Public Property Let Name(ByVal value As String)
        pName = value
    End Property
    Public Property Let Age(ByVal value As Integer)
        pAge = value
    End Property
    
    Public Function toString() As String
        toString = pName & "," & pAge
    End Function
    Thanks in advance

    Chris

  2. #2
    Moderator VBAX Master austenr's Avatar
    Joined
    Sep 2004
    Location
    Maine
    Posts
    2,033
    Location
    You need a with block here (in red) i think

    [VBA]Public Sub testClass()
    Dim p As Person
    Set p = New Person

    Dim d As Details
    Set d = New Details
    Set p.Details = d
    With d
    p.Details.Age = 20
    p.Details.Name = "chris"
    End with
    End Sub[/VBA]
    Peace of mind is found in some of the strangest places.

  3. #3
    No debug is saying it is failing on the line Set p.Details = d

  4. #4
    Moderator VBAX Master austenr's Avatar
    Joined
    Sep 2004
    Location
    Maine
    Posts
    2,033
    Location
    Thats probably because you defined the variable as private which makes it only accessable to that function/sub.
    Peace of mind is found in some of the strangest places.

  5. #5
    yes but I have public get and set methods which I am using to acess the private object. Surely there is a better way to do this than declaring the object public?

    Chris

  6. #6
    Moderator VBAX Master austenr's Avatar
    Joined
    Sep 2004
    Location
    Maine
    Posts
    2,033
    Location
    Also are you sure this line is correct:

    [VBA]Private pDetails As Details[/VBA]

    If I copy your first bit of code into a module and debug it it errors on this line with the reason being"User defined type not defined"
    Peace of mind is found in some of the strangest places.

  7. #7
    They need to go in class modules and you will need the Details class as well. Then it should be ok

  8. #8
    Mac Moderator VBAX Guru mikerickson's Avatar
    Joined
    May 2007
    Location
    Davis CA
    Posts
    2,778
    The object p.Details has not been instancised.

    in the Person class, you need to intialize pDetails and use Set in the Property code.
    [VBA]Option Explicit

    Private pDetails As Details

    Public Property Get Details() As Details
    Set Details = pDetails
    End Property

    Public Property Set Details(value As Details)
    Set pDetails = value
    End Property

    Private Sub Class_Initialize()
    Set pDetails = New Details
    End Sub
    [/VBA]

    Edit: Also, Person should have a Terminate event that sets pDetails = Nothing.

  9. #9
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    You haven't loaded Details, so you will get an error. But why do you have Details and Person, seems superluous to me seeing as Person just points at Details.
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  10. #10
    Great, its working now thnaks

  11. #11
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    Would you still care to share with me why you are doing it this way. You have a calss with all of the properties, and another class that just wraps the first class. What is the point?
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  12. #12
    The point was just purely learning. I just wanted to figure out how to encapsulate a custom object in a class.

    Thanks for your help

  13. #13
    Mac Moderator VBAX Guru mikerickson's Avatar
    Joined
    May 2007
    Location
    Davis CA
    Posts
    2,778
    Actualy, my answer was incomplete.

    In the OP, the keyword Set has to be added to the Details property routines
    [VBA]Public Property Get Details() As Details
    Set Details = pDetails
    End Property

    Public Property Set Details(value As Details)
    Set pDetails = value
    End Property [/VBA]

    But, the Class_Initialize event I posted above is not needed. Whether or not to initialize pDetails (i.e. Set pDetails = New Details) relates to Xld's question "Why"?

    If the Object model is that each Person has its own Details, then the Person class should initialize pDetails.

    If the model is that Details exist independent of People and that the connection between People and Details is only formal, then it might be best not to initialize Details in the People class module.

    Consider Age. An Age = 3 years doesn't make sense. Age of what? Logically, Age can't be a stand alone object. The Object pAge should be initialized inside Person's class module

    Compare House. A House as an independent object makes sense. In an object model that allows one to say somePerson.House = thatHouse, it would be best if pHouse was initialized outside of the Person Class module

    If an ObjectA only makes sense if it is the a property of some ObjectB, then initializing ObjectA should take place inside ObjectB's code module.

    If an ObjectA makes sense independent of any ObjectB, then it might be better if initializing ObjectA and setting its properties outside of ObjectB's class module.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •