Domanda
Esiste un modo generico per clonare oggetti in VBA? In modo che potrei copiare x su y invece di copiare solo il puntatore?
Dim x As New Class1
Dim y As Class1
x.Color = 1
x.Height = 1
Set y = x
y.Color = 2
Debug.Print "x.Color=" & x.Color & ", x.Height=" & x.Height
Per generico intendo qualcosa come Set y = CloneObject (x)
piuttosto che dover creare il mio metodo per la classe copiando le sue proprietà una per una.
Soluzione
OK, ecco l'inizio di qualcosa che lo illustra:
Crea una classe, chiamala, oh, " Class1 " ;:
Option Explicit
Public prop1 As Long
Private DontCloneThis As Variant
Public Property Get PrivateThing()
PrivateThing = DontCloneThis
End Property
Public Property Let PrivateThing(value)
DontCloneThis = value
End Property
Ora dobbiamo dargli una funzione Clone. In un altro modulo, prova questo:
Opzione esplicita
Public Sub makeCloneable()
Dim idx As Long
Dim line As String
Dim words As Variant
Dim cloneproc As String
' start building the text of our new function
cloneproc = "Public Function Clone() As Class1" & vbCrLf
cloneproc = cloneproc & "Set Clone = New Class1" & vbCrLf
' get the code for the class and start examining it
With ThisWorkbook.VBProject.VBComponents("Class1").CodeModule
For idx = 1 To .CountOfLines
line = Trim(.lines(idx, 1)) ' get the next line
If Len(line) > 0 Then
line = Replace(line, "(", " ") ' to make words clearly delimited by spaces
words = Split(line, " ") ' so we get split on a space
If words(0) = "Public" Then ' can't set things declared Private
' several combinations of words possible
If words(1) = "Property" And words(2) = "Get" Then
cloneproc = cloneproc & "Clone." & words(3) & "=" & words(3) & vbCrLf
ElseIf words(1) = "Property" And words(2) = "Set" Then
cloneproc = cloneproc & "Set Clone." & words(3) & "=" & words(3) & vbCrLf
ElseIf words(1) <> "Sub" And words(1) <> "Function" And words(1) <> "Property" Then
cloneproc = cloneproc & "Clone." & words(1) & "=" & words(1) & vbCrLf
End If
End If
End If
Next
cloneproc = cloneproc & "End Function"
' put the code into the class
.AddFromString cloneproc
End With
End Sub
Eseguilo e quanto segue viene aggiunto in Class1
Public Function Clone() As Class1
Set Clone = New Class1
Clone.prop1 = prop1
Clone.PrivateThing = PrivateThing
End Function
... che sembra un inizio. Molte cose che avrei ripulito (e probabilmente lo farò - questo si è rivelato divertente). Una bella espressione regolare per trovare gli attributi gettable / lettable / settable, refactoring in diverse piccole funzioni, codice per rimuovere il vecchio "Clone" funzioni (e metti il ??nuovo alla fine), qualcosa di un po 'più Stringbuilder-ish da DRY (Don't Repeat Yourself) nelle concatenazioni, cose del genere.
Altri suggerimenti
Scott Whitlock ha pubblicato una risposta fantastica a questo problema su un'altra domanda.
Non penso che ci sia qualcosa incorporato, anche se sarebbe bello.
Penso che dovrebbe esserci almeno un modo per creare automaticamente un metodo Clone usando l'editor VBA. Vedrò se posso dargli un'occhiata una volta che avrò i bambini a letto ...