2016-12-24 35 views
0

因为错误恢复下一步进行到下一个语句,而不是下一行,有没有人有任何建议,以使用它与If语句?使用错误继续下一个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语句会变得混乱。有没有人有什么建议?

+1

可以更好地解释什么是你想达到什么目的?以及你在哪里得到你的错误(不使用'On Error Resume Next')。有时候最好是陷阱并处理你的错误) –

+0

你总是可以添加一个额外的测试'如果Err.Number = 0',你也可以在适当的地方使用像'Err.Clear'这样的语句。但是,您不应该大量使用'On Error Resume Next'机制,它只是一个非常方便的“诀窍”,但如果您确实想在您的代码中指望它,那么您应该重新考虑这一决定。 –

+0

例如,在上面的代码中,如果变量不能保证是一个数字,一个*好的*代码首先应该用'IsNumeric'来测试它,而不是依靠错误处理来计算,因为后者不是一个“流量控制”指示。 –

回答

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将始终使用美国设置(如点十进制)。

  • CDbl,CStr将考虑区域设置。

链接: ValWriting International Code

+1

'IsNumeric()'函数必须处理_consciously_。例如'IsNumeric(“1,.23”)'会返回'True' ...所以我只有在知道我有“声音”数据时才使用它,也就是_real_数字或文本 – user3598756

+0

@ user3598756,因为没有数据 - 例如,这只是一个方式如何可以完成与不错误处理程序。但是,是的,你是对的,你给了一个很好的补充,但如果提问者期望你提到的事情 - 很容易照顾他们!毕竟,正如我所提到的 - 提问者可以从它开始,建立自己的东西。我认为这不仅仅是复制/粘贴SO的答案,尤其是对于这类问题。 – CommonSense

+0

我不是说你的方法_won't_工作。我只是添加了一个关于可能的缺点的警告,并且(可能)都提高了你的答案,并帮助人们阅读它 – user3598756

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 
+0

那么我们在评论区的讨论精神中,但最好还包括您提出的'SpecialCells'成语。 –

+0

@ A.S.H,我很喜欢,但它会更有效,有真正的数据结构,以显示它 – user3598756

+1

@ user3598756谢谢!顺便说一句,Err值是否需要通过Resume语句重置?我似乎回想起,如果不这样做,Err将保持为<> 0,这意味着Err不能被触发并且后续错误不会被捕获。 –