Results 1 to 8 of 8

Thread: Collection holds only last object, very important, please help

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 1999
    Location
    Ont, Canada, Earth
    Posts
    458

    Exclamation

    Hi,
    I'd really appreciate if someone could help me with this.
    I have a simple program with 1 class - CPerson which has 3 properies:
    -Name
    -Phone
    -Age

    Thanks for taking the time


    This is the way program should work:
    1.Open PHONES.TXT and read in all records (in a loop) into variables. The file has 5 records in this format:
    "John","888-6345",21 (name, phone, age). Each time a record is read-in, add object to collection (People.Add Person)
    2.Assing variables to properties of object Person(Name,Phone,Age)
    3.Add current object to collection
    4.Ask user for a name to search
    5.In a For-Next loop go through the entire collection and search for user's specified name

    The problem is that when I read back contents of the collection, only last object is in it.
    Please help, I don't know what's wrong.


    'FORM CODE
    '-------------------------------------------------
    Code:
    Option Explicit
    
    Private Person As CPerson
    Dim People As New Collection
    
    
    Private Sub cmdRequestPerson_Click()
        Set Person = New CPerson
        
        Dim strPersonName As String
        Dim ctr As Integer
        Dim intFileNumber As Integer
        
        ' Temp variables for reading file
        Dim sName As String
        Dim sPhone As String
        Dim iAge As Integer
        
        ' Read Persons.txt in to a collection
        intFileNumber = FreeFile
        
        ' Read name, phone, age for all poeple in the file
        Open "Phones.txt" For Input As intFileNumber
        Do While (Not (EOF(intFileNumber)))
            Input #intFileNumber, sName, sPhone, iAge
            
            ' Fill object w. latest record
            Person.Name = sName
            Person.Phone = sPhone
            Person.Age = iAge
            
            ' Add current object to collection
            People.Add Person
            
        Loop
        Close #intFileNumber
        
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    txtAllPeople = People.Item(3).Name
    
    'AT THIS POINT THERE SHOULD BE 3rd RECORD FROM THE FILE
    'IN THE txtAllPeople TextBox, BUT THE ENTIRE COLLECTION
    'HOLDS FIFTH RECORD
    'The collection doesn't hold assinged data
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        ' Get Person's name from user
        strPersonName = InputBox("Enter Person's name")
        
        ' Go thourgh the collection & find requested name
        For ctr = 1 To People.Count
            If strPersonName = People.Item(ctr).Name Then
                txtPersonInfo = People.Item(ctr).Name & _
                                People.Item(ctr).Age
                Exit Sub
            End If
        Next ctr
        
        ' Destroy object
        Set Person = Nothing
    End Sub
    
    
    
    'CLASS CODE
    '-------------------------------------------------
    
    Option Explicit
    
    Private m_Name As String
    Private m_Phone As String
    Private m_Age As Integer
    
    
    Property Let Name(vName As String)
        m_Name = vName
    End Property
    
    Property Get Name() As String
        Name = m_Name
    End Property
    
    
    Property Let Phone(vPh As String)
        m_Phone = vPh
    End Property
    
    Property Get Phone() As String
        Phone = m_Phone
    End Property
    
    
    Property Let Age(vAge As Integer)
        m_Age = vAge
    End Property
    
    Property Get Age() As Integer
        Age = m_Age
    End Property
    Thanks

    Tomexx.

  2. #2
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Youre actually adding the same object and destroying the old one as you reassign it.

    What you need to do is to declare person within the procedure instead
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 1999
    Location
    Ont, Canada, Earth
    Posts
    458
    Thanks Kedaman,
    I'm a beginner, can you give me an example.
    Thanks

    Tomexx.

  4. #4
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221

    Red face feeling really stupid

    aah, sometimes you first have to do post something before you do the test, sorry about that...

    The problem is that cperson holds the original person all the way in your loop. The collection is just a bunch of references to cperson, in īthat's why they have all the same Values

    put this line
    Set Person = New cperson
    after
    People.Add Person

    and the old reference will be only in the collection
    should work! just tested

    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 1999
    Location
    Ont, Canada, Earth
    Posts
    458
    Works!
    ...but I'm creating Person twice (once at the top of procedure and second time afte People.Add) and destroying it only once - before leaving the sub.

    Is this OK? Shouldn't I be destroying twice as well?
    Thanks

    Tomexx.

  6. #6
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Actually youre creating the object all the time while reading the file, but each time you create the new one, the old one will not be destroyed, (as i first thought your problem was) the object reference will only point to the new object instead. When you unload it in the end, the variable will be empty and your collection will have all the persons.

    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 1999
    Location
    Ont, Canada, Earth
    Posts
    458

    HeSaidJoe or anyone else - Collections problem

    Hi,
    This code works... but I don't understand why do I have to do: Set Person As Cperson twice. First I do it at the top of the procedure, then I DO IT AGAIN AFTER adding the object to collection. Why?

    Also, since I'm Set(ting) it twice, shouldn't I destroy it twice as well (Set Person = Nothing). I only do it at the bottom.

    Thanks.



    Code:
    Option Explicit
    
    Dim People As New Collection
    Private Person As CPerson
    
    
    Private Sub cmdRequestPerson_Click()
        Set Person = New CPerson
        
        Dim strPersonName As String
        Dim ctr As Integer
        Dim intFileNumber As Integer
        
        ' Temp variables for reading file
        Dim sName As String
        Dim sPhone As String
        Dim iAge As Integer
        
        ' Read Persons.txt in to a collection
        intFileNumber = FreeFile
        
        ' Read name, phone, age for all poeple in the file
        Open "Phones.txt" For Input As intFileNumber
        Do While (Not (EOF(intFileNumber)))
            Input #intFileNumber, sName, sPhone, iAge
            
            ' Fill object
            Person.Name = sName
            Person.Phone = sPhone
            Person.Age = iAge
            
            ' Add current object to collection
            People.Add Person
    
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' WHY DO I HAVE TO SET NEW OBJECT HERE AGAIN???????????
    ' I ALREADY SET IT UP AT THE TOP OF SUB
            Set Person = New CPerson
    
    
            
        Loop
        Close #intFileNumber
        
        
        ' Get Person's name from user
        strPersonName = InputBox("Enter Person's name")
        
        ' Go thru the collection & find requested Person's age
        For ctr = 1 To People.Count
            If strPersonName = People.Item(ctr).Name Then
                msgbox People.Item(ctr).Name & vbTab & _
                       People.Item(ctr).Age
                Exit Sub
            End If
        Next ctr
        
        ' Destroy object
        Set Person = Nothing
    End Sub
    Thanks

    Tomexx.

  8. #8
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    btw, you could remove both

    Set Person = New CPerson

    and place one after

    Input #intFileNumber, sName, sPhone, iAge

    As i said, you don't need to set the person to nothing all the time in between since the object reference will be replaced automatically. The persons will unload when you remove them from the collection.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

Posting Permissions

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



Click Here to Expand Forum to Full Width