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

VB6是否可以是数字错误?

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

    是否可以使用isNumeric()测试字符串并使其返回true,但当您使用cint()将同一字符串强制转换为整数并将其分配给整数类型的变量时,它将给出类型不匹配错误?

    我问是因为我得到了一个类型不匹配的错误,所以在尝试强制转换字符串之前,我使用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 回复  |  直到 12 年前
        1
  •  6
  •   Ryan    16 年前

    由于最大整数大小,您可能会出现溢出;对于较大的数字,货币类型实际上非常适合(但要注意任何区域问题)。参见下面的编辑了解Int64讨论。

    根据有关 IsNumeric :

    • 如果数据 表达式类型为Boolean、Byte和 decimal、double、integer、long、 sbyte、short、single、uinteger、 乌龙,乌肖特,或 包含这些数字类型之一。 如果表达式为 一个字符或字符串,可以是 已成功转换为数字。

    • IsNumeric返回false if表达式 数据类型为日期或数据类型 对象,它不包含 数字类型。IsNumeric返回false 如果表达式是字符或字符串 无法转换为数字的。

    由于类型不匹配,可能是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。

    我对大整数和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
    

    有关详细信息,请搜索大整数和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    16 年前

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

        3
  •  2
  •   Craig Gidney Mihai    16 年前

    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    16 年前

    对。试试这个:

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

    这是一个溢出,但我认为它说明了isNumeric()的不可靠性(尤其是对于ints,对于double,它更可靠)。

        5
  •  1
  •   Bryan Oakley    16 年前

    根据VB6文档,“如果表达式的数据类型是布尔型、字节型、十进制、double、integer、long、sbyte、short、single、uinteger、ulong或ushort,或者包含这些数字类型之一的对象,则isNumeric返回true。如果表达式是可以成功转换为数字的字符或字符串,则返回“真”。

    其中许多不能转换为整数。例如,“1.5”是数字,但不是整数。所以,你可以把它转换成一个数字,但不一定是整数。

        6
  •  0
  •   RS Conley    16 年前

    以下代码在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    16 年前

    你最好的办法是用实际值记录错误,这样你就可以知道发生了什么。

        8
  •  0
  •   jac    16 年前

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

        9
  •  0
  •   Cosmin    13 年前

    刚刚找到这个金块。如果运行以下命令,script 1将返回true,但script 2&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    16 年前

    两种选择…

    变化

    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