簡談VBA的錯誤處理

Word Excel 乃至其他支持 VBA Office 組件中,在代碼中處理錯誤的方式通常都是使用“ On Error Goto 錯誤標籤”語句,然後在代碼的後面添加錯誤標籤及其中包含的錯誤處理代碼。下面總結了創建錯誤處理程序的步驟:

1 )在過程中可能導致錯誤的代碼行的前面添加錯誤處理語句 On Error Goto ErrHandler ,其中的“ ErrHandler ”爲自定義的錯誤標籤名稱。

2 )在有可能導致錯誤的代碼行後面添加取消錯誤處理的語句 On Error Goto 0 ,這樣當遇到錯誤時,就不會跳轉到指定的錯誤標籤處,而是直接顯示錯誤提示窗口,其中包括【調試】、【結束】等按鈕。

3 )在宏的末尾(正常程序的末尾)添加代碼行 Exit Sub ,這樣可以避免程序未發生錯誤時執行錯誤處理程序。

4 )在代碼行 Exit Sub 的下一行添加一個錯誤標籤,該標籤由名稱和冒號組成,例如“ MyErr: ”。

5 )在錯誤標籤的下一行編寫錯誤處理代碼。如果要返回導致錯誤的代碼行後面的代碼行,可以使用 Resume Next 語句。

注意:可以在過程的末尾添加多個錯誤處理程序,但必須確保每個錯誤處理程序都以 Resume Next Exit Sub 語句結束,這樣可以避免從當前錯誤程序之後繼續執行其後的錯誤處理程序。

舉一個簡單的例子可能會更直觀地反映出上面所說的內容。在下面的代碼中,當檢測到工作簿中沒有指定的工作表時,將出現錯誤,並執行錯誤代碼,顯示一個包含錯誤號與錯誤描述的對話框。

Sub 檢測工作表是否存在 ()

    Dim wksname As String, msg As String

    On Error GoTo MyErr

    wksName = Worksheets("sx").Name

MyErr:

    msg = " 錯誤 " & Err.Number & " " & Err.Description

    MsgBox msg

End Sub

注意:無論在導致問題的代碼行前面使用 On Error Resume Next 語句還是“ On Error Goto 標籤”語句,要想讓程序重新獲取其他錯誤信息,則都必須在導致問題的代碼行後面使用 On Error Goto 0 語句恢復正常的錯誤捕獲狀態。否則當前的錯誤處理程序將對後面的所有錯誤都起作用。例如,下面的代碼由於沒有使用 On Error Goto 0 語句,因此,在後面遇到錯誤時(兩次 x/y ),都會轉到標籤 MyErr 處執行錯誤處理程序。

Sub ErrTest()

    Dim x As Integer, y As Integer, z As Single

    x = 1

    y = 0

    On Error GoTo MyErr

    MsgBox x / y

    MsgBox x / y

    MsgBox " 繼續執行錯誤代碼行的下一行代碼 "

    Exit Sub

MyErr:

    MsgBox " 1 次:除數不能爲 0"

    Resume Next

End Sub

而下面的代碼由於及時使用了 On Error Goto 0 語句,因此,在第 2 次錯誤發生時(即第 2 x/y ),系統將顯示內置錯誤消息,而不是運行 MyErr 標籤處的代碼。

Sub ErrTest()

    Dim x As Integer, y As Integer, z As Single

    x = 1

    y = 0

    On Error GoTo MyErr

    MsgBox x / y

    On Error GoTo 0

    MsgBox x / y

    MsgBox " 繼續執行錯誤代碼行的下一行代碼 "

    Exit Sub

MyErr:

    MsgBox " 1 次:除數不能爲 0"

    Resume Next

End Sub

下面的代碼雖然未使用 On Error Goto 0 語句,但是在第 2 個錯誤發生前,添加了第 2 個錯誤標籤,因此,兩個錯誤處理程序分別處理各自的錯誤。

Sub ErrTest()

    Dim x As Integer, y As Integer, z As Single

    x = 1

    y = 0

    On Error GoTo MyErr1

    MsgBox x / y

    On Error GoTo MyErr2

    MsgBox x / y

    MsgBox " 繼續執行錯誤代碼行的下一行代碼 "

    Exit Sub

MyErr1:

    MsgBox " 1 次:除數不能爲 0"

    Resume Next

MyErr2:

    MsgBox " 2 次:除數不能爲 0"

    Resume Next

End Sub

以上 3 段代碼在執行完錯誤處理程序後,都會返回發生錯誤的代碼之後繼續執行。對於本例來說,在執行完錯誤處理程序後,都會繼續執行“ MsgBox " 繼續執行錯誤代碼行的下一行代碼 " ”代碼行。

雖然我們不希望在程序運行時出現錯誤,但是有些時候我們可以利用錯誤來提高代碼的效率。例如,當用戶由於某些原因將工作簿中的某個工作表刪除,如果 VBA 程序中中包括操作該工作表的代碼,那麼當用戶運行該程序時,將導致錯誤發生。此時,可以利用錯誤來檢測要操作的工作表是否存在於工作簿中。代碼如下:

Sub 檢測工作表是否存在 ()

    Dim WksName As String

    On Error Resume Next

    WksName = Worksheets("sx").Name

    If Err.Number <> 0 Then

        MsgBox prompt:=" 此工作簿中未找到工作表 sx", Title:=" 錯誤 "

    End If

    On Error GoTo 0

End Sub

注意:當使用 On Error Resume Next 語句後,應該及時在可能導致錯誤的代碼行之後使用 On Error Goto 0 語句恢復錯誤的捕獲,即恢復到錯誤檢查的正常狀態,以便可以獲悉其他任何可能發生的錯誤。另外,如果使用 On Error Resume Next 語句忽略了無法忽略的錯誤,將會立刻結束當前運行的過程。而更糟糕的是,如果宏 1 調用宏 2 ,但宏 2 發生了無法忽略的錯誤,那麼將立刻結束宏 2 的運行,而繼續執行宏 1 中的下一行代碼,這種情況可能會使整個代碼包含了不可預知的錯誤,因此務必要小心。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章