VBA преобразовать строку в INT, если строка является числом

42

Мне нужно преобразовать строку, полученную из excel, в VBA в interger. Для этого я использую CInt(), который работает хорошо. Однако есть вероятность, что строка может быть чем-то иным, чем числом, в этом случае мне нужно установить целое число в 0. В настоящее время у меня есть:

If oXLSheet2.Cells(4, 6).Value <> "example string" Then
  currentLoad = CInt(oXLSheet2.Cells(4, 6).Value)
Else
  currentLoad = 0
End If

Проблема в том, что я не могу предсказать все возможные числовые строки, которые могут быть в этой ячейке. Есть ли способ, который я могу сказать, чтобы преобразовать, если это целое число и установлено в 0, если нет?

Приветствия Cap

Теги:
excel-vba
excel

5 ответов

69
Лучший ответ

Используйте IsNumeric. Он возвращает true, если в противном случае это число или false.

Public Sub NumTest()
    On Error GoTo MyErrorHandler

    Dim myVar As Variant
    myVar = 11.2 'Or whatever

    Dim finalNumber As Integer
    If IsNumeric(myVar) Then
        finalNumber = CInt(myVar)
    Else
        finalNumber = 0
    End If

    Exit Sub

MyErrorHandler:
    MsgBox "NumTest" & vbCrLf & vbCrLf & "Err = " & Err.Number & _
        vbCrLf & "Description: " & Err.Description
End Sub
  • 3
    CInt все еще может потерпеть неудачу из-за переполнения, даже если IsNumeric возвращает True, особенно для чисел меньше -32768 или больше 32767.
  • 1
    Чтобы избежать проблемы переполнения, вы можете использовать Int или Fix вместо CInt, хотя их поведение немного отличается, когда дело доходит до работы с нецелыми десятичными числами - CInt округляет, тогда как Int усекает вниз (от нуля) и исправляет усечения вверх (к нулю).
Показать ещё 2 комментария
4

Передать в long или cast to int, помнить следующее.

Эти функции являются одной из функций представления в Excel VBA, которые зависят от региональных настроек системы. Поэтому, если вы используете запятую в своем двойном, как в некоторых странах Европы, вы испытаете ошибку в США.

Например, в европейской версии excel версии 0,5 будет хорошо работать с CDbl(), но в US-версии это приведет к 5. Поэтому я рекомендую использовать следующую альтернативу:

Public Function CastLong(var As Variant)

    ' replace , by .
    var = Replace(var, ",", ".")        

    Dim l As Long
    On Error Resume Next
    l = Round(Val(var))

    ' if error occurs, l will be 0
    CastLong = l

End Function

' similar function for cast-int, you can add minimum and maximum value if you like
' to prevent that value is too high or too low.
Public Function CastInt(var As Variant)

    ' replace , by .
    var = Replace(var, ",", ".")

    Dim i As Integer
    On Error Resume Next
    i = Round(Val(var))

    ' if error occurs, i will be 0
    CastInt = i

End Function

Конечно, вы также можете вспомнить случаи, когда люди используют запятые и точки, например, три тысячи, как 3000,00. Если вам требуются функции для подобных случаев, вам необходимо проверить другое решение.

  • 1
    Кроме того, CLng в регионах США будет анализировать числа в скобках как отрицательные. Например, CLng("(123)") возвращает -123 . Смотрите, например, support.office.com/en-in/article/…
2

Попробуйте следующее:   currentLoad = ConvertToLongInteger(oXLSheet2.Cells(4, 6).Value) с этой функцией:

Function ConvertToLongInteger(ByVal stValue As String) As Long
 On Error GoTo ConversionFailureHandler
 ConvertToLongInteger = CLng(stValue)  'TRY to convert to an Integer value
 Exit Function           'If we reach this point, then we succeeded so exit

ConversionFailureHandler:
 'IF we've reached this point, then we did not succeed in conversion
 'If the error is type-mismatch, clear the error and return numeric 0 from the function
 'Otherwise, disable the error handler, and re-run the code to allow the system to 
 'display the error
 If Err.Number = 13 Then 'error # 13 is Type mismatch
      Err.Clear
      ConvertToLongInteger = 0
      Exit Function
 Else
      On Error GoTo 0
      Resume
 End If
End Function

Я выбрал Long (Integer) вместо простого Integer, потому что минимальный/максимальный размер Integer в VBA является crummy (min: -32768, max: +32767). Обычно для работы с электронными таблицами существует целое число за пределами этого диапазона.

Вышеприведенный код может быть изменен, чтобы обрабатывать преобразование из строки в целые числа, в-Currency (с использованием CCur()), to-Decimal (с использованием CDec()), to-Double (с использованием CDbl()) и т.д. Просто замените функцию преобразования (CLng). Измените возвращаемый тип функции и переименуйте все вхождения функциональной переменной, чтобы все было согласовано.

0

Вот три функции, которые могут быть полезны. Сначала проверяет строку для правильного числового формата, вторая и третья функции преобразуют строку в Long или Double.

Function IsValidNumericEntry(MyString As String) As Boolean
'********************************************************************************
'This function checks the string entry to make sure that valid digits are in the string.
'It checks to make sure the + and - are the first character if entered and no duplicates.
'Valid charcters are 0 - 9, + - and the .
'********************************************************************************
Dim ValidEntry As Boolean
Dim CharCode As Integer
Dim ValidDigit As Boolean
Dim ValidPlus As Boolean
Dim ValidMinus As Boolean
Dim ValidDecimal As Boolean
Dim ErrMsg As String

ValidDigit = False
ValidPlus = False
ValidMinus = False
ValidDecimal = False

ValidEntry = True
For x = 1 To Len(MyString)
    CharCode = Asc(Mid(MyString, x, 1))
    Select Case CharCode

    Case 48 To 57 ' Digits 0 - 9
        ValidDigit = True

    Case 43 ' Plus sign

    If ValidPlus Then 'One has already been detected and this is a duplicate
        ErrMsg = "Invalid entry....too many plus signs!"
        ValidEntry = False
        Exit For
    ElseIf x = 1 Then 'if in the first positon it is valide
        ValidPlus = True
    Else 'Not in first position and it is invalid
        ErrMsg = "Invalide entry....Plus sign not in the correct position! "
        ValidEntry = False
        Exit For
    End If

    Case 45 ' Minus sign

    If ValidMinus Then 'One has already been detected and this is a duplicate
        ErrMsg = "Invalide entry....too many minus signs! "
        ValidEntry = False
        Exit For
    ElseIf x = 1 Then 'if in the first position it is valid
        ValidMinus = True
    Else 'Not in first position and it is invalid
        ErrMsg = "Invalide entry....Minus sign not in the correct position! "
        ValidEntry = False
        Exit For
    End If

    Case 46 ' Period

    If ValidDecimal Then 'One has already been detected and this is a duplicate
        ErrMsg = "Invalide entry....too many decimals!"
        ValidEntry = False
        Exit For
    Else
        ValidDecimal = True
    End If

    Case Else
        ErrMsg = "Invalid numerical entry....Only digits 0-9 and the . + - characters are valid!"
        ValidEntry = False
        Exit For

    End Select

Next

    If ValidEntry And ValidDigit Then
        IsValidNumericEntry = True
    Else
        If ValidDigit = False Then
            ErrMsg = "Text string contains an invalid numeric format." & vbCrLf _
            & "Use only one of the following formats!" & vbCrLf _
            & "(+dd.dd  -dd.dd  +dd  -dd  dd.d or dd)! "
        End If
        MsgBox (ErrMsg & vbCrLf & vbCrLf & "You Entered:   " & MyString)
        IsValidNumericEntry = False
    End If

End Function

Function ConvertToLong(stringVal As String) As Long
'Assumes the user has verified the string contains a valide numeric entry.
'User should call the function IsValidNumericEntry first especially after any user input
'to verify that the user has entered a proper number.

 ConvertToLong = CLng(stringVal)


End Function
Function ConvertToDouble(stringVal As String) As Double
'Assumes the user has verified the string contains a valide numeric entry.
'User should call the function IsValidNumericEntry first especially after any user input
'to verify that the user has entered a proper number.

    ConvertToDouble = CDbl(stringVal)

End Function
  • 1
    Первая функция имеет довольно специфические требования к формату, которые делают ее не столь важной для вопроса, как другие ответы. 2-ю и 3-ю функцию не следует использовать, потому что все, что они делают, это вызывают одну функцию vba, требуя более узкой переменной. Было бы более разумно называть их «ConvertStringToDouble» или «ConvertStringToLong», что делает еще более понятным, почему он не добавляет значения.
  • 0
    Первая функция специфична тем, что она проверяет, не вводятся ли другие символы или опечатки (у меня были проблемы с людьми, вводящими дополнительные символы), поэтому она просто проверяет, может ли строка быть преобразована функциями CDbl или CLng, не взрываясь или возвращая неверные значения. Исправьте остальное, поскольку я использовал эти функции отладки. Можно было бы проверить правильность числового вызова в обоих из них перед преобразованием строки, если вы не всегда предполагаете, что строка имеет правильный формат ... Я никогда не предполагаю. Спасибо за комментарии.
0

Чтобы поставить его на одну строку:

currentLoad = IIf(IsNumeric(oXLSheet2.Cells(4, 6).Value), CInt(oXLSheet2.Cells(4, 6).Value), 0)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню