錯誤處理

良好的錯誤處理可防止終端使用者看到 VBA 執行時錯誤,並幫助開發人員輕鬆診斷和糾正錯誤。

VBA 中有三種主要的錯誤處理方法,除非程式碼中特別要求,否則應避免分散式程式中的兩種方法。

On Error GoTo 0 'Avoid using

要麼

On Error Resume Next 'Avoid using

喜歡使用:

On Error GoTo <line> 'Prefer using

On Error GoTo 0

如果你的程式碼中未設定錯誤處理,則 On Error GoTo 0 是預設的錯誤處理程式。在此模式下,任何執行時錯誤都將啟動典型的 VBA 錯誤訊息,允許你結束程式碼或進入 debug 模式,以識別源。在編寫程式碼時,這種方法是最簡單和最有用的,但是對於分發給終端使用者的程式碼應始終避免使用,因為這種方法非常難看並且終端使用者難以理解。

On Error Resume Next

On Error Resume Next 將導致 VBA 忽略錯誤呼叫之後所有行在執行時丟擲的任何錯誤,直到更改錯誤處理程式。在非常具體的情況下,這條線可能很有用,但在這些情況之外應該避免使用。例如,從 Excel 巨集啟動單獨的程式時,如果你不確定該程式是否已開啟,則 On Error Resume Next 呼叫可能很有用:

'In this example, we open an instance of Powerpoint using the On Error Resume Next call
Dim PPApp As PowerPoint.Application
Dim PPPres As PowerPoint.Presentation
Dim PPSlide As PowerPoint.Slide

'Open PPT if not running, otherwise select active instance
On Error Resume Next
Set PPApp = GetObject(, "PowerPoint.Application")
On Error GoTo ErrHandler
If PPApp Is Nothing Then
    'Open PowerPoint
    Set PPApp = CreateObject("PowerPoint.Application")
    PPApp.Visible = True
End If

如果我們沒有使用 On Error Resume Next 呼叫並且 Powerpoint 應用程式尚未開啟,則 GetObject 方法會丟擲錯誤。因此,On Error Resume Next 是避免建立應用程式的兩個例項所必需的。

注意: 一旦不再需要 On Error Resume Next 呼叫,立即重置錯誤處理程式也是最佳做法

On Error GoTo <line>

建議將此錯誤處理方法用於分發給其他使用者的所有程式碼。這允許程式設計師通過將程式碼傳送到指定行來準確控制 VBA 如何處理錯誤。標記可以填充任何字串(包括數字字串),並將程式碼傳送到後面跟冒號的相應字串。通過對 On Error GoTo <line> 進行不同的呼叫,可以使用多個錯誤處理塊。下面的子例程演示了 On Error GoTo <line> 呼叫的語法。

注意: 必須將 Exit Sub 行放在第一個錯誤處理程式之上,並且在每個後續錯誤處理程式之前,以防止程式碼在沒有呼叫錯誤的情況下自然地進入塊。因此,在程式碼塊的末尾放置錯誤處理程式是函式和可讀性的最佳實踐。

Sub YourMethodName()
    On Error GoTo errorHandler
    ' Insert code here
    On Error GoTo secondErrorHandler

    Exit Sub 'The exit sub line is essential, as the code will otherwise
             'continue running into the error handling block, likely causing an error

errorHandler:
    MsgBox "Error " & Err.Number & ": " & Err.Description & " in " & _
        VBE.ActiveCodePane.CodeModule, vbOKOnly, "Error"
    Exit Sub

secondErrorHandler:
    If Err.Number = 424 Then 'Object not found error (purely for illustration)
        Application.ScreenUpdating = True
        Application.EnableEvents = True
        Exit Sub
    Else
        MsgBox "Error " & Err.Number & ": " & Err.Desctription
        Application.ScreenUpdating = True
        Application.EnableEvents = True   
        Exit Sub
    End If      
    Exit Sub

End Sub

如果你使用錯誤處理程式碼退出方法,請確保清理:

  • 撤消部分完成的任何內容
  • 關閉檔案
  • 重置螢幕更新
  • 重置計算模式
  • 重置事件
  • 重置滑鼠指標
  • End Sub 之後持續存在的物件例項上呼叫 unload 方法
  • 重置狀態列