代码之家  ›  专栏  ›  技术社区  ›  Matt

VB6 IsNumeric会出错吗?

  •  5
  • Matt  · 技术社区  · 17 年前

    我问是因为我收到了一个类型不匹配错误,所以我在尝试转换字符串之前使用了IsNumeric()来检查字符串是否为数字,但我仍然收到了错误。

    我用这个把头发扯掉了。

    这是有问题的代码。 iGlobalMaxAlternatives = CInt(strMaxAlternatives) 是错误发生的地方。

    Dim strMaxAlternatives As String
    Dim iGlobalMaxAlternatives As Integer
    iGlobalMaxAlternatives = 0
    bSurchargeIncInFare = True
    
    strMaxAlternatives = ReadStringKeyFromRegistry("Software\TL\Connection Strings\" & sConn & "\HH", "MaxAlt")
    
    If IsNumeric(strMaxAlternatives) And strMaxAlternatives <> "" Then
        iGlobalMaxAlternatives = CInt(strMaxAlternatives)
    End If
    
    10 回复  |  直到 14 年前
        1
  •  6
  •   Ryan    17 年前

    由于最大整数大小,您可能会出现溢出;货币类型实际上对大量货币表现良好(但要注意任何地区问题)。Int64讨论见以下编辑。

    IsNumeric :

    • 如果数据为True,则IsNumeric返回True 表达式的类型是布尔型、字节型, ULong,或UShort,或一个物体 包含其中一种数字类型。 如果表达式为 一个字符或字符串,可以是 已成功转换为数字。

    • 如果表达式为,则IsNumeric返回False 数据类型为日期或数据类型 对象,它不包含 数字类型。IsNumeric返回False 如果表达式是Char或String

    由于您遇到了类型不匹配,可能是Double干扰了转换。IsNumeric不保证它是一个整数,只是保证它与其中一个数字可能性相匹配。如果数字是双精度的,则可能是区域设置(逗号与句点等)导致了异常。

    您可以尝试将其转换为双精度,然后再转换为整数。

    ' Using a couple of steps
    Dim iValue As Integer
    Dim dValue As Double
    dValue = CDbl(SourceValue)
    iValue = CInt(iValue)
    ' Or in one step (might make debugging harder)
    iValue = CInt(CDbl(SourceValue))
    

    编辑:在您澄清后,您似乎得到了溢出转换。首先尝试使用Long和CLng()而不是CInt()。不过,条目仍然有可能是Int64,这在使用VB6时更难。

    我对LARGE_INTEGER和Integer8类型(均为Int64)使用了以下代码,但它可能不适用于您的情况:

    testValue = CCur((inputValue.HighPart * 2 ^ 32) + _
                      inputValue.LowPart) / CCur(-864000000000)
    

    这个例子来自一个 LDAP password expiration example

    Private Type LARGE_INTEGER
        LowPart As Long
        HighPart As Long
    End Type
    

    搜索LARGE_INTEGER和VB6以获取更多信息。

    If IsNumeric(strMaxAlternatives) And strMaxAlternatives <> "" Then
        On Error Resume Next
        iGlobalMaxAlternatives = CInt(strMaxAlternatives)
        If Err.Number <> 0 Then
            Debug.Print "Conversion Error: " & strMaxAlternatives & _
                        " - " & Err.Description
        EndIf
        On Error Goto YourPreviousErrorHandler
    End If
    
        2
  •  3
  •   workmad3    17 年前

    是的,“3.41”是数字,但不是整数。

        3
  •  2
  •   Craig Gidney Mihai    17 年前

    VB6没有提供好的方法来保证CInt不会失败。我发现最简单的方法就是使用错误处理。

    function TryParse(byval text as string, byref value as integer) as boolean
      on error resume next
      value = CInt(text)
      TryParse = (err.number = 0)
    endfunction
    

    当然,您的错误处理偏好可能会有所不同。

        4
  •  1
  •   Ant    17 年前

    对。试试这个:

    If IsNumeric("65537") Then
        Dim i As Integer
        i = CInt("65537") 'throws an error on this line!
    End If
    

    这是一个溢出,但我认为它说明了IsNumeric()在一般情况下的不可靠性(特别是对于int-对于double,它更可靠)。

        5
  •  1
  •   Bryan Oakley    17 年前

    根据VB6文档,“如果表达式的数据类型是布尔、字节、十进制、双精度、整数、长、SByte、短、单精度、UInteger、ULong或UShort,或者是包含这些数字类型之一的对象,则IsNumeric返回True。如果表达式是可以成功转换为数字的Char或String,则它也返回True。”

    其中许多无法转换为整数。例如,“1.5”是数字,但不是整数。因此,您可以将其转换为数字,但不一定是整数。

        6
  •  0
  •   RS Conley    17 年前

    以下代码在Visual BASIC 6中工作时没有类型不匹配错误

    Dim I As Integer
    I = CInt("3.41")
    

    Dim I As Integer
    Dim TempS As String
    TempS = "3.41"
    I = CInt(TempS)
    

    发布有问题的代码将有助于回答您的问题。VB6中基本上有几个函数用于将字符串转换为数字。

    CInt和Int转换为数字,但处理舍入的方式不同。直接分配工作,相当于使用CInt。但是,我建议您在将来继续使用CInt,以便向您和您的开发人员同事清楚地说明操作。

    CInt处理带逗号的数字,如“3041.41”。但是VB6在处理区域设置时存在问题,因此如果您使用的是标准美式英语以外的符号,您将得到奇怪的结果和错误。

        7
  •  0
  •   ChrisLively    17 年前

    你最好的办法是开始用它正在使用的实际值记录错误,这样你就可以弄清楚发生了什么。

        8
  •  0
  •   jac    17 年前

    如果IsNumeric可以将字符串转换为数字,它将返回true。即使字符串中有非数字字符,我也总是一次遍历一个字符并测试每个字符。如果一个字符失败,那么我可以返回一个错误。

        9
  •  0
  •   Cosmin    14 年前

    刚找到这块金块。如果运行以下命令,脚本#1返回TRUE,但脚本#2返回TRUE;#3将失败:

    SELECT ISNUMERIC('98,0') AS isNum   -- Fails
    
    SELECT CONVERT(INT, '98,0')   -- Fails
    
    SELECT CONVERT(NUMERIC(11,4), '98,0')     -- Fails
    
        10
  •  -1
  •   Andrew G. Johnson    17 年前

    If IsNumeric(strMaxAlternatives) And strMaxAlternatives <> "" Then
        iGlobalMaxAlternatives = CInt(strMaxAlternatives)
    End If
    

    If IsNumeric(strMaxAlternatives) And strMaxAlternatives <> "" Then
        iGlobalMaxAlternatives = CDbl(strMaxAlternatives) ' Cast to double instead'
    End If
    

    If IsNumeric(strMaxAlternatives) And strMaxAlternatives <> "" Then
        If CDbl(strMaxAlternatives) Mod 1 = 0 Then ' Make sure there\'s no decimal points'
            iGlobalMaxAlternatives = CInt(strMaxAlternatives)
        End If
    End If