将字符串变量传递给Variant参数并将Array函数的结果分配给参数时,类型不匹配

时间:2018-07-10 19:04:37

标签: vba

我有以下两个过程:

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

运行OuterSub时,在prm = Array(prm)的{​​{1}}处出现以下错误:

  

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

这仅在我传入类型为InnerSub的变量时发生。以下任何一种选择均不会产生错误:

  • String中将s定义为常量:
    OuterSub
  • 传入字符串文字:
    Const s = "Lorem ipsum dolor sit amet"
  • InnerSub "Lorem ipsum dolor sit amet"中将s定义为OuterSub
    Variant

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

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


更新

s中声明局部String变量也无济于事:

InnerSub

也不将参数括在括号中

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

2 个答案:

答案 0 :(得分:3)

此处的参数定义:

Sub InnerSub(prm As Variant)

隐式为ByRef

Sub InnerSub(ByRef prm As Variant)

这意味着对prm的所有分配也将分配给s中的OuterSub。虽然可以将数组分配给Variant变量prm,但是不能将其分配给String中的s变量OuterSub

您可以通过在s As Variant中定义OuterSub(保存数组没有问题),并在s完成之后检查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 won't accept variant arguments的回答。从该答案中引用的链接中引用:

  

方法:强制值传递参数(Visual Basic)

     

过程声明确定传递机制。如果参数声明为ByRef,则Visual Basic希望通过引用传递相应的参数。这使过程可以更改调用代码中作为参数基础的编程元素的值。如果希望保护基础元素免遭此类更改,则可以在过程调用中通过在括号中括入参数名称来覆盖ByRef传递机制。这些括号是在调用中将参数列表括起来的括号的补充。

     

调用代码无法覆盖ByVal机制。

     

强制将参数传递给值   如果在过程中将相应的参数声明为ByVal,则无需执行任何其他步骤。 Visual Basic已经期望按值传递参数。

     

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

答案 1 :(得分:0)

我不知道原因,但是似乎在传递byref时,期望值被抛出了。字符串是通过引用传递的,但是如果在其上加上括号,则会按值传递:

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

如果不想更改外部函数,另一种选择是通过值定义InnerSub prm

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