我有以下两个程序:
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)
收到以下错误在 InnerSub
:Run-time error '13': Type mismatch
只有当我传入一个类型为
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
也不将参数包装在括号中:
Sub InnerSub(prm As Variant)
prm = Array((prm))
End Sub
最佳答案
这里的参数定义:
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 的回答.引用该答案中引用的链接:
How to: Force an Argument to Be Passed by Value (Visual Basic)
The procedure declaration determines the passing mechanism. If a parameter is declared ByRef, Visual Basic expects to pass the corresponding argument by reference. This allows the procedure to change the value of the programming element underlying the argument in the calling code. If you wish to protect the underlying element against such change, you can override the ByRef passing mechanism in the procedure call by enclosing the argument name in parentheses. These parentheses are in addition to the parentheses enclosing the argument list in the call.
The calling code cannot override a ByVal mechanism.
To force an argument to be passed by value If the corresponding parameter is declared ByVal in the procedure, you do not need to take any additional steps. Visual Basic already expects to pass the argument by value.
If the corresponding parameter is declared ByRef in the procedure, enclose the argument in parentheses in the procedure call.
关于vba - 将字符串变量传递给 Variant 参数时类型不匹配,并将 Array 函数的结果分配给参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51272430/