473,503 Members | 2,076 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why can't I copy a collection class from one instance to another?

Either I don't understand (entirely possible), or there's no way to
copy parts of a class hierarchy from one instance to another.

Say I have a class called Foo, and it contains, among other things, a
custom collection called SubFoos. If I do something like

Dim MyFoo1 As Foo
Dim MyFoo2 As Foo

'call something to populate MyFoo1 and its SubFoos...

Debug.Print MyFoo1.SubFoos.Count

'pretend it's, say, 18. What a lot of SubFoos!

Set MyFoo2 = MyFoo1

Set MyFoo1 = Nothing

Debug.Print MyFoo2.SubFoos.Count

The last line will always give me 0. The only way, it seems, to copy
the members of the SubFoos collection from MyFoo1 to MyFoo2 is to
iterate through it, and add each one. And yet all the Foo-level stuff
is there.

I think this has something to do with pointers and other such "real"
"programming" notions that I have never learned, but still, frankly, it
blows. What's the point of building all that sexy self-enforcing
structure only to have to turn around and walk it like a plain old
recordset or whatever when you want a simple copy? Is this an
Access/VBA problem, or is it common to all programming languages? Or
am I just too green to get it?

Apr 14 '06 #1
8 9613

You don't give the implementation details or your collection class but I'm
guessing your doing something like exposing the collection as a public
member of the class. If so this is wrong, the collection should be private
to the class and you then provide methods of the class to manipulate the
collection.

The following is a very simple example of a collection class implementation
(I've omitted the Item and Remove methods for clarity).
Foo Class
=========
Option Explicit

Private SubFoos As Collection

Sub Add(RHS As Object)
If SubFoos Is Nothing Then
Set SubFoos = New Collection
End If
SubFoos.Add RHS
End Sub

Function Count() As Long
Count = SubFoos.Count
End Function

=========

Test Code
=========
Function TestFoo()
Dim MyFoo1 As Foo
Dim MyFoo2 As Foo
Dim MyObj As Object
Dim intX As Integer

Set MyFoo1 = New Foo

For intX = 1 To 10
MyFoo1.Add MyObj
Next
Debug.Print MyFoo1.Count

Set MyFoo2 = MyFoo1
Debug.Print MyFoo1.Count, MyFoo2.Count

Set MyFoo1 = Nothing
Debug.Print MyFoo2.Count
Set MyFoo2 = Nothing

End Function

=========

Results
=========
10
10 10
10

=========
--

Terry Kreft
"downwitch" <do*******@gmail.com> wrote in message
news:11**********************@z34g2000cwc.googlegr oups.com...
Either I don't understand (entirely possible), or there's no way to
copy parts of a class hierarchy from one instance to another.

Say I have a class called Foo, and it contains, among other things, a
custom collection called SubFoos. If I do something like

Dim MyFoo1 As Foo
Dim MyFoo2 As Foo

'call something to populate MyFoo1 and its SubFoos...

Debug.Print MyFoo1.SubFoos.Count

'pretend it's, say, 18. What a lot of SubFoos!

Set MyFoo2 = MyFoo1

Set MyFoo1 = Nothing

Debug.Print MyFoo2.SubFoos.Count

The last line will always give me 0. The only way, it seems, to copy
the members of the SubFoos collection from MyFoo1 to MyFoo2 is to
iterate through it, and add each one. And yet all the Foo-level stuff
is there.

I think this has something to do with pointers and other such "real"
"programming" notions that I have never learned, but still, frankly, it
blows. What's the point of building all that sexy self-enforcing
structure only to have to turn around and walk it like a plain old
recordset or whatever when you want a simple copy? Is this an
Access/VBA problem, or is it common to all programming languages? Or
am I just too green to get it?

Apr 14 '06 #2
"downwitch" <do*******@gmail.com> wrote in message
news:11**********************@z34g2000cwc.googlegr oups.com...
Either I don't understand (entirely possible), or there's no way to
copy parts of a class hierarchy from one instance to another.

Set MyFoo2 = MyFoo1


Unfortunately, there is no object clone method in access...

You can prevent the object from going out of scope like

So, in the above...you just are pointing MyFoo2 to MyFoo1...

However!!..if you create a new instance of the object FIRST and then set it
to the previous ..you get a copy of the pointer..but NOT the data!!

So, change the above to

set MyFoo2 = new Foo

set MyFoo2 = MyFoo1
set MyFoo1 = nothing....

At this point, you CAN now still use MyFoo2. However, this will NOT SOLVE
your problem. They are still both the SAME object...if you change one..the
other changes. (but, now we only got one since the use of the =
nothing...but they are NOT independent).

Unfortunately, this means you have to write your own clone method of the
class....

you can use

public function myClone as Foo

dim f as new foo

f.m_BollingPoint = me.m_BollingPoint
......et.c etc. etc...

You have to write one line of code to for everything and peiice of data your
have....

set MyClone = f

end function.

Then, you can go

dim antoherFoo as new foo

set anotherFoo = myFoo1.MyClone

--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
pl*****************@msn.com
http://www.members.shaw.ca/AlbertKallal
Apr 14 '06 #3
In place of the = nothing...try changing the value of one of the
objects....you will see that the other changes....

eg:

Set MyFoo2 = MyFoo1
Debug.Print MyFoo1.Count, MyFoo2.Count

MyFoo1.Add MyObj <--- add this

Set MyFoo1 = Nothing

Debug.Print MyFoo2.Count
Set MyFoo2 = Nothing

you will get a value of 11 for the above last print....despite the first
object being set = nothing...

When you set MyFoo1 = nothing...you are killing the pointer...but they both
are still the same copy.....

Try adding one value to the first one BEFORE you do a set MyFoo1 =
nothing...and you will STILL find the 2nd instance will have that new
value...

You have to write code to copy the class......

--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
pl*****************@msn.com
http://www.members.shaw.ca/AlbertKallal
Apr 14 '06 #4
rkc
downwitch wrote:
Either I don't understand (entirely possible), or there's no way to
copy parts of a class hierarchy from one instance to another.


You should really post actual code that you have tried
for something like this. I don't see the behaviour you
describe so it's must be your implementation.

<clsStuff>
Option Compare Database
Option Explicit

Private stuff As VBA.Collection
Private index As Long

Public Function NextStuff() As Variant
index = index + 1
If index <= stuff.count Then
NextStuff = stuff(index)
End If
End Function

Public Function HasMoreStuff() As Boolean
HasMoreStuff = index < stuff.count
End Function

Public Sub ResetStuff()
index = 0
End Sub

Public Sub AddStuff(v As Variant)
stuff.Add v
End Sub

Private Sub Class_Initialize()
Set stuff = New VBA.Collection
End Sub

Private Sub Class_Terminate()
Set stuff = Nothing
End Sub
</clsStuff>

<Test Form>
Option Compare Database
Option Explicit

Dim stf2 As clsStuff

Sub TestStuff()
Dim stf As clsStuff

Set stf = New clsStuff
Set stf2 = New clsStuff

With stf
.AddStuff "Thing One"
.AddStuff "Thing Two"
.AddStuff "Thing Three"
While .HasMoreStuff
Debug.Print .NextStuff
Wend
Set stf2 = stf
Set stf = Nothing
End With

Set stf = Nothing

End Sub

Sub ShowStuff2(stf As clsStuff)
stf.ResetStuff
While stf.HasMoreStuff
Debug.Print "2: "; stf.NextStuff
Wend
End Sub

Private Sub Command0_Click()
Call TestStuff
End Sub

Private Sub Command1_Click()
Call ShowStuff2(stf2)
End Sub

</Test Form>
Apr 14 '06 #5
This is the point. The other posts don't show the key thing here,
which is that even though you can set an Instance2 to _point to_ an
Instance1, it's not because you say "make Instance1 nothing" that it
truly goes away. In other words, it's not a clone, it's two pointers
to the same single object.

I would've posted real code, but (1) my class hierarchies are
hydra-like, huge, and impossible, and (2) I am more interested in the
theoretical wrongheadedness of why Access/VBA doesn't do this properly,
and (less importantly) if this is common to classes in other
programming environments. Besides, Albert nailed it with his simple
addition to Terry's code: change one, you change the other, meaning
there's one, not two. Still a slightly different question from why
public instances of the same class collection can't be set to equal
each other, but the two phenomena must be linked; if you could make a
proper clone of an instance, then you could reasonably expect to make a
proper clone of a part of an instance.

Is this different from working with, say, two string variables, or is
it all just pointers? At what point does something really get
"created"?
Albert D. Kallal wrote:
In place of the = nothing...try changing the value of one of the
objects....you will see that the other changes....

eg:

Set MyFoo2 = MyFoo1
Debug.Print MyFoo1.Count, MyFoo2.Count

MyFoo1.Add MyObj <--- add this

Set MyFoo1 = Nothing

Debug.Print MyFoo2.Count
Set MyFoo2 = Nothing

you will get a value of 11 for the above last print....despite the first
object being set = nothing...

When you set MyFoo1 = nothing...you are killing the pointer...but they both
are still the same copy.....

Try adding one value to the first one BEFORE you do a set MyFoo1 =
nothing...and you will STILL find the 2nd instance will have that new
value...

You have to write code to copy the class......

--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
pl*****************@msn.com
http://www.members.shaw.ca/AlbertKallal


Apr 15 '06 #6
rkc
downwitch wrote:
This is the point. The other posts don't show the key thing here,
which is that even though you can set an Instance2 to _point to_ an
Instance1, it's not because you say "make Instance1 nothing" that it
truly goes away. In other words, it's not a clone, it's two pointers
to the same single object.

I would've posted real code, but (1) my class hierarchies are
hydra-like, huge, and impossible, and (2) I am more interested in the
theoretical wrongheadedness of why Access/VBA doesn't do this properly,
and (less importantly) if this is common to classes in other
programming environments. Besides, Albert nailed it with his simple
addition to Terry's code: change one, you change the other, meaning
there's one, not two. Still a slightly different question from why
public instances of the same class collection can't be set to equal
each other, but the two phenomena must be linked; if you could make a
proper clone of an instance, then you could reasonably expect to make a
proper clone of a part of an instance.

Is this different from working with, say, two string variables, or is
it all just pointers? At what point does something really get
"created"?


I did completely miss your actual question.
In Visual Basic/VBA there is no built into the language way
of creating an independent clone of an object. You have to
do what you don't think you should have to do. That is to copy
the actual base data piece by piece.

You can ponder it till the end of time, but that's the way it is.

Apr 15 '06 #7
>if this is common to classes in other
programming environments.

Yes, it is common to true object programming environments. You often have to
still write a clone method, but the properties and methods of the object
*usually* can be un-corked out to a serialized string that can be saved (in
fact, we call this serialization). It is this "string" of data that can
then be loaded back into the object.

This gives two benefits.

you can actually "save" the state of the object to your hard disk..and
next time you run the program...re-load the object. Thus, you can actually
use objects, and save them to a database, or even a file on hard disk.

The side benefit of this serialization process is that the code to clone
a object his thus very easy to write....

And, even more important, with web based services...you can *transfer* a
object across the connection this way.

So, if the language at hand does not support clone of the object (not all
do), but does support what we call serialization, then cloning is easy
anyway...

We have neither clone, nor serialization available in VB, or ms-access,
which by the way is the same as VB6...

You do have serialization in vb.net however.....
--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
pl*****************@msn.com
http://www.members.shaw.ca/AlbertKallal
Apr 18 '06 #8
OK, I thought it was fairly obvious what was on from my example.

A class variable contains a pointer to a piece of memory, initially this is
null but when you instantiate it using the New keyword (or CreateObject)
then a piece of memory is set aside for the class an the variable is set to
point to this piece of memory.

If you have a second variable which you set equal to an existing class
variable then you are copying the value of that variable, that is you are
copying the pointer to the memory which holds the class information. So you
aren't creating a copy of the class you are creating a copy of the pointer
to the class.

In order to create a copy of the class you would need to do one of two
things.
a)
instantiate a new class object
copy all the property values from the original to the new class
object

This isn't so difficult if you implement a properties collection on the
class

You could in theory
b)
instantiate a new class object
determine the length of memory containing the class data of the
original
copy the memory block of the original class data over the new class
data

This would involve a fair amount of API work.

--

Terry Kreft
"downwitch" <do*******@gmail.com> wrote in message
news:11**********************@i40g2000cwc.googlegr oups.com...
This is the point. The other posts don't show the key thing here,
which is that even though you can set an Instance2 to _point to_ an
Instance1, it's not because you say "make Instance1 nothing" that it
truly goes away. In other words, it's not a clone, it's two pointers
to the same single object.

I would've posted real code, but (1) my class hierarchies are
hydra-like, huge, and impossible, and (2) I am more interested in the
theoretical wrongheadedness of why Access/VBA doesn't do this properly,
and (less importantly) if this is common to classes in other
programming environments. Besides, Albert nailed it with his simple
addition to Terry's code: change one, you change the other, meaning
there's one, not two. Still a slightly different question from why
public instances of the same class collection can't be set to equal
each other, but the two phenomena must be linked; if you could make a
proper clone of an instance, then you could reasonably expect to make a
proper clone of a part of an instance.

Is this different from working with, say, two string variables, or is
it all just pointers? At what point does something really get
"created"?
Albert D. Kallal wrote:
In place of the = nothing...try changing the value of one of the
objects....you will see that the other changes....

eg:

Set MyFoo2 = MyFoo1
Debug.Print MyFoo1.Count, MyFoo2.Count

MyFoo1.Add MyObj <--- add this

Set MyFoo1 = Nothing

Debug.Print MyFoo2.Count
Set MyFoo2 = Nothing

you will get a value of 11 for the above last print....despite the first
object being set = nothing...

When you set MyFoo1 = nothing...you are killing the pointer...but they both are still the same copy.....

Try adding one value to the first one BEFORE you do a set MyFoo1 =
nothing...and you will STILL find the 2nd instance will have that new
value...

You have to write code to copy the class......

--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
pl*****************@msn.com
http://www.members.shaw.ca/AlbertKallal

Apr 18 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
1691
by: Mark Buxbaum | last post by:
Hi, Is is possible to use a collection class instance as a helper object in a class? For example: MyClass.h: ---------- class MyClass {
7
7895
by: Steven.Xu | last post by:
Hello everyone! I have a problem about create an instance automatically in C#. Now I have a class: namespace1.namespace11.CClass01. I want to create it's instance in a function named...
6
1384
by: Gerard Flanagan | last post by:
Hello If I have the Vector class below, is there a means by which I can have the following behaviour >>>A = Vector(1, 2) >>>print A (1, 2) >>>A = 0
19
4890
by: Jamey Shuemaker | last post by:
I'm in the process of expanding my knowledge and use of Class Modules. I've perused MSDN and this and other sites, and I'm pretty comfortable with my understanding of Class Modules with the...
3
6227
by: Chris Pratt | last post by:
I'm sorry to ask such a fundamental question, but is it possible to create a copy of an object in VB.Net 2005? I have an app which, on load, creates an instance of a class, into which it reads a...
2
2121
by: TEK | last post by:
Hello We're having a issue with a part of our app that is very strange, and I'm unable to see that it should be possible. We have: A collection (ActivityCollection) that is inherited from a...
5
8237
by: DBC User | last post by:
I have 2 classes which are exactly same except the name. I do not have access to either of the class to change anything in it. In my code, I need to copy one of one class to another class. How can...
5
2150
by: Joseph Geretz | last post by:
Of course, I can store a C# class instance to the Server Cache (this.Context.Cache). I've tried it. My question is, will this destroy the scalability of my application? My background is VB6....
6
15294
by: ffreino | last post by:
Hi, I have a Solution with two different Projects. In one project, can I import a class from another project? It's something like: Solution mySolution ProjectA Class A1
0
7188
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7063
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7258
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6970
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5558
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4663
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3156
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3146
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
366
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.