2011-06-01 38 views
44

我需要将从VBA中获取的字符串从excel中转​​换为整数。为此,我使用了CInt(),它运行良好。但是有机会的话,该字符串可能比许多其他的东西,在这种情况下,我需要设置整数为0。目前我有:vba将字符串转换为int如果字符串是数字

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

的问题是,我无法预测所有可能的非数字可能在这个单元格中的字符串。有没有一种方法可以告诉它转换,如果它是一个整数,并设置为0,如果不是?

干杯 帽

回答

76

使用则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

即使IsNumeric返回True,CInt仍可能因溢出而失败 - 特别是对于小于-32768或大于32767的数字。 – 2011-06-01 14:32:12

+1

为避免溢出问题,您可以使用Int或Fix而不是CInt,尽管它们的行为是在处理非整数十进制数时会略有不同--Cnt回合,而Int向下截断(远离零),Fix向上截断(向零)。 – 2011-06-01 14:38:03

+4

作为使用IsNumeric的替代方法,您可以简单地以默认值0开始,尝试使用Int转换提供的值,并忽略任何错误,如下所示:'Public Function IntOrZero(ByVal vValue As Variant)As Double | IntOrZero = 0 | On Error Resume Next | IntOrZero = Int(vValue)| End Function' - 只需替换|换行符。 – 2011-06-01 14:43:44

0

把它放在一个行:

currentLoad = IIf(IsNumeric(oXLSheet2.Cells(4, 6).Value), CInt(oXLSheet2.Cells(4, 6).Value), 0) 
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 

我选择龙(整数),而不是简单的整型的,因为整数在VBA中的最小/最大大小很差(最小值:-32768,最大值:+32767)。在电子表格操作中,通常在该范围外有一个整数。

上面的代码可以修改为处理从字符串到整数,到货币(使用CCur()),到十进制(使用CDec()),到双(使用CDbl())等的转换。只需要替换转换函数本身(CLng)。更改函数返回类型,并重命名函数变量的所有匹配项以使所有内容保持一致。

-1

这里有三个可能有用的功能。首先检查字符串是否为正确的数字格式,第二个和第三个函数将字符串转换为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

第一个函数具有相当特殊的格式要求,使其与其他答案的问题差不多相关。第二和第三个函数不应该被使用,因为他们所做的只是调用一个vba函数,而要求一个较窄的变量。将它们称为“ConvertStringToDouble”或“ConvertStringToLong”会更合理,这使得它更清晰,为什么它不增加任何价值。 – 2012-08-29 19:23:47

+0

第一个功能是特定的,它检查以确保没有其他字符或打字错误输入(我有问题与人输入额外的字符),所以这只是检查,以确保该字符串可以通过CDbl或CLng函数转换而不吹启动或返回不正确的值。正在使用这些调试功能时纠正余下的问题。除非你总是假设字符串格式正确,否则在转换字符串之前,可以在这两个字符串中检查有效的数字调用......我从不假设。感谢您的评论。 – Doug 2012-08-29 21:28:57

4

强制转为或转换为int,注意以下事项。

这些函数是Excel VBA中取决于系统区域设置的视图函数之一。因此,如果您在欧洲某些国家/地区使用双倍逗号,则会在美国遇到错误。

例如,在欧洲的Excel版本0.5将与CDbl()表现良好,但在美国的版本,它会导致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 

当然,你也可以考虑人们使用逗号和点的情况,例如三千如3,000.00。如果您需要这些类型的功能,那么您必须检查另一个解决方案。

+1

另外,美国语言环境中的CLng会将括号中的数字解析为负数。例如,'CLng(“(123)”)'返回'-123'。参见例如https://support.office.com/en-in/article/Type-Conversion-Functions-8ebb0e94-2d43-4975-bb13-87ac8d1a2202 – cxw 2015-03-17 16:02:00