運(yùn)行時(shí)錯(cuò)誤處理的元素

此頁(yè)沒(méi)有內(nèi)容條目
內(nèi)容

expandtri全部顯示

錯(cuò)誤和錯(cuò)誤處理

編寫(xiě)應(yīng)用程序時(shí),必須考慮出現(xiàn)錯(cuò)誤時(shí)應(yīng)該怎么辦。有兩個(gè)原因會(huì)導(dǎo)致應(yīng)用程序中出錯(cuò)。第一,在運(yùn)行應(yīng)用程序時(shí)某些條件可能會(huì)使原本正確的代碼產(chǎn)生錯(cuò)誤。例如,如果代碼嘗試打開(kāi)一個(gè)已被用戶刪除的,就會(huì)出錯(cuò)。第二,代碼可能包含不正確的邏輯,導(dǎo)致不能運(yùn)行所需的操作。例如,如果在代碼中試圖將數(shù)值被 0 除,就會(huì)出現(xiàn)錯(cuò)誤。

如果沒(méi)有做任何錯(cuò)誤處理,則在代碼出錯(cuò)時(shí) Visual Basic 將停止運(yùn)行并顯示一條出錯(cuò)消息。當(dāng)發(fā)生這種情況時(shí),用戶很可能對(duì)此感到迷惑和沮喪。通過(guò)把完整的錯(cuò)誤處理例程包含在代碼中來(lái)處理可能產(chǎn)生的所有錯(cuò)誤,可以預(yù)防許多問(wèn)題。

當(dāng)將錯(cuò)誤處理代碼添加到過(guò)程中時(shí),應(yīng)當(dāng)考慮在出現(xiàn)錯(cuò)誤時(shí)過(guò)程將如何控制執(zhí)行順序。在將執(zhí)行交給錯(cuò)誤處理程序的步驟中,第一步是通過(guò)將某些形式的 On Error 語(yǔ)句包含在過(guò)程中而啟用錯(cuò)誤處理程序。On Error 語(yǔ)句在錯(cuò)誤事件中對(duì)執(zhí)行進(jìn)行定向。如果沒(méi)有 On Error 語(yǔ)句,在出現(xiàn)錯(cuò)誤時(shí) Visual Basic 只是簡(jiǎn)單地中止程序執(zhí)行并顯示一條出錯(cuò)消息。

如果已啟用了錯(cuò)誤處理程序的過(guò)程發(fā)生了錯(cuò)誤,Visual Basic 將并不顯示普通的出錯(cuò)消息,而是將它路由給錯(cuò)誤處理程序(如果存在)。當(dāng)執(zhí)行傳遞到一個(gè)已啟用的錯(cuò)誤處理程序時(shí),該錯(cuò)誤處理程序就被激活。在活動(dòng)的錯(cuò)誤處理程序中,可以確定出現(xiàn)的錯(cuò)誤類型,并按所選的方式處理它。Microsoft Access 提供了三類對(duì)象,它們包含關(guān)于已發(fā)生錯(cuò)誤的信息。這三類對(duì)象分別是:ADO Error 對(duì)象、Visual Basic Err 對(duì)象和 DAO Error 對(duì)象。

出現(xiàn)錯(cuò)誤時(shí)路由執(zhí)行

錯(cuò)誤處理程序指定發(fā)生錯(cuò)誤時(shí)過(guò)程如何響應(yīng)。例如,在出現(xiàn)特定的錯(cuò)誤時(shí)您可能需要終止過(guò)程的運(yùn)行,或者需要改正導(dǎo)致錯(cuò)誤的條件并恢復(fù)過(guò)程執(zhí)行。On ErrorResume 語(yǔ)句決定了如何在錯(cuò)誤事件中繼續(xù)執(zhí)行。

On Error 語(yǔ)句

On Error 語(yǔ)句啟用或禁用錯(cuò)誤處理例程。如果啟用了錯(cuò)誤處理例程,則當(dāng)出現(xiàn)錯(cuò)誤時(shí)執(zhí)行會(huì)傳遞給錯(cuò)誤處理例程。

On Error 語(yǔ)句有三種形式:On Error GoTo label、On Error GoTo 0On Error Resume NextOn Error GoTo label 語(yǔ)句啟用錯(cuò)誤處理例程,該例程從這個(gè)語(yǔ)句出現(xiàn)的代碼行開(kāi)始執(zhí)行。應(yīng)當(dāng)在可能出現(xiàn)錯(cuò)誤的第一行代碼前啟用錯(cuò)誤處理例程。在錯(cuò)誤處理程序被激活并出現(xiàn)錯(cuò)誤時(shí),執(zhí)行就會(huì)傳到由 label 參數(shù)指定的代碼行上。

由 label 參數(shù)指定的行應(yīng)是錯(cuò)誤處理例程的開(kāi)頭。例如,下面的過(guò)程指定:如果發(fā)生錯(cuò)誤,執(zhí)行會(huì)傳給標(biāo)簽為 Error_MayCauseAnError 的行:

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 語(yǔ)句在過(guò)程中禁用錯(cuò)誤處理。即使過(guò)程中包含有標(biāo)號(hào)為 0 的代碼行,該語(yǔ)句也不把 0 行指定為錯(cuò)誤處理代碼的起始。如果代碼中沒(méi)有 On Error GoTo 0 語(yǔ)句,則在過(guò)程運(yùn)行完成時(shí)將自動(dòng)禁用錯(cuò)誤處理程序。On Error GoTo 0 語(yǔ)句會(huì)重置 Err 對(duì)象的屬性,這與使用 Err 對(duì)象的 Clear 方法效果一樣。

On Error Resume Next 語(yǔ)句會(huì)忽略導(dǎo)致錯(cuò)誤的代碼行并將執(zhí)行路由到錯(cuò)誤代碼行的下一行。此時(shí)過(guò)程執(zhí)行并沒(méi)有中止。如果要檢查緊挨可能導(dǎo)致錯(cuò)誤的代碼行之后的 Err 對(duì)象的屬性,并且要在過(guò)程中(而不是錯(cuò)誤處理程序中)處理錯(cuò)誤,則可使用 On Error Resume Next 語(yǔ)句。

Resume 語(yǔ)句

Resume 語(yǔ)句將執(zhí)行從錯(cuò)誤處理例程中重定向回到過(guò)程的主體。如果要從過(guò)程某一特定點(diǎn)上繼續(xù)執(zhí)行程序,則可以在錯(cuò)誤處理例程中包含 Resume 語(yǔ)句。不過(guò) Resume 語(yǔ)句并不是必需的;也可以在運(yùn)行完錯(cuò)誤處理例程之后就結(jié)束過(guò)程。

Resume 語(yǔ)句有三種形式。其中 ResumeResume 0 語(yǔ)句將執(zhí)行返回到發(fā)生錯(cuò)誤的代碼行。而 Resume Next 語(yǔ)句將執(zhí)行返回到錯(cuò)誤代碼行的下一行。Resume label 語(yǔ)句則將執(zhí)行返回到由 label 參數(shù)指定的代碼行。label 參數(shù)必須指定一個(gè)行標(biāo)簽或一個(gè)行號(hào)。

通常如果要求用戶必須更正錯(cuò)誤,則可以使用 ResumeResume 0 語(yǔ)句。例如,如果提示用戶輸入一個(gè)表的名稱以便打開(kāi)該表,而用戶輸入了一個(gè)并不存在的表名,則可以再次提示用戶并在導(dǎo)致錯(cuò)誤的語(yǔ)句上繼續(xù)程序的執(zhí)行。

如果代碼在錯(cuò)誤處理程序中改正了錯(cuò)誤,并且無(wú)需再次運(yùn)行引起錯(cuò)誤的代碼行而想繼續(xù)執(zhí)行,可以使用 Resume Next 語(yǔ)句。如果想在過(guò)程中由 label 參數(shù)指定的其他代碼行上繼續(xù)執(zhí)行,則可以使用 Resume label 語(yǔ)句。例如,可以在退出例程上恢復(fù)程序的運(yùn)行,如以下章節(jié)所述。

退出過(guò)程

在過(guò)程中包含一個(gè)錯(cuò)誤處理例程的同時(shí),還應(yīng)該包括一個(gè)退出例程,以便只有在發(fā)生錯(cuò)誤時(shí)才運(yùn)行錯(cuò)誤處理例程。可以像指定錯(cuò)誤處理例程一樣用行標(biāo)簽指定退出例程。

例如,可以將退出例程添加到前面章節(jié)的示例中。如果沒(méi)有出現(xiàn)錯(cuò)誤,退出例程在過(guò)程主體之后運(yùn)行。而如果出現(xiàn)錯(cuò)誤,則在運(yùn)行完錯(cuò)誤處理例程之后執(zhí)行將傳到退出例程。退出例程包含一個(gè) Exit 語(yǔ)句。

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

處理嵌套過(guò)程中的錯(cuò)誤

當(dāng)一個(gè)沒(méi)有已啟用的錯(cuò)誤處理程序的嵌套過(guò)程中出現(xiàn)錯(cuò)誤時(shí),Visual Basic 將通過(guò)向后搜索調(diào)用列表查找其他過(guò)程中已啟用的錯(cuò)誤處理程序,而不是簡(jiǎn)單地中止執(zhí)行程序。這就使得代碼有機(jī)會(huì)在其他過(guò)程中糾正錯(cuò)誤。例如,假設(shè)過(guò)程 A 調(diào)用過(guò)程 B,過(guò)程 B 調(diào)用過(guò)程 C。如果過(guò)程 C 出現(xiàn)錯(cuò)誤而其中沒(méi)有已啟用的錯(cuò)誤處理程序,則 Visual Basic 會(huì)先檢查過(guò)程 B 再檢查過(guò)程 A,以找出已啟用的錯(cuò)誤處理程序。如果找到了,執(zhí)行就會(huì)傳到該錯(cuò)誤處理程序。否則會(huì)中止程序執(zhí)行并顯示出錯(cuò)消息。

當(dāng)活動(dòng)的錯(cuò)誤處理程序中出現(xiàn)錯(cuò)誤時(shí),Visual Basic 也會(huì)通過(guò)向后搜索調(diào)用列表查找已啟用的錯(cuò)誤處理程序。通過(guò)用 Err 對(duì)象的 Raise 方法在活動(dòng)的錯(cuò)誤處理程序中產(chǎn)生錯(cuò)誤,可以強(qiáng)制 Visual Basic 向后搜索調(diào)用列表。這在處理錯(cuò)誤處理程序中出現(xiàn)預(yù)料外的錯(cuò)誤時(shí)很有用。如果出現(xiàn)預(yù)料之外的錯(cuò)誤,而在錯(cuò)誤處理程序中又重新生成了該錯(cuò)誤,則執(zhí)行將按照調(diào)用列表的逆序傳遞以查找其他可能被設(shè)置來(lái)處理該錯(cuò)誤的錯(cuò)誤處理程序。

例如,假設(shè)過(guò)程 C 有一個(gè)已啟用的錯(cuò)誤處理程序,但并未糾正已經(jīng)出現(xiàn)的錯(cuò)誤。當(dāng)該錯(cuò)誤處理程序檢查了所有預(yù)料之中的錯(cuò)誤之后,它可以重新產(chǎn)生原有的錯(cuò)誤。此時(shí)執(zhí)行將按照調(diào)用列表的逆序傳給過(guò)程 B 中的錯(cuò)誤處理程序(如果存在該程序的話),給該錯(cuò)誤處理程序糾正錯(cuò)誤的機(jī)會(huì)。如果過(guò)程 B 沒(méi)有錯(cuò)誤處理程序或者如果不能糾正錯(cuò)誤并重新生成了錯(cuò)誤,則執(zhí)行將傳給過(guò)程 A 中的錯(cuò)誤處理程序(假設(shè)該誤處理程序存在)。

為了換一個(gè)角度來(lái)闡明這個(gè)概念,假設(shè)有一個(gè)嵌套過(guò)程,其中包含的錯(cuò)誤處理程序用于處理預(yù)料中類型可能不匹配的錯(cuò)誤。過(guò)程 C 的某個(gè)代碼行上出現(xiàn)了一個(gè)預(yù)料之外的錯(cuò)誤:值被 0 除。如果包含了一個(gè)重新生成原有錯(cuò)誤的語(yǔ)句,則執(zhí)行將按照調(diào)用列表的逆序傳給其他已啟用的錯(cuò)誤處理程序(如果存在該程序的話)。如果已在調(diào)用列表中的另一個(gè)過(guò)程中糾正了“值被 0 除”的錯(cuò)誤,那么該錯(cuò)誤就可被糾正。但如果代碼不重新生成該錯(cuò)誤,則過(guò)程將繼續(xù)運(yùn)行但不糾正“值被 0 除”的錯(cuò)誤。按照這種次序有可能會(huì)在嵌套過(guò)程集內(nèi)產(chǎn)生其他錯(cuò)誤。

總之,在以下情況下 Visual Basic 會(huì)按照調(diào)用列表的逆序搜索已啟用的錯(cuò)誤處理程序:

?過(guò)程中出現(xiàn)錯(cuò)誤,而該過(guò)程又不包含已啟用的錯(cuò)誤處理程序。
?在活動(dòng)的錯(cuò)誤處理程序中出現(xiàn)錯(cuò)誤。如果使用 Err 對(duì)象的 Raise 方法來(lái)產(chǎn)生一個(gè)錯(cuò)誤,就可強(qiáng)制 Visual Basic 向后搜索調(diào)用列表以查找已啟用的錯(cuò)誤處理程序。

獲得有關(guān)錯(cuò)誤的信息

一旦執(zhí)行傳至錯(cuò)誤處理例程,代碼就必須確定發(fā)生了何種錯(cuò)誤并處理它。Visual Basic 和 Microsoft Access 提供了幾種可用來(lái)獲取特定錯(cuò)誤信息的語(yǔ)言元素。每種語(yǔ)言元素都適用于不同類型的錯(cuò)誤。因?yàn)殄e(cuò)誤將發(fā)生在應(yīng)用程序的不同部分,所有需要根據(jù)所預(yù)期的錯(cuò)誤在代碼中選擇使用不同的語(yǔ)言元素。

可用于錯(cuò)誤處理的語(yǔ)言元素有:

?Err 對(duì)象。
?ADO Error 對(duì)象和 Errors 集合。
?DAO Error 對(duì)象和 Errors 集合。

?AccessError 方法。

?Error 事件。

Err 對(duì)象

Err 對(duì)象是由 Visual Basic 提供的。當(dāng)出現(xiàn) Visual Basic 錯(cuò)誤時(shí),有關(guān)該錯(cuò)誤的信息將存儲(chǔ)在 Err 對(duì)象中。Err 對(duì)象每次只維護(hù)一個(gè)錯(cuò)誤的信息。當(dāng)出現(xiàn)新的錯(cuò)誤時(shí),Err 對(duì)象將更新為新的錯(cuò)誤信息。

若要獲取某個(gè)特定錯(cuò)誤的信息,可以使用 Err 對(duì)象的屬性和方法。Number 屬性是 Err 對(duì)象的默認(rèn)屬性。它將返回所出現(xiàn)的錯(cuò)誤的標(biāo)識(shí)號(hào)。Err 對(duì)象的 Description 屬性則返回與 Visual Basic 錯(cuò)誤有關(guān)的描述性字符串。Clear 方法將清除 Err 對(duì)象的當(dāng)前錯(cuò)誤信息。Raise 方法可生成一個(gè)特定的錯(cuò)誤并用關(guān)于該錯(cuò)誤的信息填充 Err 對(duì)象的屬性。

下面的示例說(shuō)明了如何在可能導(dǎo)致類型不匹配錯(cuò)誤的過(guò)程中使用 Err 對(duì)象:

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

請(qǐng)注意在上面的示例中,Raise 方法用來(lái)重新產(chǎn)生原有的錯(cuò)誤。如果出現(xiàn)除了類型不匹配以外的錯(cuò)誤,執(zhí)行將按照調(diào)用列表的逆序傳遞給其他的錯(cuò)誤處理程序(如果存在該程序的話)。

Err 對(duì)象提供了所需有關(guān) Visual Basic 錯(cuò)誤的所有信息。然而,它并沒(méi)有給出有關(guān) Microsoft Access 錯(cuò)誤或 Microsoft Jet 數(shù)據(jù)庫(kù)引擎錯(cuò)誤的完整信息。Microsoft Access 和數(shù)據(jù)訪問(wèn)對(duì)象 (DAO) 提供了附加的語(yǔ)言元素來(lái)幫助處理這些錯(cuò)誤。

Error 對(duì)象和 Errors 集合

Error 對(duì)象和 Errors 集合是由 ADO 和 DAO 提供的。Error 對(duì)象代表一個(gè) ADO 或 DAO 錯(cuò)誤。單個(gè) ADO 或 DAO 操作可能引起幾個(gè)錯(cuò)誤,特別是執(zhí)行 DAO ODBC 操作時(shí)。在特定數(shù)據(jù)訪問(wèn)操作過(guò)程中發(fā)生的每個(gè)錯(cuò)誤都有一個(gè)相關(guān) Error 對(duì)象。與特定的 ADO 或 DAO 對(duì)象有關(guān)的所有 Error 對(duì)象都存儲(chǔ)在 Errors 集合中,其中最低級(jí)別的錯(cuò)誤為集合中的第一個(gè)對(duì)象,最高級(jí)別的錯(cuò)誤為集合中的最后一個(gè)對(duì)象。

出現(xiàn) ADO 或 DAO 錯(cuò)誤時(shí),Visual Basic 的 Err 對(duì)象包含 Errors 集合中第一個(gè)對(duì)象的錯(cuò)誤編號(hào)。若要確定是否出現(xiàn)了其他的 ADO 或 DAO 錯(cuò)誤,可檢查 Errors 集合。Errors 集合中第一個(gè) Error 對(duì)象的 ADO Number 或 DAO Number 屬性和 ADO Description 或 DAO Description 屬性應(yīng)該與 Visual Basic Err 對(duì)象的 NumberDescription 屬性值相匹配。

AccessError 方法

使用 Err 對(duì)象的 Raise 方法可產(chǎn)生一個(gè)實(shí)際上并未出現(xiàn)的 Visual Basic 錯(cuò)誤并確定與該錯(cuò)誤相關(guān)的描述性字符串。然而,不能使用 Raise 方法產(chǎn)生 Microsoft Access 錯(cuò)誤、ADO 錯(cuò)誤或 DAO 錯(cuò)誤。若要確定與實(shí)際上并未發(fā)生的 Microsoft Access 錯(cuò)誤、ADO 錯(cuò)誤或 DAO 錯(cuò)誤相關(guān)的描述性字符串,可使用 AccessError 方法。

Error 事件

使用 Error 事件可捕獲發(fā)生在 Microsoft Access 窗體報(bào)表上的錯(cuò)誤。例如,當(dāng)用戶試圖在數(shù)據(jù)類型為“日期/時(shí)間”的字段中輸入文本就會(huì)發(fā)生 Error 事件。如果把 Error 事件過(guò)程添加到“雇員”窗體上,然后試圖在“雇傭日期”字段中輸入一個(gè)文本值,Error 事件過(guò)程就會(huì)運(yùn)行。

Error 事件過(guò)程有一個(gè)整型參數(shù) DataErr。在運(yùn)行 Error 事件過(guò)程時(shí),DataErr 參數(shù)將包含出現(xiàn)的 Microsoft Access 錯(cuò)誤的編號(hào)。確定發(fā)生錯(cuò)誤的編號(hào)的唯一方法就是在事件過(guò)程中檢查 DataErr 參數(shù)。在發(fā)生 Error 事件之后,Err 對(duì)象并不為錯(cuò)誤信息所填充??蓪?DataErr 參數(shù)值與 AccessError 方法一起使用來(lái)確定錯(cuò)誤編號(hào)及其描述性字符串。

注釋  提供 Error 語(yǔ)句和 Error 函數(shù)的目的只是為了向后兼容。在編寫(xiě)新代碼時(shí),請(qǐng)使用 ErrError 對(duì)象、AccessError 函數(shù)和 Error 事件來(lái)獲取錯(cuò)誤信息。