Search code examples
vbaclassexceldictionaryclone

vba deep copy/clone issue with class object dictionary


I have a dictionary in my Main Sub (KEY = string; VALUE = Class Object). The Class Object consists of two dictionaries. As I collect data and check the values stored in the Dictionary Values (Class Object - dictionaries) I noticed that only the last values are getting stored. What I mean is that all the Values in my dictionary in my Main Sub are pointing to the same dictionary reference, hence, all the instances of my Class Objects contain the same data. This means that I need to make a clone of my Class Objects (deep copy?). I have successfully done this before with Class Objects that only stored simple values, but not with dictionaries. I need help cloning my Class Object that contains dictionaries.

MAIN SUB

Dim dGroup As New Scripting.Dictionary ' Main Dictionary
'
' loop thru a listbox
  For i = 0 To UserForm1.ListBox1.ListCount - 1
    Gname = UserForm1.ListBox1.List(i) ' get listbox names
' populate temp dictionary
    Set dic = FNC.GET_SESSION_FILE_ELEMENTS(mySesFile, Gname) 
'
' instantiate new Class Object
    Dim NewCol As New cVM_Col
    Call NewCol.INIT(dic) ' pass the dictionary to a 'constructor'
    dGroup.Add Gname, NewCol.CLONE ' add to the MAIN SUB dictionary
'
    Set dic = Nothing ' clear the temp dictionary
  Next i

CLASS OBJECT

Private dElms As Scripting.Dictionary 
Private dDat As Scripting.Dictionary 
'
Private Sub Class_Initialize()
  Set dElms = New Scripting.Dictionary
  Set dDat = New Scripting.Dictionary
End Sub
'
Public Sub INIT(inp As Scripting.Dictionary)
  Set dElms = inp
End Sub
'
Public Function CLONE()
  Set CLONE = New cVM_Col
  Set CLONE.dElms = dElms ' <-- THIS IS WHERE IT CRASHES
  Set CLONE.dDat = dDat
End Function

Normally my CLONE function works when I am only cloning simple data types like String or Long or Double. I've never had to do this with a Dictionary.


Solution

  • To CLONE the dictionary objects in my CLASS Objects I had to make the following changes:

    CLASS OBJECT (Modified CLONE function)

    Public Function CLONE()
      Set CLONE = New cVM_Col
      CLONE.Elms = dElms
      CLONE.Dat = dDat
    End Function
    

    (Added Properties)

    Public Property Get Elms() As Scripting.Dictionary
      Set Elms = dElms
    End Property
    Public Property Let Elms(p As Scripting.Dictionary)
      Set dElms = p
    End Property
    '
    Public Property Get Dat() As Scripting.Dictionary
      Set Dat = dDat
    End Property
    Public Property Let Dat(p As Scripting.Dictionary)
      Set dDat = p
    End Property