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 のドキュメントによると:

  • IsNumeric は、Expression のデータ型が Boolean、Byte、Decimal、Double、Integer、Long、SByte、Short、Single、UInteger、ULong、または UShort であるか、これらの数値型のいずれかを含むオブジェクトである場合に True を返します。また、Expression が数値に正常に変換できる Char または String である場合も True を返します。

  • IsNumeric は、Expression がデータ型 Date またはデータ型 Object であり、数値型を含まない場合、False を返します。Expression が数値に変換できない Char または String の場合、IsNumeric は False を返します。

Type Mismatch が発生しているため、Double が変換を妨げている可能性があります。IsNumeric は、それが整数であることを保証するものではなく、数値の可能性の 1 つに一致することだけを保証します。数値が 2 倍の場合は、地域設定 (カンマとピリオドなど) が例外の原因である可能性があります。

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

編集:明確にした後、オーバーフロー変換が発生しているようです。まず、CInt() の代わりに Long と CLng() を使用してみてください。ただし、エントリが 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

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 に答える
3

はい、「3.41」は数値ですが、整数ではありません。

于 2009-01-22T17:22:39.793 に答える
1

はい。これを試して:

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

これはオーバーフローですが、一般的に IsNumeric() の信頼性が低いことを示していると思います (特に int の場合 - double の場合ははるかに信頼性が高くなります)。

于 2009-01-22T18:15:41.513 に答える
1

VB6 のドキュメントによると、「IsNumeric は、Expression のデータ型が Boolean、Byte、Decimal、Double、Integer、Long、SByte、Short、Single、UInteger、ULong、または UShort、またはそれらのいずれかを含むオブジェクトである場合に True を返します。数値型。Expression が数値に正常に変換できる Char または String の場合も True を返します。」

それらの多くは整数に変換できません。たとえば、「1.5」は数値ですが、整数ではありません。したがって、数値に変換できますが、必ずしも整数になるとは限りません。

于 2009-01-22T17:25:25.733 に答える
0

最善の策は、エラーのログ記録を実際の値で開始して、何が起こっているのかを把握できるようにすることです。

于 2009-01-22T18:59:37.867 に答える
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 に答える
0

文字列を数値に変換できる場合、IsNumeric は true を返します。文字列に数字以外の文字が含まれていても。私は常に文字列を一度に 1 文字ずつループし、各文字をテストします。1 つの文字が失敗した場合、エラーを返すことができます。

于 2009-01-22T19:27:50.057 に答える
0

次のコードは、Visual BASIC 6 で Type Mismatch エラーなしで機能します。

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 に答える
-1

2 つのオプション...

変化する

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 に答える