为什么在通过ParamArray将数组元素传递给函数时,变量指针会到达函数中?

时间:2018-09-04 12:51:47

标签: arrays excel vba excel-vba function

当使用ParamArray并通过它传递数组元素时,我注意到VBA中有一个奇怪的地方。在某些情况下,到达函数的不是数组元素的值,而是var指针。 (Excel 2016,32位)。

经过深思熟虑之后,我发现将函数定义为变量数组-与参数列表结合ParamArray一起使用-似乎是意外行为的起源,但我看不到这样做的可行原因。

在以下情况下,行为会恢复正常:
1)在函数声明中删除变量r
2)bDim 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)无法接受数组变量。)

3 个答案:

答案 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

这不是错误,是不强烈键入数据的情况。