在 VBA 中克隆对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/218696/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cloning Objects in VBA?
提问by Mark Nold
Is there a generic way to clone objects in VBA? So that i could copy x to y instead of copying just the pointer?
是否有在 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
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.
泛型我的意思是类似Set y = CloneObject(x)而不是必须为类创建自己的方法来一一复制其属性。
采纳答案by Mike Woodhouse
OK, here's the beginning of something that illustrates it:
好的,这是说明它的开始:
Create a class, call it, oh, "Class1":
创建一个类,叫它,哦,“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:
现在我们需要给它一个 Clone 函数。在另一个模块中,试试这个:
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
运行它,然后将以下内容添加到 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.
......这看起来像是一个开始。我会清理很多东西(并且可能会清理 - 结果很有趣)。一个很好的正则表达式,用于查找 gettable/lettable/settable 属性,重构为几个小函数,代码删除旧的“克隆”函数(并将新函数放在最后),一些更像 Stringbuilder 的东西到 DRY(Don' t 重复你自己)串联起来,诸如此类。
回答by MarkJ
Scott Whitlock has posted a fantastic answerto this problem on another question.
Scott Whitlock在另一个问题上发布了这个问题的绝妙答案。
回答by Mike Woodhouse
I don't think there's anything built in, although it would be nice.
我不认为有任何内置的东西,虽然它会很好。
I think there should at least be a way to create a Clone method automatically using the VBA Editor. I'll see if I can take a look at it once I've got the kids to bed...
我认为至少应该有一种方法可以使用 VBA 编辑器自动创建 Clone 方法。等我让孩子们睡觉后,我会看看我是否可以看一下......

