VB6 IsNumeric 会错吗?

发布于 2024-07-11 23:52:41 字数 687 浏览 5 评论 0原文

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

Is it possible to test a string with IsNumeric() and for it to return true, but when you cast that same string to an integer using CInt() and assign it to a variable of type integer that it will give a type mismatch error?

I ask because I was getting a type mismatch error, so I used IsNumeric() to check the string was numeric before trying to cast it, but I still get the error.

I am tearing my hair out with this.

Here is the code in question.
iGlobalMaxAlternatives = CInt(strMaxAlternatives) is where the error is occuring.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

ゃ人海孤独症 2024-07-18 23:52:41

由于最大整数大小,您可能会发生溢出; 货币类型实际上对于大量数字来说效果很好(但要注意任何区域问题)。 请参阅下面的编辑以了解 Int64 讨论。

根据关于 IsNumeric 的 MSDN 文档:

  • IsNumeric 返回 True,如果数据
    表达式的类型为布尔型、字节型、
    小数、双精度、整数、长整型、
    SByte、短整型、单个、UInteger、
    ULong,或 UShort,或一个对象
    包含这些数字类型之一。
    如果表达式是,它也会返回 True
    一个字符或字符串可以是
    成功转换为数字。

  • 如果表达式,IsNumeric 返回 False
    数据类型为 Date 或数据类型
    对象并且它不包含
    数字类型。 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

You may have an overflow due the maximum integer size; the currency type actually does very well for large numbers (but beware of any regional issues). See edits below for Int64 discussion.

According to MSDN documentation on IsNumeric:

  • IsNumeric returns True if the data
    type of Expression is Boolean, Byte,
    Decimal, Double, Integer, Long,
    SByte, Short, Single, UInteger,
    ULong, or UShort, or an Object that
    contains one of those numeric types.
    It also returns True if Expression is
    a Char or String that can be
    successfully converted to a number.

  • IsNumeric returns False if Expression
    is of data type Date or of data type
    Object and it does not contain a
    numeric type. IsNumeric returns False
    if Expression is a Char or String
    that cannot be converted to a number.

Since you are getting a Type Mismatch, perhaps a Double is interfering with the conversion. The IsNumeric does not guarantee it is an Integer, just that it matches one of the numeric possibilities. If the number is a double, perhaps regional settings (comma versus period and so on) are causing the exception.

You might try converting it to a double and then to an integer.

' 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))

EDIT: After your clarification, it appears you are getting an overflow conversion. First try using a Long and CLng() instead of CInt(). There is still a chance the entry is Int64 though, which is more difficult using VB6.

I have used the following code for the LARGE_INTEGER and Integer8 types (both Int64), but it may not work for your situation:

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

This example was from an LDAP password expiration example, but like I said it may or may not work in your scenario. If you don't have the LARGE_INTEGER type, it looks like:

Private Type LARGE_INTEGER
    LowPart As Long
    HighPart As Long
End Type

Search for LARGE_INTEGER and VB6 for more information.

EDIT: For debugging, it may be useful to temporarily avoid error handling and then turn it back on after passing the troubling lines:

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
撩动你心 2024-07-18 23:52:41

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

Yes, "3.41" would be numeric but not an integer.

指尖上得阳光 2024-07-18 23:52:41

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

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

VB6 doesn't provide good methods to guarantee CInt won't fail. I've found the simplest way is to just use error-handling.

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

Of course your error-handling preferences may vary.

我的鱼塘能养鲲 2024-07-18 23:52:41

是的。 试试这个:

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

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

Yes. Try this:

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

This one's an overflow, but I think it illustrates the unreliability of IsNumeric() in general (especially for ints - for doubles it's much more reliable).

╰◇生如夏花灿烂 2024-07-18 23:52:41

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

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

According to the VB6 documentation, "IsNumeric returns True if the data type of Expression is Boolean, Byte, Decimal, Double, Integer, Long, SByte, Short, Single, UInteger, ULong, or UShort, or an Object that contains one of those numeric types. It also returns True if Expression is a Char or String that can be successfully converted to a number."

Many of those cannot be converted to an Integer. For example "1.5" is numeric but it's not an integer. So, you can convert it to a number, but not necessarily an integer.

债姬 2024-07-18 23:52:41

以下代码在 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 在处理区域设置方面存在问题,因此如果您使用标准美式英语以外的符号,您将得到奇怪的结果和错误。

The following code works without a Type Mismatch error in Visual BASIC 6

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

The same for this variant

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

Posting the code in question would help answer your question. Basically there are several function in VB6 that are used to convert strings into number.

CInt and Int convert into number but handle rounding different. Direct assignment works and equivalent to using CInt. Howver I recommend continuing to use CInt to make the operation clear to you and your fellow developers in the future.

CInt works on number with commas like "3,041.41" However VB6 has problem handling region settings so if you are using notation other than standard American English you will get strange results and errors.

假情假意假温柔 2024-07-18 23:52:41

最好的选择是开始使用正在使用的实际值记录错误,以便您可以弄清楚发生了什么。

Your best bet is to start logging the errors with the actual values it's working with so you can figure out whats going on.

我纯我任性 2024-07-18 23:52:41

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

IsNumeric will return true if it can convert the string to a number. Even if there are non-numeric characters in the string. I always loop though the string one character at a time and test each character. If one character fails then I can return an error.

人事已非 2024-07-18 23:52:41

刚刚发现这个金块。 如果运行以下命令,脚本 #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

Just found this nugget. If you run the following, script #1 returns TRUE but script #2 & #3 will fail:

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

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

SELECT CONVERT(NUMERIC(11,4), '98,0')     -- Fails
ペ泪落弦音 2024-07-18 23:52:41

两个选项...

更改

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

Two options...

Change

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

To

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

Or

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文