我已经击中了一些奇怪的数组,我可以为整个数组分配值,但不是单个数组成员。
这是一个名为Class_E
的数据类模块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
这是正文代码,只是为2个数组分配和重新分配值
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}}
问题:
1.为什么第2部分中的简单赋值没有执行?并且没有错误消息。我们没有问题重新分配数组,如第3部分所示。
2.为什么第4部分中的“Temp_Name = Band.Name”是数组值的副本而不是数组指针?没有关于临时阵列的内存分配的指令。
非常感谢您的投入。
答案 0 :(得分:3)
使用数组作为公共类成员是有问题的。 VBA不允许这样做的原因。您试图通过将成员声明为Variant
来克服此限制,但这并不能解决问题。
您可以使用Collection
或Dictionary
,因为它们是Objects
,因此您可以Set
引用。但是VBA数组是值类型。因此,当您从函数中获取数组时,您将获得该数组的副本。
- 为什么第2部分中的简单分配没有执行?并且没有错误消息。我们没有问题重新分配数组,如第3部分所示。
醇>
因为您实际上处理了数组的副本。在声明中
Band.Name(k) = "Foo"
虽然Band.Name
似乎直接访问该类的一个字段,但它实际上是通过属性get“wrapper”访问它;对于公共类成员,情况总是如此,编译器会自动添加COM的IDispatch接口所需的get / let包装器以及最终的后期绑定(在object
引用中访问类)。包装器返回数组的副本,不是引用,因为如前所述,VBA中的数组(以及字符串)是 value-types < / em>,而不是对象。所以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将按预期工作。
- 为什么第4部分中的“Temp_Name = Band.Name”是数组值的副本而不是数组指针?没有关于临时阵列的内存分配的指令。
醇>
如前所述,数组是值类型,而不是对象。将数组分配给变量始终会创建副本,而不是像对象案例那样创建重复引用。 (添加到包装器属性get,你发现自己距离初始类的数组两英里)。
答案 1 :(得分:1)
根据我的建议来翻转你如何将数组从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