使用On Error Resume Next使用If语句

时间:2016-12-24 06:00:02

标签: arrays vba excel-vba error-handling excel

由于On Error Resume Next进入下一个语句而不是下一行,是否有人对使用If语句有任何建议?

On Error Resume Next
For i = 1 To r
    If dataArray(i,1) <10 Then
        intA = intA + 1
    End If
    If dataArray(i,2) <10 Then intB = intB + 1
    If dataArray(i,2) <10 Then _
        intC = intC + 1: intD = intD + 1
Next i
On Error GoTo 0

对于上面的每种If语句样式,如果出现错误,仍会执行添加,例如包含文本的元素dataArray(i,1)。这可以通过错误处理程序修复,但是多个If语句会变得混乱。有没有人有任何建议?

2 个答案:

答案 0 :(得分:1)

对您的问题的严格答案如下:

Option Explicit

Sub main()
    Dim dataArray As Variant
    Dim i As Long, r As Long, intA As Long, intB As Long, intC As Long, intD As Long

    dataArray = Range("A1:D5").Value
    r = UBound(dataArray)
    On Error GoTo SKIP
    For i = 1 To r
        If dataArray(i, 1) < 10 Then intA = intA + 1

        If dataArray(i, 2) < 10 Then
            intB = intB + 1
            intC = intC + 1
            intD = intD + 1
        End If
SKIP:
    Next i
    ' On Error GoTo 0 '<--| you can comment this out being the last statement since upon exiting the default error handling is resumed 

End Sub

答案 1 :(得分:0)

如果你期望数组指定位置的数字值,你真的不需要构建庞大的错误处理程序或使用GoTo,你可以检查变量的Type! 所以,例如:

For i = 1 To r
    If IsNumeric(dataArray(i,1)) And Not IsString(dataArray(i,1)) Then
        If dataArray(i,1) <10 Then
            intA = intA + 1
        End If
        If dataArray(i,2) <10 Then intB = intB + 1
        If dataArray(i,2) <10 Then _
            intC = intC + 1: intD = intD + 1
    End If
Next i

Public Function IsString(ByRef var as Variant) as Boolean
    IsString = (TypeName(var) = "String")
End Function

如您所见,您可以检查IsNumeric,因为字符串可以是数字,然后明确检查Not IsString

因为不仅字符串可以从IsNumeric函数(例如字符)返回True,还有修改示例和扩展自己的函数的方法!

链接: TypeNameIsNumeric

另一个例子(只有一个小数点并允许字符串的数字)。 那么如果输入如下所示:

input

示例:

Sub AcceptOnlyNumbers()
'pass only strings that can be threaten as doubles
    Dim rng As Range
    Dim cl As Range

    Set rng = Sheets(1).[A1:A8]

    For Each cl In rng
        With cl
        If Not (IsNumeric(.Value2) Or (IsNumeric(Val(.Value2)) And _
            Len(.Value2) = Len(CStr(Val(.Value2))))) And .Value2 <> vbNullString Then
                Debug.Print .Value2, "is filtered"
            Else
                Debug.Print .Value2, "is passed"
            End If
        End With
    Next

End Sub

输出:

output

之后,如果十进制是逗号,我们可以用CDbl转换字符串,如果是十进制,则可以转换为Val。随意玩吧!例如,如果您不需要十进制数字,则可以在此之后添加另一个检查(或者,再次构建您自己的 - 仅这些示例,您可以在开始时检查整数):

Public Function IsWholeNumber(ByVal expDbl As Double) as Boolean
    IsWholeNumber = (Int(expDbl) = expDbl)
    'or more bulky but ok too: IsWholeNumber = InStr(Str(expDbl), ".") = 0
End Function

请注意,在小数点国家/地区CDbl适用于dot并且我的示例工作方式不同(使用逗号的值也会被过滤)。

  • ValStr将始终使用美国设置(点为十进制)。

  • CDblCStr会考虑区域设置。

链接: ValWriting International Code