【问题标题】:"ByRef Argument Type Mismatch" Error on VBA UDFVBA UDF 上的“ByRef 参数类型不匹配”错误
【发布时间】:2016-05-23 20:50:00
【问题描述】:

这是给出问题的函数:

它应该检查一个字符串是否只有数字 0-9

Public Function onlyNumbers(str As String)
        For i = 1 To Len(str)
        If Not (IsNumber(Mid(str, i, 1))) Then
            onlyNumbers = False
        End If
    Next
    onlyNumbers = True
End Function

模块:

    Dim value as string
For j = 2 to 2205
    value = Cells(j, 2)

    value = Trim(Replace(Replace(value, "-", ""), ".", ""))
   'Error gives on the if check (it highlights "value") :        
    If onlyNumbers(value) Then

   ' code goes on... no syntax error, execution only

【问题讨论】:

  • 在之前添加call 或删除()
  • IsNumber 不是 vba。试试 IsNumeric()
  • 您的 UDF 也将始终返回 true。发现错误需要退出函数。
  • @ScottCraner 至少在 excel 2007 中,这就是你返回的方式,设置返回会导致语法错误
  • 问题是你使用value一个已经在vba中使用过的词,将变量更改为一些非vba词,如vlu或其他东西。

标签: excel vba


【解决方案1】:

只是为了省去所有麻烦 - 您甚至不需要函数或循环,只需使用 Like 运算符:

Dim myString As String

myString = "12345"

If myString Like Application.Rept("[0-9]", Len(myString) Then
    MsgBox "myString is numbers only"
Else
    MsgBox "myString contains other characters that aren't 0-9"
End If

如果你真的希望它成为一个函数,那么:

Function IsNumbersOnly(str As String) As Boolean
    IsNumbersOnly = str Like Application.Rept("[0-9]", Len(str))
End Function

【讨论】:

    【解决方案2】:

    添加:

     Dim value As String
    

    在子的开头。

    【讨论】:

    • 我的错,那条线刚刚被剪掉了
    【解决方案3】:

    看起来人们在 cmets 中给出了很好的建议,下面是一个有效的解决方案,可以吸收它们并减少代码库。

    Public Function onlyNumbers(ByVal str As String) As Boolean
    For i = 1 To Len(str)
        If Not (IsNumeric(Mid(str, i, 1))) Then Exit Function
    Next
    onlyNumbers = True
    End Function
    

    【讨论】:

    • 其实是因为你已经取出了减号和小数点。你根本不需要函数If IsNumeric(value) Then 而不是If onlyNumbers(value) Then
    • 退出函数自动将其返回值赋值为false?
    • @Mojimi 是的,除非你指定一个布尔值,否则它的默认值为 false
    • 在其中加入一些关于使用Value 作为变量的问题,所以这是正确的答案。
    • @Mojimi 另外,以防万一它是未知的。您不必使用End If 关闭If 语句,因为它在触发时正在运行单个命令。 IE。如果If状态的内容是简单的一行操作,你可以把它放在一行上,不要像我做的那样添加End If。我必须经常这样做,因为代码优化对我来说是一项艰巨的任务,但是,它会使代码难以遵循,所以如果您不确定或者代码变得过于复杂,我不会说这样做.
    【解决方案4】:

    Cells() 返回一个范围对象。

    您需要将 value 设置为范围的值。调用函数时尝试 Cells().value。

    value = Cells(j, 2)
    value = Trim(Replace(Replace(value, "-", ""), ".", ""))
    'Error gives on the if check :        
    If onlyNumbers(value.value) Then
    

    【讨论】:

    • 实际上,除非您在赋值之前使用Set 关键字,否则Cells() 方法的默认属性是.Value,所以这就是您不指定时返回的内容。
    • 不,不是这样
    • 这很好——我没有意识到这一点。谢谢宏人!
    【解决方案5】:

    4 个错误

    1) 退出循环以获得@ScottCraner 指出的正确逻辑

    2) vba 已使用的变量名“值”,@ScottCrane 指出的可能冲突(来自问题标题的错误)

    3) 接下来我错过了

    4) IsNumber 不在 VBA 中,正确的是 @ScottCraner 指出的 IsNumeric

    Public Function onlyNumbers(str As String)
            For i = 1 To Len(str)
            If Not (IsNumeric(Mid(str, i, 1))) Then
                Exit Function
            End If
        Next i
        onlyNumbers = True
    End Function
    

    感谢所有帮助过的人

    【讨论】:

    • 我仍然建议您根本不需要该函数,您正在逐个字符循环以查找字符串中的非数字条目,您可以将整个字符串传递给 IsNumeric 和得到相同的结果,但您将受益于无需进入额外的函数,也无需循环。
    【解决方案6】:

    我相信您的 Cells 通话有问题。请将其更改为 Cells(2, 10)。这将是 j2,因为这个 API 是 Cells(row, column) by index

    Dim Value As String
    Value = Cells(2, 10)
    
    Value = Trim(Replace(Replace(Value, "-", ""), ".", ""))
    Debug.Print onlyNumbers(Value)
    

    你的另一篇文章有​​一些不正确的语法,因为你应该使用 IsNumeric

    Public Function onlyNumbers(str As String)
        For i = 1 To Len(str)
        If Not IsNumeric(Mid(str, i, 1)) Then
            onlyNumbers = False
        End If
    Next
    onlyNumbers = True
    End Function
    

    【讨论】:

    • Cells() 方法中使用j 完全没问题,只要j 是一个数字,并且您的函数将始终返回true
    • 原帖没有定义变量J。因此,当我重新构建代码时,我的假设(正确与否)是 J 旨在作为列标题。这篇文章被多次重新编辑的事实让我看起来好像没有读过——感谢任何人的否定。原始帖子中缺少:Dim value as string For j = 2 to 2205
    猜你喜欢
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 2012-10-16
    • 2016-08-07
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 2017-10-17
    相关资源
    最近更新 更多