2008-10-20 11 views
7

Czy istnieje ogólny sposób klonowania obiektów w języku VBA? Czy mogę skopiować x na y zamiast kopiować tylko wskaźnik?Klonowanie obiektów w VBA?

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 

rodzajowymi mam na myśli coś takiego Set y = CloneObject(x) zamiast stworzyć własną metodę kopiowania klasy jego właściwości, jeden po drugim.

Odpowiedz

6

OK, tu jest początek czegoś, co ilustruje to:

Utwórz klasę, nazwać, 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 

Teraz musimy nadać mu funkcję klonowania. W innym modułem, spróbuj tego:

Option Explicit

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 

metę, a następnego zostanie dodana do Class1

Public Function Clone() As Class1 
Set Clone = New Class1 
Clone.prop1 = prop1 
Clone.PrivateThing = PrivateThing 
End Function 

... która wygląda jak początek. Wiele rzeczy, które wyczyściłem (i prawdopodobnie zrobię - okazało się to zabawne). Ładne wyrażenie regularne pozwalające znaleźć atrybuty gettable/lettable/settable, refaktoryzujące na kilka małych funkcji, kod usuwający stare funkcje "Clone" (i umieszcza nowy na końcu), coś nieco bardziej Stringbuilder-a do DRY (Don ' t Repeat Yourself) na konkatenacje, takie rzeczy.

+0

Świetny pomysł Mike, choć podejrzewam, że ręczne utrzymywanie metody klonowania może być łatwiejsze w moim przypadku. Bardzo dobry pomysł. –

1

Nie sądzę, że coś jest wbudowane, chociaż byłoby miło.

Myślę, że powinien istnieć przynajmniej sposób na automatyczne utworzenie metody klonowania za pomocą edytora VBA. Zobaczę, czy uda mi się spojrzeć na niego raz mam dzieci do łóżka ...

1
Private pOldinfo As YourClass 

Public Property Set clone(ByVal Value As YourClass) 
    Set pOldinfo = Value 
End Property 

Kluczowe słowo ByVal powinno rozwiązać problem.