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.

È stato utile?

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 ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top