2016-12-24 38 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不能被觸發並且後續錯誤不會被捕獲。 –