当使用ParamArray
并通过它传递数组元素时,我注意到VBA中有一个奇怪的地方。在某些情况下,到达函数的不是数组元素的值,而是var指针。 (Excel 2016,32位)。
经过深思熟虑之后,我发现将函数定义为变量数组-与参数列表结合ParamArray
一起使用-似乎是意外行为的起源,但我看不到这样做的可行原因。
在以下情况下,行为会恢复正常:
1)在函数声明中删除变量r
2)b
用Dim b()
声明
3)函数返回Variant
,而不是Variant()
我很欣赏这是一个非常深奥的问题,并且它似乎可以通过各种方式控制,但是在那里有一种解释可以阐明这种行为吗?
Sub Variantarraybug()
Dim b: b = [{1, 2, 3}]
Debug.Print farray1(2, b(1))(0)
Debug.Print Application.WorksheetFunction.Sum(farray1(2, b(1)))
Debug.Print Join(farray1(2, b(1)), " ")
Debug.Print farray2(2, b(1))(0)
Debug.Print Application.WorksheetFunction.Sum(farray2(2, b(1)))
Debug.Print Join(farray2(2, b(1)), " ")
Debug.Print VarPtr(b(1)), VarPtr(b(2))
End Sub
Function farray1(r, ParamArray plop()) As Variant
farray1 = Array(plop(0), 3)
End Function
Function farray2(r, ParamArray plop()) As Variant()
farray2 = Array(plop(0), 5)
End Function
调试窗口中的结果:
1
4
1 3
1
6
358808368 5
358808368 358808384
注释1:我的理解是VarPtr
函数返回该变量所需的内存起始地址的内存位置。这里,它仅用于说明farray2
函数看到的意外数字( 358808368 )实际上是该元素的地址。
注意2::这种情况与生成数组的方式(例如b=array(1,2,3)
,b=[1,2,3]
等)以及声明b
的方式({ {1}},b
等)。但是,如果用b(1 to 3)
声明b
,则意外行为将消失。 (在这种情况下,您无法打印Dim b()
,因为VarPtr(b)
无法接受数组变量。)
答案 0 :(得分:0)
我认为此错误是由于数组“ declaration”而出现的。 在这一点上,我认为Microsoft明确指出了这一点:
数组
您可以声明一个变量来保存一个数组,该数组可以保存多个值。要指定变量保存数组,请在变量名后立即加上括号。
在here
答案 1 :(得分:0)
我认为,这是“C”中的粗心大意。你得到这样的错误
int *X;
int i;
i = 7;
X = &i;
printf("%d\n", X);
printf("%d\n", *X);
答案 2 :(得分:-1)
对我来说,这取决于传递错误的数据类型。
您需要将变体传递到ParamArray https://docs.microsoft.com/en-us/office/vba/Language/Reference/user-interface-help/paramarray-must-be-declared-as-an-array-of-variant
将b(1)更改为变体可以正常工作。
Sub Variantarraybug()
Dim b: b = [{1, 2, 3}]
Debug.Print farray1(2, CVar(b(1)))(0)
Debug.Print Application.WorksheetFunction.Sum(farray1(2, CVar(b(1))))
Debug.Print Join(farray1(2, CVar(b(1))), " ")
Debug.Print farray2(2, CVar(b(1)))(0)
Debug.Print Application.WorksheetFunction.Sum(farray2(2, CVar(b(1))))
Debug.Print Join(farray2(2, CVar(b(1))), " ")
Debug.Print VarPtr(b(1)), VarPtr(b(2))
End Sub
Function farray1(r, ParamArray plop()) As Variant
farray1 = Array(plop(0), 3)
End Function
Function farray2(r, ParamArray plop()) As Variant()
farray2 = Array(plop(0), 5)
End Function
这不是错误,是不强烈键入数据的情况。