VB6 Can IsNumeric会出错吗?

时间:2009-01-22 17:19:43

标签: vb6 casting isnumeric

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

我问因为我遇到类型不匹配错误,所以在尝试强制转换之前我使用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 个答案:

答案 0 :(得分:6)

由于最大整数大小,您可能会出现溢出;货币类型实际上对大数字表现非常好(但要注意任何地区问题)。有关Int64的讨论,请参阅下面的编辑。

根据IsNumeric上的MSDN文档:

  • 如果数据,IsNumeric返回True 表达式的类型是布尔值,字节, 十进制,双精度,整数,长, SByte,短,单,UInteger, ULong,或UShort,或者对象 包含其中一种数字类型。 如果表达式是,它也返回True 可以是Char或String 成功转换为数字。

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

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

您可以尝试将其转换为double,然后转换为整数。

' 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,但我说它可能会或可能不会在您的方案中有效。如果您没有LARGE_INTEGER类型,它看起来像:

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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

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

当然,您的错误处理首选项可能会有所不同。

答案 3 :(得分:1)

根据VB6文档,如果Expression的数据类型为Boolean,Byte,Decimal,Double,Integer,Long,SByte,Short,Single,UInteger,ULong或UShort,或包含的对象,则IsNumeric返回True。其中一种数字类型。如果Expression是一个可以成功转换为数字的Char或String,它也会返回True。“

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

答案 4 :(得分:1)

是。试试这个:

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

这是一个溢出,但我认为它说明了IsNumeric()的不可靠性(特别是对于整数 - 对于双精度来说它更可靠)。

答案 5 :(得分:0)

以下代码在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使用逗号“3,041.41”处理号码但是VB6处理区域设置有问题,所以如果你使用标准美式英语以外的符号,你会得到奇怪的结果和错误。

答案 6 :(得分:0)

您最好的选择是开始使用它正在使用的实际值记录错误,以便了解最新情况。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

刚发现这个金块。如果运行以下命令,脚本#1将返回TRUE,但脚本#2和&amp; #3将失败:

SELECT ISNUMERIC('98,0') AS isNum   -- Fails

SELECT CONVERT(INT, '98,0')   -- Fails

SELECT CONVERT(NUMERIC(11,4), '98,0')     -- Fails

答案 9 :(得分:-1)

两个选项......

更改

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