On Error 陳述式 (Visual Basic)

啟用錯誤處理,並指定程序內的常式位置;也可以用來停用錯誤處理。 On Error 陳述式用於非結構化錯誤處理中,而且可以使用,而非結構化例外狀況處理。 結構化例外狀況處理內建於 .NET 中,通常更有效率,因此在應用程式中處理執行階段錯誤時建議使用。

如果沒有錯誤處理或例外狀況處理,則發生的任何執行階段錯誤皆屬於嚴重:顯示錯誤訊息並停止執行。

注意

Error 關鍵字也用於 Error 陳述式中,其支援回溯相容性。

語法

On Error { GoTo [ line | 0 | -1 ] | Resume Next }

組件

詞彙 定義
GoToline 啟用從必要 line 引數中所指定行開始的錯誤處理。 line 引數可以是任何行標籤或行號。 如果發生執行階段錯誤,控制項會分支到指定行,使錯誤處理常式處於作用中狀態。 指定的行必須與 On Error 陳述式位於相同的程序中,否則會發生編譯時期錯誤。
GoTo 0 在目前程序中停用已啟用的錯誤處理常式,並將其重設為 Nothing
GoTo -1 在目前程序中停用已啟用的例外狀況,並將其重設為 Nothing
Resume Next 指定當執行階段錯誤發生時,控制項會緊接在發生錯誤的陳述式之後移至陳述式,然後從該點繼續執行。 存取物件時請使用此表單,而非 On Error GoTo

備註

注意

建議您盡可能在程式碼中使用結構化例外狀況處理,而非使用非結構化例外狀況處理和 On Error 陳述式。 如需詳細資訊,請參閱 Try...Catch...Finally 陳述式

「enabled」錯誤處理常式是由 On Error 陳述式開啟的錯誤處理常式。 「active」錯誤處理常式是在處理錯誤程序中啟用的處理常式。

如果在發生錯誤時錯誤處理常式為作用中 (發生錯誤所在與 ResumeExit SubExit FunctionExit Property 陳述式之間),則目前程序的錯誤處理常式無法處理錯誤。 控制項會傳回呼叫程序。

如果呼叫程序有啟用的錯誤處理常式,則會啟動以處理錯誤。 如果呼叫程序的錯誤處理常式也是作用中,則控制項會透過先前的呼叫程序傳回,直到啟用但非作用中時,才會找到錯誤處理常式。 如果找不到此類錯誤處理常式,則錯誤會在實際發生的時間點視為嚴重。

每次錯誤處理常式將控制項傳回呼叫程序時,該程序就會變成目前的程序。 一旦錯誤由任何程序中的錯誤處理常式處理之後,執行就會在 Resume 陳述式所指定的時間點繼續執行目前的程序。

注意

錯誤處理不是 Sub 程序或 Function 程序。 其是以行標籤或行號標示的程式碼區段。

Number 屬性

錯誤處理依賴於 Err 物件 Number 屬性中的值,以判斷錯誤的原因。 常式應該在發生任何其他錯誤之前,或在呼叫可能造成錯誤的程序之前,先在 Err 物件中測試或儲存相關的屬性值。 Err 物件中的屬性值只會反映最新的錯誤。 與 Err.Number 相關聯的錯誤訊息包含在 Err.Description 中。

Throw 陳述式

使用 Err.Raise 方法引發的錯誤會將 Exception 屬性設定為 Exception 類別的新建立執行個體。 為了支援引發衍生例外狀況類型的例外狀況,語言中支援 Throw 陳述式。 這會採用要擲回例外狀況執行個體的單一參數。 下列範例顯示這些功能如何搭配現有的例外狀況處理支援使用:

    On Error GoTo Handler
    Throw New DivideByZeroException()
Handler:
    If (TypeOf Err.GetException() Is DivideByZeroException) Then
    ' Code for handling the error is entered here.
    End If

請注意,不論例外狀況類別為何,On Error GoTo 陳述式都會捕捉所有錯誤。

在錯誤繼續下一步

On Error Resume Next 會導致執行緊接在造成執行階段錯誤的陳述式之後,或緊接在包含 On Error Resume Next 陳述式的程序中最新呼叫之後的陳述式繼續執行。 即使發生執行階段錯誤,此陳述式仍允許繼續執行。 您可以將錯誤處理放在發生錯誤的位置,而非將控制項轉移至程序中的另一個位置。 呼叫另一個程序時,On Error Resume Next 陳述式會變成非作用中,因此如果您想要在該常式中內嵌錯誤處理,則應該在每個呼叫的常式中執行 On Error Resume Next 陳述式。

注意

當處理存取其他物件期間所產生的錯誤時,On Error Resume Next 建構可能比 On Error GoTo 更好。 每次與物件互動之後檢查 Err 時,就會移除程式碼所存取物件相關的模棱兩可。 您可以確定哪個物件將錯誤碼放在 Err.Number 中,以及哪些物件原本產生錯誤 (Err.Source 中指定的物件)。

發生錯誤 GoTo 0

On Error GoTo 0 會停用目前程序中的錯誤處理。 即使程序包含行號 0,其不會將第 0 行指定為錯誤處理代碼的開頭。 如果沒有 On Error GoTo 0 陳述式,當程序結束時,系統會自動停用錯誤處理常式。

On Error GoTo -1

On Error GoTo -1 會停用目前程序中的例外狀況。 即使程序包含行號 -1,其不會將第 -1 行指定為錯誤處理代碼的開頭。 如果沒有 On Error GoTo -1 陳述式,當程式結束時,系統會自動停用例外狀況。

若要防止錯誤處理代碼在發生錯誤時執行,請在緊接錯誤處理常式之前放置 Exit SubExit FunctionExit Property 陳述式,如下列片段所示:

Public Sub InitializeMatrix(ByVal Var1 As Object, ByVal Var2 As Object)
   On Error GoTo ErrorHandler
   ' Insert code that might generate an error here
   Exit Sub
ErrorHandler:
   ' Insert code to handle the error here
   Resume Next
End Sub

在這裡,錯誤處理代碼會遵循 Exit Sub 陳述式,並在 End Sub 陳述式前面將其與程序流程分開。 您可以在程序中的任何位置放置錯誤處理代碼。

未截獲的錯誤

當物件以可執行檔的形式執行時,物件中的未截獲錯誤會傳回給控制應用程式。 在開發環境中,只有在設定適當的選項時,才會將未截獲的錯誤傳回至控制應用程式。 如需偵錯期間應該設定哪些選項的描述、如何設定選項,以及主機是否可以建立類別,請參閱主應用程式的文件。

如果您建立存取其他物件的物件,您應該嘗試處理其所傳回的任何未處理錯誤。 如果無法這樣做,請將 Err.Number 中的錯誤碼對應至其中一個自己的錯誤,然後將錯誤碼傳回物件呼叫端。 您應該將錯誤碼新增至 VbObjectError 常數來指定錯誤。 例如,如果您的錯誤碼是 1052,請予以指派,如下所示:

Err.Number = vbObjectError + 1052

警告

在呼叫 Windows 動態連結程式庫 (DLL) 期間發生系統錯誤時,不會引發例外狀況,且無法使用 Visual Basic 錯誤捕捉來截獲。 呼叫 DLL 函式時,您應該檢查每個傳回值是否成功或失敗 (根據 API 規格),並在發生失敗時檢查 Err 物件 LastDLLError 屬性中的值。

範例

這個範例會先使用 On Error GoTo 陳述式來指定程序中錯誤處理常式的位置。 在此範例中,嘗試除以零會產生錯誤號碼 6。 錯誤會在錯誤處理常式中處理,然後控制項會傳回至造成錯誤的陳述式。 On Error GoTo 0 陳述式會關閉錯誤捕捉。 然後,On Error Resume Next 陳述式會用來延遲錯誤捕捉,讓下一個陳述式所產生的錯誤內容可以針對特定情況得知。 請注意,Err.Clear 用來在處理錯誤之後清除 Err 物件的屬性。

Public Sub OnErrorDemo()
   On Error GoTo ErrorHandler   ' Enable error-handling routine.
   Dim x As Integer = 32
   Dim y As Integer = 0
   Dim z As Integer
   z = x / y   ' Creates a divide by zero error
   On Error GoTo 0   ' Turn off error trapping.
   On Error Resume Next   ' Defer error trapping.
   z = x / y   ' Creates a divide by zero error again
   If Err.Number = 6 Then
      ' Tell user what happened. Then clear the Err object.
      Dim Msg As String
      Msg = "There was an error attempting to divide by zero!"
      MsgBox(Msg, , "Divide by zero error")
      Err.Clear() ' Clear Err object fields.
   End If
Exit Sub      ' Exit to avoid handler.
ErrorHandler:  ' Error-handling routine.
   Select Case Err.Number   ' Evaluate error number.
      Case 6   ' Divide by zero error
         MsgBox("You attempted to divide by zero!")
         ' Insert code to handle this error
      Case Else
         ' Insert code to handle other situations here...
   End Select
   Resume Next  ' Resume execution at the statement immediately 
                ' following the statement where the error occurred.
End Sub

需求

命名空間:Microsoft.VisualBasic

組件:Visual Basic 執行階段程式庫 (位於 Microsoft.VisualBasic.dll 中)

另請參閱