VBA的異常處理(On Error Goto 錯誤標簽....)


  在 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 語句結束,這樣可以避免從當前錯誤程序之后繼續執行其后的錯誤處理程序。

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

 1 Sub 檢測工作表是否存在 ()
 2 
 3     Dim wksname As String, msg As String
 4 
 5     On Error GoTo MyErr
 6 
 7     wksName = Worksheets("sx").Name
 8 
 9     MyErr:
10 
11     msg = " 錯誤 " & Err.Number & "" & Err.Description
12 
13     MsgBox msg
14 
15 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 標簽處的代碼。

 1 Sub ErrTest1()
 2 
 3     Dim x As Integer, y As Integer, z As Single
 4 
 5     x = 1
 6 
 7     y = 0
 8 
 9     On Error GoTo MyErr
10 
11     MsgBox x / y
12 
13     On Error GoTo 0
14 
15     MsgBox x / y
16 
17     MsgBox " 繼續執行錯誤代碼行的下一行代碼 "
18 
19     Exit Sub
20 
21 MyErr:
22 
23     MsgBox " 第 1 次:除數不能為 0"
24 
25     Resume Next
26 
27 End Sub

 

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

 1 Sub ErrTest2()
 2 
 3     Dim x As Integer, y As Integer, z As Single
 4 
 5     x = 1
 6 
 7     y = 0
 8 
 9     On Error GoTo MyErr1
10 
11     MsgBox x / y
12 
13     On Error GoTo MyErr2
14 
15     MsgBox x / y
16 
17     MsgBox " 繼續執行錯誤代碼行的下一行代碼 "
18 
19     Exit Sub
20 
21 MyErr1:
22 
23     MsgBox " 第 1 次:除數不能為 0"
24 
25     Resume Next
26 
27 MyErr2:
28 
29     MsgBox " 第 2 次:除數不能為 0"
30 
31     Resume Next
32 
33 End Sub

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

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

 1 Sub 檢測工作表是否存在()
 2 
 3     Dim WksName As String
 4 
 5     On Error Resume Next
 6 
 7     WksName = Worksheets("sx").Name
 8 
 9     If Err.Number <> 0 Then
10 
11         MsgBox prompt:=" 此工作簿中未找到工作表 sx", Title:=" 錯誤 "
12 
13     End If
14 
15     On Error GoTo 0
16 
17 End Sub

 

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

Resume 語句

  在錯誤處理程序結束后,恢復原有的運行。

語句 描述
Resume  如果錯誤和錯誤處理程序出現在同一個過程中,則從產生錯誤的語句恢復運行。如果錯誤出現在被調用的過程中,則從最近一次調用包含錯誤處理程序的過程的語句處恢復運行
Resume Next  如果錯誤和錯誤處理程序出現在同一個程序中,則從緊隨產生錯誤的語句的下個語句恢復運行。如果錯誤發生在被調用的過程中,則對最后一次調用包含錯誤處理程序的過程的語句(或 On Error Resume Next 語句),從緊隨該語句之后的語句處恢復運行。
Resume line  在必要的 line 參數指定的 line 處恢復運行。line 參數是行標簽行號,必須和錯誤處理程序在同一個過程中。

 

On Error 語句
  啟動一個錯誤處理程序並指定該子程序在一個過程中的位置;也可用來禁止一個錯誤處理程序。

語句 描述

On Error GoTo line            

 啟動錯誤處理程序,且該例程從必要的 line 參數中指定的line 開始。line 參數可以是任何行標簽或行號。如果發生一個運行時錯誤,則控件會跳到 line,激活錯誤處理程序。指定的 line 必須在一個過程中,這個過程與 On Error 語句相同; 否則會發生編譯時間錯誤。
On Error Resume Next  說明當一個運行時錯誤發生時,控件轉到緊接着發生錯誤的語句之后的語句,並在此繼續運行。訪問對象時要使用這種形式而不使用 On Error GoTo。
On Error GoTo 0

禁止當前過程中任何已啟動的錯誤處理程序。

 

 

 

  錯誤處理程序依靠 Err 對象的 Number 屬性中的值來確定錯誤發生的原因。在其它任何錯誤發生之前,或在調用一個可能會導致錯誤發生的過程之前,錯誤處理程序應該先測試或存儲 Err 對象中相關的屬性值。Err 對象中的屬性值只反映最近發生的錯誤。Err.Description 中包含有與 Err.Number 相關聯的錯誤信息。

  On Error GoTo 0 停止在當前過程中處理錯誤。即使過程中包含編號為 0 的行,它也不把行 0 指定為處理錯誤的代碼的起點。如果沒有 On Error GoTo 0 語句,在退出過程時,錯誤處理程序會自動關閉。

 

摘:https://blog.csdn.net/daihongliu/article/details/78285088


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM