在 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 中的下一行代碼,這種情況可能會使整個代碼包含了不可預知的錯誤,因此務必要小心。