Friday, April 8, 2011

How to clone an object in VB6

I am trying to automatically clone an object without having to instantiate a new one and manually copy every single variable.

I remember back in the day (when I did VB6 everyday) I came up with a method of cloning objects using the PropertyBag, which was pretty cool. But I've lost the code and don't remember how to do it anymore.

Does anyone remember or have another method?

From stackoverflow
  • Method I have used in the past is putting all instance variables on a UDT. As long as you keep the UDT up to date you can copy a class' data with a single method/statement.

    Given a "Person" class here's a simple example:

    Private Type tPerson
        ID As Long
        FirstName As String
        LastName As String
    End Type  
    
    Private m_Person As tPerson  
    
    Public Sub InitPerson(ID As Long, FirstName As String, LastName As String)
        m_Person.ID = ID
        m_Person.FirstName = FirstName
        m_Person.LastName = LastName
    End Sub  
    
    Friend Sub SetData(PersonData As tPerson)
        m_Person = PersonData
    
    End Sub  
    
    Public Function GetClone() As Person
        Dim p As New Person
        p.SetData m_Person
    
        Set GetClone = p
    
    End Function  
    
    Public Property Get FirstName() As String
        FirstName = m_Person.FirstName
    
    End Property
    

    To try the code:

    Dim p As New Person
    p.InitPerson 1, "MyName", "MyLastName"
    
    Dim p2 As Person
    Set p2 = p.GetClone
    
    MsgBox p2.FirstName
    

    If you maintain all instance varianbles inside the UDT instead of declaring them seperately you can have simple Clone method that needs very little maintenance.

    Another advantage is you can put a UDT to a file handle for quick serialization to disk.

    Public Sub Save(filePathName As String)
        Dim f As Integer
        f = FreeFile()
    
        Open filePathName For Binary Access Write Lock Read Write As #f
            Put #f, , m_Person
        Close #f
    
    End Sub
    

    A poor men's serialization solution really :-)

    onedaywhen : Can you post some example code, please?
    Tungano : I editted my answer to include some
  • Is this what you were looking for? Article is copied below for posterity.

    Serialize Data Using a PropertyBag

    You can serialize your data quickly by placing it into a PropertyBag object, then reading the PropertyBags Contents property. This property is really a Byte array that is a serial representation of the data in your PropertyBag object. You can use this byte array for many purposes, including an efficient means of data transmission over DCOM:

    Private Function PackData() As String
        Dim pbTemp As PropertyBag
    
        'Create a new PropertyBag object
        Set pbTemp = New PropertyBag
        With pbTemp
         'Add your data to the PB giving each item a 
         'unique string key
         Call .WriteProperty("FirstName", "John")
         Call .WriteProperty("MiddleInitial", "J")
         Call .WriteProperty("LastName", "Doe")
    
         'Place the serialized data into a string 
         'variable.
         Let PackData = .Contents
        End With
    
        Set pbTemp = Nothing
    End Function
    

    To retrieve the serialized data, simply create a new PropertyBag object and set the serialized string to its Contents property. Convert the string into a byte array before assigning it to the Contents property:

    Private Sub UnPackData(sData As String)
        Dim pbTemp As PropertyBag
        Dim arData() As Byte
    
        'Convert the string representation of the data to 
        'a Byte array
        Let arData() = sData
    
        'Create a new PropertyBag object
        Set pbTemp = New PropertyBag
        With pbTemp
         'Load the PropertyBag with data
         Let .Contents = arData()
    
         'Retrieve your data using the unique key
         Let m_sFirstName = .ReadProperty("FirstName")
         Let m_sMiddleInitial = _
          .ReadProperty("MiddleInitial")
         Let m_sLastName = .ReadProperty("LastName")
        End With
    
        Set pbTemp = Nothing
          End Sub
    

    Mike Kurtz, McKees Rocks, Pa.

    garykindel : I like this solution. Thx
    AngryHacker : I guess, it's not as smooth as I remember. It basically still involves a lot of grunt code. Thanks.
  • Also read: Persisting a Component's Data.

  • Every object in my application's framework has a Read and Store method. What I do is pass them a stream that writes to a bytearray and store the byte array. While this doesn't eliminate having to handle every property you only have to deal with this once for reading and once for writing.

    An alternative is to use a property bag like Darrel Miller says but you still have to deal with each property separately. If you already have read and store then my suggestion should save some time.

0 comments:

Post a Comment