Solved

Create New Data-Filled Class

Posted on 2001-06-18
13
214 Views
Last Modified: 2013-11-23
my memory is failing me...but is it possible to create a new instance of a class, and have that new instance "inherit" all of the property values of an existing class, and still have those two objects co-exist as separate entities?  e.g.,

say there is a class called Class1
p_clsPublic is a public variable of Class1 already containing property values

Dim clsNew As New Class1

'like this, but where clsNew and p_clsPublic will not be pointing to the same memory space
Set clsNew = p_clsPublic  

it seems this should be allowed via the CopyMemory API (or maybe not).  is it possible?  i realize the use of non fixed-length strings causes problems, such as when you want to employ this method with UDTs.

is there an efficient workaround other than writing a routine that does a property-by-property assignment of these values?
0
Comment
Question by:AzraSound
13 Comments
 
LVL 4

Expert Comment

by:beckingh
ID: 6204317
<listening>

I've always done property by property assignment but it'd be nice to have a generic routine to do this.
0
 
LVL 2

Expert Comment

by:TravisHall
ID: 6204381
As far as I know, you can't do this without writing a routine that does a property-by-property assignment of values. However, you can (I think) write that routine as a method of the class itself. Then, whenever you need to do it somewhere in other code, you just call that method on one of the objects, passing the other object as a parameter (ByRef, of course).

In C++, you'd write an assignment operator to handle it, and maybe a copy constructor, but VB doesn't let you have that kind of power.

(Caveat: In some cases, you possibly could use CopyMemory to do your copy, but if you use any strings, variants or anything else that hides pointers, you may run into trouble trying that.)
0
 
LVL 2

Expert Comment

by:TravisHall
ID: 6204394
Actually, just to add to my previous comment, you can create a method which creates and returns a copy of the original object (rather than just doing the assignment of properties on an existing object passed as a parameter). In the code module for Class1, put:

Public Function MakeCopy() As Class1
Set MakeCopy = New Class1
'Set properties here
End Function


That's probably about as close as you get to a copy constructor in VB.
0
 
LVL 28

Author Comment

by:AzraSound
ID: 6204439
i am thinking that this is correct, but i have seen the "impossible" accomplished several times in this forum, and it would be nice if this were one of those times.  i'll give it a bit longer...
0
 
LVL 2

Expert Comment

by:TravisHall
ID: 6204454
Fair enough. Bear in mind, though, that a copy constructor in C++ will basically set each member variable (that is, property) of the new object in turn - basically what you are trying to avoid here. I find that, as a general rule, if you can't (or don't) do something in C++, you can't (or shouldn't) do it in VB.
0
 
LVL 28

Author Comment

by:AzraSound
ID: 6204485
ok, i forgot about using the tlbinf32.dll.  here is how you COULD do it (used class builder for quick sample, dont mind the messy code):


'-- Class code
'local variable(s) to hold property value(s)
Private mvarTest1 As Single 'local copy
Private mvarTest2 As Variant 'local copy
Private mvarTest3 As String 'local copy
Public Property Let Test3(ByVal vData As String)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Test3 = 5
    mvarTest3 = vData
End Property


Public Property Get Test3() As String
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Test3
    Test3 = mvarTest3
End Property



Public Property Let Test2(ByVal vData As Variant)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Test2 = 5
    mvarTest2 = vData
End Property


Public Property Set Test2(ByVal vData As Variant)
'used when assigning an Object to the property, on the left side of a Set statement.
'Syntax: Set x.Test2 = Form1
    Set mvarTest2 = vData
End Property


Public Property Get Test2() As Variant
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Test2
    If IsObject(mvarTest2) Then
        Set Test2 = mvarTest2
    Else
        Test2 = mvarTest2
    End If
End Property



Public Property Let Test1(ByVal vData As Single)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Test1 = 5
    mvarTest1 = vData
End Property


Public Property Get Test1() As Single
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Test1
    Test1 = mvarTest1
End Property


Public Sub MakeCopy(ObjectCopy As Class1)
    Dim TLInfo  As TLI.InterfaceInfo
    Dim SR      As TLI.SearchResults
    Dim SI      As SearchItem
    Dim iIK     As Integer

    'grab info from object
    Set TLInfo = TLI.InterfaceInfoFromObject(Me)
    Set SR = TLInfo.Members.GetFilteredMembers(False)
   
   
    'loop through attribute members of the object
    For Each SI In SR
        iIK = SI.InvokeKinds
   
        If iIK And 4 Then
            'copy value over
            Call CallByName(ObjectCopy, SI.Name, VbLet, CallByName(Me, SI.Name, VbGet))
        End If
   
    Next

End Sub



'-- test Form code
Dim c1 As Class1

Private Sub Command1_Click()
    Dim c1copy As New Class1
   
    Call c1.MakeCopy(c1copy)
   
    c1copy.Test3 = "me"
   
    MsgBox c1.Test3
    MsgBox c1copy.Test3
End Sub

Private Sub Form_Load()
    Set c1 = New Class1
   
    c1.Test1 = 20
    c1.Test2 = "Nothing"
    c1.Test3 = "help"
End Sub

Private Sub Form_Unload(Cancel As Integer)
     Set c1 = Nothing
End Sub



so now my question is, what are the issues regarding tlbinf32.dll?  is it distributable?  does it come standard as part of any OSes? etc...
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 28

Author Comment

by:AzraSound
ID: 6204507
ok i've found references that say tlbinf32.dll is unsupported (which i knew) but that it IS indeed redistributable.  anyone got some documentation that can back this up?  or give me a good reason why this is not a good route to take.
0
 
LVL 5

Expert Comment

by:gbaren
ID: 6204602
I have seen CopyMemory used to duplicate an object to another of the same class. If I can only remember where...

0
 
LVL 2

Accepted Solution

by:
TravisHall earned 50 total points
ID: 6204683
Hmmm... Okay, so you are still doing the assignment property by property, it's just that you are using COM interfaces to determine what properties have to be copied.

The big problem that jumps out at me is the fact that your code isn't complete. You haven't handled properties which are object references. You can probably have it do that, just checking INVOKE_PROPERTYPUTREF (8) as well as INVOKE_PROPERTYPUT (4). Whether you supply the new object with a reference to the same sub-object (so to speak) as the original object, or create copy of the sub-object, is a question to deal with for the individual class.

Also, it will break if you have any write-only properties. You'd have to be careful of properties with "side-effects", too. (And I find I use "side-effects" quite often.)

Finally (for now), this will be less efficient than coding the property assignments directly, as CallByName is slightly less efficient than late-binding, and if you code it directly you get early-binding performance.
0
 
LVL 28

Author Comment

by:AzraSound
ID: 6204689
just to clear things up, i am not trying to avoid a property-by-property assignment "under the covers", or looking at the speediest method.  i was in search of something i could use to automate this task as much as possible.  the current project i am working on has several classes, each with tons of properties.  i will need to be creating many instances of these classes that all load with default values obtained from a global instance of these classes (which varies depending on the input data).

after spending hours just writing out all the properties for these classes, i wanted to avoid, at all costs, any further coding, by hand, that required specifying each and every property again.  i suppose this was more of an attempt to save my little fingers if anything.

i appreciate all the comments.  i was aware of some of the possible problems with my snippet (it was just a small sample) and it would need some tailoring to be made useful as a general construct.  luckily, no write-only properties exist, and all the properties are either strings or some sort of numeric value.

with that said, i guess it would be best to use the type library information component in a separate program, to create this long MakeCopy method for me which would read precisely as a property-by-property approach.  all those in favor say "ay"...
0
 
LVL 28

Author Comment

by:AzraSound
ID: 6204740
i think i will just plug something like this in tomorrow to get the results:

Public Function MakeCopy() As String
    Dim TLInfo  As TLI.InterfaceInfo
    Dim SR      As TLI.SearchResults
    Dim SI      As SearchItem
    Dim iIK     As Integer
    Dim sBuff   As String
   
    sBuff = "Public Function MakeCopy() As Class1" & vbCrLf
    sBuff = sBuff & vbTab & "Dim clsObj As New Class1" & vbCrLf & vbCrLf & vbCrLf
    sBuff = sBuff & vbTab & "With clsObj" & vbCrLf

    'grab info from object
    Set TLInfo = TLI.InterfaceInfoFromObject(Me)
    Set SR = TLInfo.Members.GetFilteredMembers(False)
   
   
    'loop through attribute members of the object
    For Each SI In SR
        iIK = SI.InvokeKinds
   
        If iIK And 4 Then
            'build string
            sBuff = sBuff & vbTab & vbTab & "." & SI.Name & " = Me." & SI.Name & vbCrLf
        End If
   
    Next

    sBuff = sBuff & vbTab & "End With" & vbCrLf & "End Function"
    MakeCopy = sBuff
End Function


then i can just copy and paste its output into my classes for use.  thanks for the input everyone.
0
 
LVL 28

Author Comment

by:AzraSound
ID: 6211561
thanks for the input.  i decided to just create a function that did the property-by-property assignment, but used the typelib info dll to automate that task for me.
0
 
LVL 4

Expert Comment

by:Nazdor
ID: 6647295
Just a quick note as this is an old question: You could do your automation via an IDE addin and not use tlbinf32 which would have numerous benefits, including not having to copy and paste code.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

26 Experts available now in Live!

Get 1:1 Help Now