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

标签 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) 收到以下错误在 InnerSub :

Run-time error '13': Type mismatch



只有当我传入一个类型为 String 的变量时才会发生这种情况。 .以下任何替代方案都不会产生错误:
  • 定义 sOuterSub作为常数:Const s = "Lorem ipsum dolor sit amet"
  • 传入字符串文字:InnerSub "Lorem ipsum dolor sit amet"
  • 定义 sOuterSub作为 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 的任何分配也将分配给 sOuterSub .虽然可以将数组分配给 Variant变量 prm ,它不能分配给 String变量 sOuterSub .

    您可以通过定义 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/

    相关文章:

    vba - excel:使用表格列的范围

    vba - 如何更改格式化日期的语言环境?

    ms-access - 打开任何桌面VBA Access的文件路径,我需要设置路径以便它可以在任何桌面上打开

    sql - SELECT 查询在转换为 VBA 时不起作用 - 无效的 SQL 语句

    excel - 在 VBA 中将数组另存为制表符分隔的文本文件

    excel - Excel vba 能做什么而 C# 不能做什么

    vba - Excel 直方图 - 分布线

    excel - 我可以将多个文本文件导入到一张 Excel 工作表中吗?

    VBA代码速度慢,需要优化

    sql - 使用vba将sql数据导入excel