共用方式為


執行階段錯誤處理的項目

錯誤和錯誤處理

開發應用程式時,您需要考慮在出現錯誤時,會發生什麼情況。 應用程式會發生錯誤有兩個原因。 第一,應用程式執行時的某些狀況會使本來有效的程式碼失敗。 例如,如果您的程式碼企圖開啟一個已經被使用者刪除的資料表,則會發生錯誤。 第二,您的程式碼可能包含不正確的邏輯,使得它無法執行您想要做的事。 例如,如果您的程式碼企圖將一個值除以零,則會發生錯誤。

如果您沒有撰寫錯誤處理,當在您的程式碼發生錯誤時,Visual Basic 會停止執行,並顯示錯誤訊息。 當這件事發生時,您應用程式的使用者可能會覺得迷惑和挫折。 您可以在您的程式碼中包含完備的錯誤處理常式來處理任何可能會發生的錯誤,以事先預防許多問題。

當您在程序中加入錯誤處理時,您應該考慮錯誤發生時程序將如何改變執行方向。 將執行轉向錯誤處理常式的第一步是在程序中含入某種形式的 On Error 陳述式,以啟動錯誤處理常式。 On Error 陳述式在有錯誤時,會指引執行方向。 如果沒有 On Error 陳述式,當錯誤發生時,Visual Basic 會停止執行並顯示錯誤訊息。

當一個具有已啟動之錯誤處理常式的程序發生錯誤時,Visual Basic 不會顯示正常的錯誤訊息。 反之,如果錯誤處理常式存在的話,它會將執行轉向該處。 當執行傳到一個已啟動的錯誤處理常式時,該錯誤處理常式即成為作用中。 當錯誤處理常式在工作中,您可以判斷發生的錯誤類型,並以您所選擇的方式解決錯誤。 Access 提供三種物件,內含已發生之錯誤的相關資訊,ADO Error 物件、Visual Basic Error 物件和 DAO Error 物件。

當錯誤發生時改變執行方向

錯誤處理常式會指定當錯誤發生時,程序會如何進行。 例如,如果發生了特定的錯誤,您可能想要結束該程序,或更正引起錯誤的狀況,並繼續執行。 On ErrorResume 陳述式可讓您決定發生錯誤時執行動作要如何進行。

On Error 陳述式

On Error 陳述式會啟動或停用錯誤處理常式。 如果錯誤處理常式被啟動,則當錯誤發生時,執行會傳到錯誤處理常式。

On Error 陳述式有三種形式:On Error GoTo labelOn Error GoTo 0On Error Resume NextOn Error GoTo label 陳述式會從找到它的那一行開始,啟動錯誤處理常式。 您應該在錯誤可能發生的第一行之前啟動錯誤處理常式。 當錯誤處理常式為作用中並且發生錯誤時,執行會傳到由 label 引數指定的行。

label 引數指定的行應該是錯誤處理常式的開頭。 例如,下列程序指定當錯誤發生時,執行傳到的那一行標有:

Function MayCauseAnError() 
    ' Enable error handler. 
    On Error GoTo Error_MayCauseAnError 
    .            ' Include code here that may generate error. 
    . 
    . 
 
Error_MayCauseAnError: 
    .            ' Include code here to handle error. 
    . 
    . 
End Function

On Error GoTo 0 陳述式會停用程序中的錯誤處理。 即使程序中包含編號為 0 的行,它也不會將第 0 行指定為錯誤處理程式碼的開始。 如果您的程式碼中沒有 On Error GoTo 0 陳述式,當程序已完全執行,錯誤處理常式會自動停用。 On Error GoTo 0 陳述式會重設 Err 物件的屬性,與 Err 物件的清除方法有相同效果。

On Error Resume Next 陳述式會略過引起錯誤的行,並將執行轉向引起錯誤之行的下一行。 執行不會被中斷。 如果您想要在預期會發生錯誤的行之後立即檢查 Err 物件的屬性,並處理程式內的錯誤,而不是在錯誤處理程式中處理錯誤,請使用 On Error Resume Next 語句。

Resume 陳述式

Resume 陳述式從錯誤處理常式中將執行導回程序本文。 如果您想要從程序中某一個特別的點繼續執行,您可以在錯誤處理常式中包含 Resume 陳述式。 不過, Resume 陳述式並非必須;您也可以在錯誤處理常式之後結束程序。

Resume 陳述式有三種形式。 ResumeResume 0 陳述式將執行傳回發生錯誤的那一行。 Resume Next 陳述式將執行傳回發生錯誤之行的下一行。 Resume label 陳述式會將執行傳至由 label 引數指定的行。 label 引數必須指出一個行標籤或行號。

當使用者必須進行修正時,您通常會使用 ResumeResume 0 陳述式。 例如,如果您提示使用者提供欲開啟之資料表的名稱,而且使用者輸入了一個不存在的資料表名稱,您可以再次提示使用者,並繼續執行引起錯誤的陳述式。

當您的程式碼為了錯誤處理常式中發生的錯誤進行更正時,若您想要繼續執行,不想重新執行造成錯誤的那一行,您可以使用 Resume Next 陳述式。 當您想要在程式中的另一個點繼續執行時,請使用 Resume標籤 句,此程式是由 label 自變數所指定。 比方說,您可能想在一個結束常式繼續執行,如下一節中所述。

結束程序

當您在程序中包含錯誤處理常式時,也應該包含一個結束常式,使錯誤處理常式只有在發生錯誤時才會執行。 您可以指定一個附有一行標籤的結束常式,就如同您指定一個錯誤處理常式一樣。

例如,您可以在前一個節的範例中加入一個結束常式。 如果錯誤並未發生,則錯誤處理常式會在程序本體之後執行。 如果發生了錯誤,則錯誤處理常式中的程式碼執行後,執行會傳到結束常式。 結束常式含有 Exit 陳述式。

Function MayCauseAnError() 
    ' Enable error handler. 
    On Error GoTo Error_MayCauseAnError 
    .            ' Include code here that may generate error. 
    . 
    . 
 
Exit_MayCauseAnError: 
    Exit Function 
 
Error_MayCauseAnError: 
    .            ' Include code to handle error. 
    . 
    . 
    ' Resume execution with exit routine to exit function. 
    Resume Exit_MayCauseAnError 
End Function

處理巢狀程序中的錯誤

沒有錯誤處理常式的巢狀程序中發生錯誤時,Visual Basic 會沿著呼叫序列往回搜尋,找出在另一個程序中啟動的錯誤處理常式,而不只是停止執行。 此舉可讓您的程式碼有機會更正另一個程序中的錯誤。 例如,假設程序 A 呼叫程序 B,程序 B 呼叫程序 C。如果程序 C 發生錯誤,而且沒有錯誤處理常式啟動,Visual Basic 會檢查程序 B,接著是程序 A,來找到已啟用的錯誤處理常式。 如果有已啟用的錯誤處理常式,執行會傳到該錯誤處理常式。 如果沒有,執行會中止並顯示一則錯誤訊息。

在作用中的錯誤處理常式內發生錯誤時,Visual Basic 也會沿著呼叫序列往回搜尋已啟動的錯誤處理常式。 使用 Err 物件的 Raise 方法來引起作用中的錯誤處理常式內發生錯誤,您可以強制 Visual Basic 沿著呼叫序列往回搜尋。 在處理非您所預期的錯誤處理常式中的錯誤時,此作法相當好用。 如果發生了非預期的錯誤,您可以在錯誤處理常式內重新產生該錯誤,則執行會傳回呼叫序列,以尋找另一個被建立來處理該錯誤的錯誤處理常式。

例如,假設程序 C 有一個已啟動的錯誤處理常式,但是該錯誤處理常式並未更正已發生的錯誤。 一旦錯誤處理常式已檢查了所有您預期的錯誤,它可以重新產生原始的錯誤。 執行即沿著呼叫序列往回傳到程序 B 中的錯誤處理常式 (如果有的話),提供此錯誤處理常式更正錯誤的機會。 如果程序 B 中沒有錯誤處理常式,或它無法更正錯誤,而將其重新產生,則執行會傳到程序 A 的錯誤處理常式 (假設其存在)。

換一種方式來說明此概念,假設您有巢狀的程序,其中包含類型不符錯誤的錯誤處理,且這是您所預期的錯誤訊息。 有時候,非您所預期、除數為零的錯誤,會出現在程序 C。如果您包含重新產生原始錯誤的陳述式,則執行會沿著呼叫序列傳回至另一個錯誤處理常式,如果有的話。 如果您已修正呼叫序列中的另一程序中除數為零的錯誤,該錯誤將會被修正。 如果您的程式碼沒有重新產生錯誤,程序會繼續執行,但不會修正除數為零的錯誤。 此舉接下來可能導致這組巢狀程序中發生其他錯誤。

總而言之,如果發生下列情況,則 Visual Basic 會沿著呼叫序列往回搜尋已啟動的錯誤處理常式:

  • 在不含已啟用之錯誤處理常式的程序中發生錯誤。

  • 在使用中錯誤處理常式內發生錯誤。 如果您使用 Err 物件的 Raise 方法來引起錯誤,則可以強制 Visual Basic 透過呼叫清單往回搜尋已啟用的錯誤處理常式。

取得關於錯誤的資訊

執行傳到錯誤處理常式之後,您的程式碼必須判斷定發生哪一種錯誤,並解決它。 Visual Basic 和 Access 提供多個語言元件,可用來取得特定錯誤的相關資訊。 每一個都適用於不同類型的錯誤。 因為錯誤會在您應用程式中不同的部分發生,所以您需要根據您所期望的錯誤來決定在程式碼中使用哪一個。

可以使用於錯誤處理常式的語言元件包括:

  • Err 物件

  • ADO Error 物件與 Errors 集合

  • DAO Error 物件與 Errors 集合

  • AccessError 方法

  • Error 事件

Err 物件

Err 物件由 Visual Basic 提供。 當 Visual Basic 錯誤發生時,有關該錯誤的資訊會儲存於 Err 物件。 Err 物件一次只保留一個錯誤的相關資訊。 而當有新的錯誤發生時,Err 物件會更新以包含該錯誤的相關資訊。

若要取得特定錯誤的相關資訊,您可以使用 Err 物件的屬性和方法:

  • Number 屬性是 Err 物件的預設屬性,會傳回錯誤發生的識別號碼。
  • Err 物件的 Description 屬性會傳回與 Visual Basic 錯誤相關聯的描述性字串。
  • Clear 方法會從 Err 物件中清除目前的錯誤資訊。
  • Raise 方法會重新產生特定的錯誤,並將有關那個錯誤的資訊集中於 Err 物件的屬性中。

下列範例顯示如何在可能引起類型不符錯誤的程序中使用 Err 物件:

Function MayCauseAnError() 
    ' Declare constant to represent likely error. 
    Const conTypeMismatch As Integer = 13 
 
    On Error GoTo Error_MayCauseAnError 
        .            ' Include code here that may generate error. 
        . 
        . 
 
Exit_MayCauseAnError: 
    Exit Function 
 
Error_MayCauseAnError: 
    ' Check Err object properties. 
    If Err = conTypeMismatch Then 
        .            ' Include code to handle error. 
        . 
        . 
    Else 
        ' Regenerate original error. 
        Dim intErrNum As Integer 
        intErrNum = Err 
        Err.Clear 
        Err.Raise intErrNum 
    End If 
    ' Resume execution with exit routine to exit function. 
    Resume Exit_MayCauseAnError 
End Function

請注意在前面的範例中使用了 Raise 方法,以便重新產生原始的錯誤。 如果發生了類型不符以外的錯誤,執行會沿著呼叫序列往回傳到另一個已啟動的錯誤處理常式 (如果有的話)。

Err 物件提供您關於 Visual Basic 錯誤您需要的所有資訊。 不過,它不會給您關於 Access 資料庫引擎錯誤的完整資訊。 Access and Data Access Objects (DAO)) 提供額外的語言元件,協助您處理這些錯誤。

Error 物件與 Errors 集合

Error 物件與 Errors 集合由 ADO 與 DAO 提供。 Error 物件代表一個 ADO 或 DAO 錯誤。 單一的 ADO 或 DAO 運算可能會引起幾個錯誤,特別是當您執行 DAO ODBC 運算時。 在某個特別的資料存取運算期間發生的每一個錯誤,都有一個相關的 Error 物件。 而所有與特別的 ADO 或 DAO 運算相關的 Error 物件,是儲存於 Errors 集合中,最低層次的錯誤,是集合中的第一個物件,而最高層次的錯誤,是集合中的最後一個物件。

當一個 ADO 或 DAO 錯誤發生時,Visual Basic Err 物件中會包含 Errors 集合中第一個物件的錯誤代碼。 若要決定是否發生了其他的 ADO 或 DAO 錯誤,請檢查 Errors 集合。 Errors 集合中第一個 Error 物件的 ADO Number 或 DAO Number 屬性和 ADO Description 或 DAO Description 屬性應該符合 Visual Basic Err 物件的 NumberDescription 屬性的值。

AccessError 方法

使用 Err 物件的 Raise 方法來產生尚未實際發生的 Visual Basic 錯誤,並判斷與該錯誤相關聯的描述性字串。 不過,您無法使用 Raise 方法來產生 Access 錯誤、ADO 錯誤訊息或 DAO 錯誤。 若要判斷與尚未實際發生的 Access 錯誤、 ADO 錯誤訊息或 DAO 錯誤相關聯的描述性字串,請使用 AccessError 方法。

Error 事件

使用 Error 事件來捕捉 Access 表單或報表上發生的錯誤。 例如,如果使用者嘗試在資料類型為 [日期/時間] 的欄位中輸入文字,則會發生 Error 事件。 如果您將 Error 事件程序加入一個 [員工] 表單,並嘗試在 HireDate 欄位中輸入文字值,則 Error 事件程序會執行。

Error 事件程序使用一個整數引數 DataErr。 當 Error 事件程序執行時,DataErr 引數會包含已發生之 Access 錯誤的個數。 在事件程序中檢查 DataErr 引數的值是決定已發生之錯誤的個數的唯一方法。 Error 事件發生後, Err 物件中並未填入有關該錯誤的資訊。 使用 DataErr 自變數的值搭配 AccessError 方法來判斷錯誤的數目及其描述性字串。

注意事項

[!注意事項] Error 陳述式和 Error 函數僅是為了後續版本相容性所提供的。 編寫新程式碼時,請使用 ErrError 物件、AccessError 函數與 Error 事件來取得錯誤的相關資訊。

關於貢獻者

UtterAccess 社群的社群成員圖示所提供的連結

UtterAccess 是最早的 Microsoft Access Wiki 和說明論壇。

另請參閱

支援和意見反應

有關於 Office VBA 或這份文件的問題或意見反應嗎? 如需取得支援服務並提供意見反應的相關指導,請參閱 Office VBA 支援與意見反應