VBA:是什么导致传递给ParamArray的这个字符串参数变为一个数字(看起来像一个指针)?

jto*_*lle 11 excel vba compiler-bug

最终编辑:它确实似乎是一个编译器错误 - 请参阅接受的答案.

在Excel 2007中使用VBA,我在'Class1'中有以下代码:

Option Explicit

Public Function strange(dummy As String, ParamArray pa())
    Debug.Print pa(LBound(pa))
End Function

Public Sub not_strange(dummy As String, ParamArray pa())
    Debug.Print pa(LBound(pa))
End Sub

Public Function also_not_strange(ParamArray pa())
    Debug.Print pa(LBound(pa))
End Function
Run Code Online (Sandbox Code Playgroud)

以及模块中的一些模式代码:

Option Explicit

Public Function not_strange_either(dummy As String, ParamArray pa())
    Debug.Print pa(LBound(pa))
End Function

Public Sub outer(v)
    Dim c As Class1
    Set c = New Class1

    Call c.strange("", v(LBound(v)))
    Call c.not_strange("", v(LBound(v)))
    Call c.also_not_strange(v(LBound(v)))

    Call not_strange_either("", v(LBound(v)))
End Sub
Run Code Online (Sandbox Code Playgroud)

如果从立即窗口调用'outer',如下所示:

call outer(array("a"))
Run Code Online (Sandbox Code Playgroud)

我得到了看起来很奇怪的输出:

 102085832 
a
a
a
Run Code Online (Sandbox Code Playgroud)

似乎问题是被调用例程是否在类模块中,无论是Sub还是Function,以及是否存在初始参数.我错过了VBA应该如何运作的一些内容吗?有任何想法吗?

奇怪的数字从运行变为运行.我说"看起来像一个指针",因为如果我这称呼:

Public Sub outer2(v)
    Dim c As Class1
    Set c = New Class1

    Dim ind As Long
    For ind = LBound(v) To UBound(v)
        Call c.strange("", v(ind))
    Next ind
End Sub
Run Code Online (Sandbox Code Playgroud)

像这样:

call outer2(array("a","b","c"))
Run Code Online (Sandbox Code Playgroud)

我得到输出像:

 101788312 
 101788328 
 101788344 
Run Code Online (Sandbox Code Playgroud)

这是16的增量让我怀疑,但我真的不知道.另外,传递一个值,比如说:

Call c.strange("", CStr(v(ind)))
Run Code Online (Sandbox Code Playgroud)

工作得很好.

编辑:更多信息...如果我将'c.strange'的返回值分配给某些东西而不是丢弃它,我会得到相同的行为:

Public Sub outer3(v)
    Dim c As Class1
    Set c = New Class1

    Dim x
    x = c.strange("", v(LBound(v)))

    Call c.not_strange("", v(LBound(v)))
    Call c.also_not_strange(v(LBound(v)))

    Call not_strange_either("", v(LBound(v)))
End Sub
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果我像上面那样调用我的测试例程,并且通过调用'Array'产生一个参数,则假定的指针值会发生变化.但是,如果我这样称呼它:

call outer([{1,2,3}])
Run Code Online (Sandbox Code Playgroud)

即使我重复拨打电话,我也会收到相同的号码.(如果我切换到Windows中的另一个应用程序,例如我的浏览器,则数字会发生变化.)所以,现在我很好奇Excel评估器(用括号调用)似乎缓解了它的结果......

GSe*_*erg 8

现在这太棒了.

在Office 2003上转载.
看起来像编译器错误.

问题出在这一行:

Call c.strange("", v(LBound(v)))
Run Code Online (Sandbox Code Playgroud)

这里编译器创建一个Variant包含1的数组Variant,其中唯一的元素是指针而不是值.然后这个指针转到strange实际上并不奇怪的函数,它只打印Variant\Long传递给它的值.

这个技巧带来了编译器的健全性:

Call c.strange("", (v(LBound(v))))
Run Code Online (Sandbox Code Playgroud)

编辑

是的,这个神奇的数字是指向应该传递给strange方法的VARIANT结构的指针.其中第一个字段是8,vbString数据字段包含指向实际字符串的指针"a".

因此,它绝对是一个编译器错误......关于数组的另一个VB编译器错误;)