如果通过引用返回数组,为什么不能执行以下操作:
'Class1 class module
Private v() As Double
Public Property Get Vec() As Double()
Vec = v()
End Property
Private Sub Class_Initialize()
ReDim v(0 To 3)
End Sub
' end class module
Sub Test1()
Dim c As Class1
Set c = New Class1
Debug.Print c.Vec()(1) ' prints 0 as expected
c.Vec()(1) = 5.6
Debug.Print c.Vec()(1) ' still prints 0
End Sub
答案 0 :(得分:25)
您没有let属性。此外,get属性返回整个数组,而不仅仅是有问题的元素。将属性Get的返回类型从Double()更改为plain Double。添加属性让。请注意,它需要两个输入,但只传递一个输入。假设最后一个变量(在本例中为MyValue)从=符号后面的任何值获取它的值。在Test1()的早期某处放置一个断点,看看这些值在Locals窗口中是如何受到影响的。比较原始代码与我的代码创建的变量:
'Class1 class module
Private v() As Double
Public Property Get Vec(index As Long) As Double
Vec = v(index)
End Property
Public Property Let Vec(index As Long, MyValue As Double)
v(index) = MyValue
End Property
Private Sub Class_Initialize()
ReDim v(0 To 3)
End Sub
' end class module
'Begin module
Sub Test1()
Dim c As Class1
Set c = New Class1
Debug.Print c.Vec(1) ' prints 0 as expected
c.Vec(1) = 5.6
Debug.Print c.Vec(1) ' prints 5.6
End Sub
'End module
答案 1 :(得分:11)
在VBA中,除非通过ByRef
参数返回数组,否则永远不会通过引用返回数组。此外,每当你使用=
为一个变量赋一个数组时,你就已经创建了一个数组的新副本,即使你将它分配给一个过程中的ByRef参数,所以你很漂亮试图让这项工作变得非常幸运。
一些替代方案是......
答案 2 :(得分:0)
我想建议另一种使用 Collection
和static Property
的好方法,而无需使用 class :< / p>
想象您想将xlCVError
枚举作为数组(或集合),例如遍历错误并根据实际错误进行处理。
以下内容在访问时初始化一次:
'from https://stackoverflow.com/a/56646199/1915920
Static Property Get XlCVErrorColl() As Collection
Dim c As Collection 'will be already initalized after 1st access
'because of "Static Property" above!
Set XlCVErrorColl = c
If Not c Is Nothing Then Exit Property
'initialize once:
Set c = New Collection
c.Add XlCVError.xlErrDiv0
c.Add XlCVError.xlErrNA
c.Add XlCVError.xlErrName
c.Add XlCVError.xlErrNull
c.Add XlCVError.xlErrNum
c.Add XlCVError.xlErrRef
c.Add XlCVError.xlErrValue
Set XlCVErrorColl = c
End Property
将其转换为数组或将其实现为数组很简单,但是集合对我来说似乎更有用,缺点是它们的元素没有隐式地类型化/(编译时)类型检查。 /> 因此,例如将其转换为(只读)数组(其他答案/评论中提到了in-mem-copy-disadvantage):
'from https://stackoverflow.com/a/56646199/1915920
Static Property Get XlCVErrorArr() As XlCVError()
Dim a() As XlCVError
XlCVErrorArr = a
If UBound( a ) > 0 Then Exit Property
'initialize once:
Dim c As Collection: Set c = XlCVErrorColl
ReDim a(c.Count)
Dim i As Integer: For i = 1 To c.Count
a(i) = c(i)
Next i
XlCVErrorArr = a
End Function
因此,使用一些数组将示例从Clayton Ss answer转换为静态的,可修改的模块属性,它将是:
'module (no class required)
'from https://stackoverflow.com/a/56646199/1915920
Private v() As Double
Static Property Get Vec(index As Long) As Double
If UBound(v) < 3 Then 'initialize once:
ReDim v(0 To 3) 'one could initialize it with anyting after here too
end if
Vec = v(index)
End Property
Public Property Let Vec(index As Long, MyValue As Double)
v(index) = MyValue
End Property
答案 3 :(得分:0)
Vec(索引为长,MyValue为双)
index关键字在这里做什么? 请引导我到一个网页,在这里我可以了解与数组相关的索引。