Collections updating each other

Fantast

Registered User.
Local time
Today, 16:52
Joined
Dec 13, 2011
Messages
41
Hi. I have this module class where one of the properties is a collection. At some points I want to be able to do the following to my class:

  1. fix the state of collection1 (stor it's content into collection2)
  2. do things with collection1
  3. reset collection1 to the value of collection2
The weird thing is that whenever I do things to collection1, collection2 changes along with it... So say I set collection2 to be empty and then add an item to collection1, for some reason the same item is now added to collection2 :confused: Either I misunderstand the way collections work or I have a really stupid mistake in my code I'm overlooking the whole time. Of course I could work my way around this problem, but I still would not understand what is going wrong here. Help would be mutch appriciated.


Class module:
Code:
Option Compare Database

Private cltActiveReports As Collection
Private cltActiveReportsReset As Collection



''''''''''''''''''''''''''''''''''''''''''''''
' cltActiveReports property
''''''''''''''''''''''''''''''''''''''''''''''
Public Property Get ActiveReportsCollection() As Collection
    Set ActiveReportsCollection = cltActiveReports
End Property
Public Property Let ActiveReportsCollection(cltNewActiveReports As Collection)
    Set cltActiveReports = Nothing
    Set cltActiveReports = New Collection
    Set cltActiveReports = cltNewActiveReports
End Property
Public Property Let AddActiveReport(Value As String)
    cltActiveReports.Add Value
End Property

''''''''''''''''''''''''''''''''''''''''''''''
' cltActiveReportsReset property
''''''''''''''''''''''''''''''''''''''''''''''
Public Property Get ActiveReportsCollectionReset() As Collection
    Set ActiveReportsCollectionReset = cltActiveReportsReset
End Property
Public Property Let ActiveReportsCollectionReset(cltNewActiveReports As Collection)
    Set cltActiveReportsReset = Nothing
    Set cltActiveReportsReset = New Collection
    Set cltActiveReportsReset = cltNewActiveReports
End Property


' initialize class: set default values
Private Sub Class_Initialize()
    Set cltActiveReports = New Collection
    Set cltActiveReportsReset = New Collection
End Sub

''''''''''''''''''''''''''''''''''''''''''''''
' SetResetPositionForm function
''''''''''''''''''''''''''''''''''''''''''''''
Public Sub SetResetPositionForm()
    Me.ActiveReportsCollectionReset = Me.ActiveReportsCollection
End Sub

''''''''''''''''''''''''''''''''''''''''''''''
' ResetFormClass function
''''''''''''''''''''''''''''''''''''''''''''''
Public Sub ResetFormClass()
    Me.ActiveReportsCollection = Me.ActiveReportsCollectionReset
End Sub
VBA Module:

Code:
Option Compare Database

Public Function testClt()

    ' Setup the form handler to store filtering and source data into
    Dim clsIBForm As New Class1
    
    clsIBForm.SetResetPositionForm
    
    Debug.Print "active reports 1:" & clsIBForm.ActiveReportsCollection.Count
    Debug.Print "reset reports 1:" & clsIBForm.ActiveReportsCollectionReset.Count
    
    clsIBForm.AddActiveReport = "Report1"
    
    ' This is the point were I would expect only the cltActiveReports property to be changed,
    ' but unfortunately cltActiveReportsReset appears to have changed as well.
    Debug.Print "active reports 2:" & clsIBForm.ActiveReportsCollection.Count
    Debug.Print "reset reports 2:" & clsIBForm.ActiveReportsCollectionReset.Count
    
    clsIBForm.ResetFormClass 'does not work unforyunately due to the changed cltActiveReportsReset collection
    
    Debug.Print "active reports 3:" & clsIBForm.ActiveReportsCollection.Count
    Debug.Print "reset reports 3:" & clsIBForm.ActiveReportsCollectionReset.Count
End Function
 
* Setting one object to the other (i.e. using the SET keyword) only points to the same address location so any changes you make on one will affect the other.
* If you want an exact copy of a collection, you need to loop through the collection and for each item add it to the other collection.
 
I see. So that would be the same for all pointer objects, right? So It is not possible to make a copy of a complete class to a second one, unless you copy the value of each property of that class to the other class?
 
I think we had this chat before, but just in case:

If you are married to this application until death do you part, then you can basically do anything you want. If this is code that is perhaps to be maintained by someone else in the future, then just remember that a huge number of people dabbling in Access are not well-versed in custom collections, classes, objects, etc. You obviously come from some other programming environment, but do take pity on those who might inherit your app :-)
 
I see. So that would be the same for all pointer objects, right? So It is not possible to make a copy of a complete class to a second one, unless you copy the value of each property of that class to the other class?
Yes, but any object that needs to be instantiated uses the Set keyword and that keyword doesn't clone. You can try passing it ByVal but I think you will still end up with the same pointer to the memory address of that object. The way to clone as object is to save it in a collection. And the only way to clone a collection is to loop through each item copying it over one by one.

Try not to make things too complicated, like spikepl mentioned.
 
I started the projects without custom classes and collections, but at some point the quantity of the code and the repetition in it forced me to change my mind and go for custom classes. Now I'm rewriting great leaps of it before moving on.

Thanks for the info, again :)
 
Last edited:

Users who are viewing this thread

Back
Top Bottom