12

VBAでオブジェクトを複製する一般的な方法はありますか? ポインタだけをコピーするのではなく、x を y にコピーできますか?

  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

ジェネリックSet y = CloneObject(x)とは、クラスのプロパティを 1 つずつコピーするための独自のメソッドを作成する必要がないことを意味します。

4

3 に答える 3

10

OK、これはそれを説明する何かの始まりです:

クラスを作成し、「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

ここで、Clone 関数を指定する必要があります。別のモジュールで、これを試してください。

オプション明示

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

それを実行すると、以下が Class1 に追加されます

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

...これが始まりのようです。私がきれいにしたいことがたくさんあります(そしておそらくそうするでしょう-これは楽しいことがわかりました)。gettable/lettable/settable 属性を見つけるための優れた正規表現、いくつかの小さな関数へのリファクタリング、古い「クローン」関数を削除するコード (そして新しいものを最後に配置するコード)、DRY に対してもう少し Stringbuilder っぽいもの (Don' t Repeat Yourself) を連結して、そのようなものを作成します。

于 2008-10-20T21:42:35.760 に答える
7

Scott Whitlock は、この問題に対する素晴らしい回答を別の質問に投稿しました。

于 2011-01-27T12:43:06.593 に答える
2

それは素晴らしいことですが、何も組み込まれていないと思います。

少なくとも、VBA エディターを使用して Clone メソッドを自動的に作成する方法が必要だと思います。子供たちを寝かしつけたら見てみようかな…

于 2008-10-20T16:49:09.220 に答える