5

是否可以使用 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
4

10 回答 10

7

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

根据IsNumeric上的 MSDN 文档:

  • 如果 Expression 的数据类型为 Boolean、Byte、Decimal、Double、Integer、Long、SByte、Short、Single、UInteger、ULong 或 UShort,或包含其中一种数字类型的 Object,则 IsNumeric 返回 True。如果 Expression 是可以成功转换为数字的 Char 或 String,它也返回 True。

  • 如果 Expression 的数据类型为 Date 或 Object 的数据类型并且它不包含数值类型,则 IsNumeric 返回 False。如果 Expression 是不能转换为数字的 Char 或 String,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 时更加困难。

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

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

此示例来自LDAP 密码过期示例,但就像我说的那样,它可能适用于您的场景,也可能不适用。如果您没有 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
于 2009-01-22T17:28:16.850 回答
3

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

于 2009-01-22T17:22:39.793 回答
3

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

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

于 2009-01-22T18:24:55.410 回答
1

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

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

于 2009-01-22T17:25:25.733 回答
1

是的。试试这个:

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

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

于 2009-01-22T18:15:41.513 回答
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 处理区域设置有问题,所以如果您使用标准美式英语以外的符号,您会得到奇怪的结果和错误。

于 2009-01-22T17:58:57.990 回答
0

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

于 2009-01-22T18:59:37.867 回答
0

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

于 2009-01-22T19:27:50.057 回答
0

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

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

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

SELECT CONVERT(NUMERIC(11,4), '98,0')     -- Fails
于 2010-01-29T20:50:04.600 回答
-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
于 2009-01-22T19:43:00.133 回答