Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
388 views
in Technique[技术] by (71.8m points)

clone - Cloning Objects in VBA?

Is there a generic way to clone objects in VBA? So that i could copy x to y instead of copying just the pointer?

  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

By generic i mean something like Set y = CloneObject(x) rather than having to create my own method for the class copying its properties one by one.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

OK, here's the beginning of something that illustrates it:

Create a class, call it, 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

Now we need to give it a Clone function. In another module, try this:

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

Run that, and the following gets added into Class1

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

...which looks like a start. Lots of things I'd clean up (and probably will - this turned out to be fun). A nice Regular Expression to find gettable/lettable/settable attributes, refactoring into several small functions, code to remove old "Clone" functions (and put the new one at the end), something a bit more Stringbuilder-ish to DRY (Don't Repeat Yourself) up the concatenations, stuff like that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...