首页 > 解决方案 > 将字符串变量传递给 Variant 参数时类型不匹配,并将 Array 函数的结果分配给参数

问题描述

我有以下两个程序:

Sub OuterSub()
    Dim s As String
    s = "Lorem ipsum dolor sit amet"
    InnerSub s
End Sub

Sub InnerSub(prm As Variant)
    prm = Array(prm)
End Sub

当我运行时,我在inOuterSub收到以下错误:prm = Array(prm)InnerSub

运行时错误“13”:类型不匹配

这只发生在我传入一个类型为String. 以下任何替代方案都不会产生错误:

定义s为固定长度的字符串没有帮助。

为什么会这样?我该如何解决它?


更新

在内部声明局部String变量InnerSub也无济于事:

Sub InnerSub(prm As Variant)
    Dim s As String
    s = prm
    prm = Array(s)
End Sub

也不会将参数括在括号中:

Sub InnerSub(prm As Variant)
    prm = Array((prm))
End Sub

标签: vba

解决方案


这里的参数定义:

Sub InnerSub(prm As Variant)

是隐含的ByRef

Sub InnerSub(ByRef prm As Variant)

这意味着任何分配 toprm也将分配给sin OuterSub。虽然可以将数组分配给Variant变量prm,但不能将数组分配给 中的String变量sOuterSub

您可以通过定义s As Variantin OuterSub(保存数组没有问题)并检查safter的值来查看此操作InnerSub已完成。

您可以显式强制传入一个变量ByVal

Sub InnerSub(ByVal prm As Variant)

传递一个常数:

Const s = "Lorem ipsum dolor sit amet"

或字符串文字:

InnerSub "Lorem ipsum dolor sit amet"

两者都有效,因为两者都不能传入ByRef

将参数括在括号中也会强制传入变量ByVal,这就是以下工作的原因

Sub OuterSub()
    Dim s As String
    s = "Lorem ipsum dolor sit amet"
    InnerSub (s) ' The brackets here do the trick
End Sub

OTOH,您的非工作替代方案都不起作用,因为无论您是创建本地字符串变量,还是将参数包装Array在括号中,问题都是一样的——您试图通过将数组分配给字符串变量ByRef prm范围。


请参阅我对CallByName的回答将不接受变体参数。引用该答案中引用的链接:

如何:强制按值传递参数 (Visual Basic)

过程声明决定了传递机制。如果参数声明为 ByRef,Visual Basic 期望通过引用传递相应的参数。这允许过程更改调用代码中参数基础的编程元素的值。如果您希望保护底层元素免受此类更改,您可以通过将参数名称括在括号中来覆盖过程调用中的 ByRef 传递机制。这些括号是对调用中参数列表的括号的补充。

调用代码不能覆盖 ByVal 机制。

强制参数按值传递 如果相应参数在过程中声明为 ByVal,则无需采取任何额外步骤。Visual Basic 已经期望按值传递参数。

如果相应的参数在过程中声明为 ByRef,则在过程调用中将参数括在括号中。


推荐阅读