类模块types数组不更新

我已经触及了一些奇怪的数组,我可以为整个数组赋值而不是单个数组成员。

这是一个名为Class_E的数据类模块

Public Name As Variant Public Age As Variant 

这是body代码,它只是分配和重新赋值给2个数组

 Sub main() Dim r As Class_E Set r = Band() End Sub Function Band() As Class_E Set Band = New Class_E 'Part 1: Initialize the variables Debug.Print "Part 1" Band.Name = Array("Edison", "Tesla", "Faraday", "Turing") Debug.Print "Before: Name={" & Band.Name(0) & ", " & Band.Name(1) & ", " & Band.Name(2) & ", " & Band.Name(3) & "}" Band.Age = Array(10, 10, 10, 10) Debug.Print "Before: Age={" & Band.Age(0) & ", " & Band.Age(1) & ", " & Band.Age(2) & ", " & Band.Age(3) & "}" 'Part 2: Change values of arrays, by item Debug.Print "Part 2" For k = LBound(Band.Name) To UBound(Band.Name) Debug.Print "k=" & k Band.Name(k) = "Foo" Band.Age(k) = 999 Next k Debug.Print "After: Name={" & Band.Name(0) & ", " & Band.Name(1) & ", " & Band.Name(2) & ", " & Band.Name(3) & "}" Debug.Print "After: Age={" & Band.Age(0) & " " & Band.Age(1) & " " & Band.Age(2) & " " & Band.Age(3) & "}" 'Part 3: Change values of array, entirely Debug.Print "Part 3" Band.Name = Array("Spring", "Summer", "Autumn", "Winter") Debug.Print "Again: Name={" & Band.Name(0) & ", " & Band.Name(1) & ", " & Band.Name(2) & ", " & Band.Name(3) & "}" Band.Age = Array(11, 11, 11, 11) Debug.Print "Again: Age={" & Band.Age(0) & ", " & Band.Age(1) & ", " & Band.Age(2) & ", " & Band.Age(3) & "}" 'Part 4: Use another temp array variable Debug.Print "Part 4" Dim Temp_Name As Variant, Temp_Age As Variant Temp_Name = Band.Name Temp_Age = Band.Age For k = LBound(Band.Name) To UBound(Band.Name) Debug.Print "k=" & k Temp_Name(k) = "Foo" Temp_Age(k) = 999 Next k Debug.Print "Temp: Name={" & Temp_Name(0) & ", " & Temp_Name(1) & ", " & Temp_Name(2) & ", " & Temp_Name(3) & "}" Debug.Print "Temp: Age={" & Temp_Age(0) & " " & Temp_Age(1) & " " & Temp_Age(2) & " " & Temp_Age(3) & "}" 'Part 5: Original arrays again Debug.Print "Part 5" Debug.Print "Again: Name={" & Band.Name(0) & ", " & Band.Name(1) & ", " & Band.Name(2) & ", " & Band.Name(3) & "}" Debug.Print "Again: Age={" & Band.Age(0) & ", " & Band.Age(1) & ", " & Band.Age(2) & ", " & Band.Age(3) & "}" End Function 

这是我得到的输出屏幕

 Part 1 Before: Name={Edison, Tesla, Faraday, Turing} Before: Age={10, 10, 10, 10} Part 2 k=0 k=1 k=2 k=3 After: Name={Edison, Tesla, Faraday, Turing} After: Age={10 10 10 10} Part 3 Again: Name={Spring, Summer, Autumn, Winter} Again: Age={11, 11, 11, 11} Part 4 k=0 k=1 k=2 k=3 Temp: Name={Foo, Foo, Foo, Foo} Temp: Age={999 999 999 999} Part 5 Again: Name={Spring, Summer, Autumn, Winter} Again: Age={11, 11, 11, 11} 

问题:

1.为什么第2部分中的简单任务没有执行? 并没有错误信息。 我们没有问题重新分配数组,如第3部分所示。

2.为什么第4部分中的“Temp_Name = Band.Name”是数组值的副本而不是数组指针? 没有内存分配给临时arrays的指令。

您的意见非常感谢。

使用数组作为公共类成员是有问题的。 VBA不允许有这个原因。 您试图通过将成员声明为Variant来克服这个限制,但这并不能解决问题。

您可以使用CollectionDictionary ,因为这些是Objects所以你可以在它们上Set 引用 。 但是VBA数组是价值types 。 因此,当你从一个函数获得一个数组时,你会得到一个数组的副本

  1. 为什么第2部分中的简单任务没有执行? 并没有错误信息。 我们没有问题重新分配数组,如第3部分所示。

因为你实际上在数组的副本上工作。 在声明中

 Band.Name(k) = "Foo" 

虽然Band.Name似乎直接访问类的一个字段,但它实际上是通过一个属性get“wrapper”来访问它。 公共类成员总是这样,编译器会自动添加COM的IDispatch接口所需的get / let包装,并最终进行后期绑定(在object引用中访问类)。 包装返回数组的副本而不是引用 ,因为如前所述,VBA中的数组(和string)是值types的 ,而不是对象。 所以yoiu在数组的副本上工作。

您可以通过添加Property Let方法来分配成员数组中的条目来克服此问题。 考虑你的类的这个代码:

 Public Names As Variant '<-- Change to plural to add property get/let Public Ages As Variant ' <-- Same Public Property Let Name(i As Long, s As String) Names(i) = s End Property Public Property Let Age(i As Long, val As Long) Ages(i) = val End Property 

您可以使用这些在成员数组中分配条目。 您的Part2将按预期工作。

  1. 为什么第4部分中的“Temp_Name = Band.Name”是数组值的副本而不是数组指针? 没有内存分配给临时arrays的指令。

如前所述,数组是值types,而不是对象。 将一个数组赋值给一个variables总是创build一个副本 ,而不是像对象案例一样的重复引用 。 (添加到包装属性得到,你发现自己距离初始类的数组两英里)。

根据我的build议,如何将数组从Band.Name(0到3)存储到Band(0到3).Name中,这里是一些工作代码。

Class_E(代码)类模块代码表

 Option Explicit Private pName As String Private pAge As Long Public Property Get Name() As String Name = pName End Property Public Property Let Name(Value As String) pName = Value End Property Public Property Get Age() As Long Age = pAge End Property Public Property Let Age(Value As Long) pAge = Value End Property 

标准模块1(代码)代码表

 Option Explicit Sub main() Dim i As Long, r() As New Class_E r = fillBand() For i = LBound(r) To UBound(r) Debug.Print r(i).Name & " - " & r(i).Age Next i End Sub Function fillBand() As Class_E() Dim tmpBands() As New Class_E, tmp1 As Variant, tmp2 As Variant, i As Long 'Part 1: Initialize the variables Debug.Print "Part 1" tmp1 = Array("Edison", "Tesla", "Faraday", "Turing") tmp2 = Array(5, 10, 15, 20) ReDim tmpBands(LBound(tmp1) To UBound(tmp1)) For i = LBound(tmp1) To UBound(tmp1) With tmpBands(i) .Name = tmp1(i) .Age = tmp2(i) End With Next i Debug.Print "Before: Name={" & tmpBands(0).Name & ", " & tmpBands(1).Name & ", " & tmpBands(2).Name & ", " & tmpBands(3).Name & "}" Debug.Print "Before: Age={" & tmpBands(0).Age & ", " & tmpBands(1).Age & ", " & tmpBands(2).Age & ", " & tmpBands(3).Age & "}" 'Part 2: Initialize the variables Debug.Print "Part 2" tmp1 = Array("foo", "bar", "foobar", "else") tmp2 = Array(9, 99, 999, 9999) ReDim tmpBands(LBound(tmp1) To UBound(tmp1)) For i = LBound(tmp1) To UBound(tmp1) tmpBands(i).Name = tmp1(i) tmpBands(i).Age = tmp2(i) Next i Debug.Print "Before: Name={" & tmpBands(0).Name & ", " & tmpBands(1).Name & ", " & tmpBands(2).Name & ", " & tmpBands(3).Name & "}" Debug.Print "Before: Age={" & tmpBands(0).Age & ", " & tmpBands(1).Age & ", " & tmpBands(2).Age & ", " & tmpBands(3).Age & "}" 'Part 3: Initialize the variables Debug.Print "Part 3" tmp1 = Array("spring", "summer", "fall", "winter") tmp2 = Array(1, 11, 111, 1111) ReDim tmpBands(LBound(tmp1) To UBound(tmp1)) For i = LBound(tmp1) To UBound(tmp1) tmpBands(i).Name = tmp1(i) tmpBands(i).Age = tmp2(i) Next i Debug.Print "Before: Name={" & tmpBands(0).Name & ", " & tmpBands(1).Name & ", " & tmpBands(2).Name & ", " & tmpBands(3).Name & "}" Debug.Print "Before: Age={" & tmpBands(0).Age & ", " & tmpBands(1).Age & ", " & tmpBands(2).Age & ", " & tmpBands(3).Age & "}" fillBand = tmpBands End Function 

即时窗口的结果

 Part 1 Before: Name={Edison, Tesla, Faraday, Turing} Before: Age={5, 10, 15, 20} Part 2 Before: Name={foo, bar, foobar, else} Before: Age={9, 99, 999, 9999} Part 3 Before: Name={spring, summer, fall, winter} Before: Age={1, 11, 111, 1111} Returned Values: spring - 1 summer - 11 fall - 111 winter - 1111