Solved

Create New Data-Filled Class

Posted on 2001-06-18
13
213 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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

743 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

10 Experts available now in Live!

Get 1:1 Help Now