這裡介紹各種處理 VBA 程式的除錯技巧與錯誤處理用法,並提供幾個基礎範例。
在 Excel 中使用 VBA 撰寫程式,難免都會遇到程式出問題的狀況,例如程式跑不出來,或是執行結果不正確等,通常程式的問題可分為兩種,一種是程式開發者不小心所造成的臭蟲(bug),例如程式設計不良、程式碼打錯字等,這種狀況就要在開發程式時,使用 VBA 的各種除錯技巧把問題找出來。
另外一種狀況是程式本身沒問題,但使用者操作不當所造成的錯誤(error),例如輸入錯誤的資料、或是程式需要讀取的檔案不存在等,遇到這類的問題就要撰寫 VBA 的錯誤處理程式碼,針對各種錯誤進行妥善的處理。
除錯技巧(Debug)
開發 VBA 程式時,在撰寫好程式碼之後,都會先測試一下,看看執行的結果如何,若要測試 VBA 程式碼的執行狀況,最方便的做法就是善用 Visual Basic 的開發工具。
若要測試某個子程序(Sub)的執行狀況,可將游標移動到該子程序中,這時候視窗右上角的子程序名稱會即時顯示目前游標所在的子程序名稱,接著按下工具列上面的執行按鈕,這樣就可以立刻執行這個子程序,觀察執行結果。

如果程式出現問題時,就會出現類似這樣的錯誤訊息視窗,這時候如果要檢查錯誤的程式碼,可以選擇「偵錯」。

點選「偵錯」之後,就會開啟中斷模式的程式碼視窗,並顯示目前程式出問題的位置。

如果遇到語法錯誤、打錯字等比較單純的問題,我們可以透過檢查出問題的程式碼,找出問題的所在,但如果是邏輯性的問題,可能就要查看程式執行時,每個變數的實際內容。
在中斷模式中,我們可以將滑鼠移動到要觀察的變數上,這樣就可以立即查看變數的內容,幫助我們找出問題點。

如果程式碼中有比較複雜的運算,也可以用滑鼠把運算式子選取起來,這樣它就會顯示運算出來的數值。
程式中斷點
如果遇到程式執行都沒有出現錯誤,但是執行的結果又跟預期不同,也不曉得問題在哪裡的時候,就可以考慮使用設定程式中斷點的方式來除錯。
首先在程式比較可疑的地方,使用滑鼠新增中斷點,設定好之後,再執行程式。

設定中斷點之後,程式執行時就會在中斷點的位置暫停,讓開發者可以慢慢檢查每個變數的內容。

逐行執行
如果程式要檢查的地方非常多,就可以直接使用逐行執行程式的方式來除錯。

按下 F8 按鍵之後,程式就會從子程序的第一行開始逐行執行,每按一下就會執行一行,而在程式執行的期間,我們都可以隨時用滑鼠來查看每個變數的內容,找出有問題的地方。

中斷程式執行
如果在寫迴圈時,不小心寫成了無窮迴圈,執行之後就會停不下來,就像這樣:
Dim x As Long
x = 5
' 無窮迴圈
Do While x > 2
x = x + 1
Loop
遇到無法停止的程式,可以按下鍵盤上的 Esc 按鍵,或是 Ctrl + break 按鍵,讓程式立即停止執行。
監看式
在程式的除錯過程中,我們可能會需要觀察多個變數或運算式的內容變化,這時候就可以將有興趣的運算式選取起來,在滑鼠右鍵選單中點選「新增監看式」。

填入想要觀察的運算式。

設定好的監看式會顯示在監看式的視窗中,這樣就可以比較方便同時觀察好多的變數或是運算式。

錯誤處理(Error Handling)
一個完整的 VBA 應用程式,縱使程式碼本身沒有任何設計上的錯誤,也難免會需要處理程式出錯的狀況,典型常見的問題包含輸入錯誤的資料、要讀取的檔案不存在或是各種使用者操作不當所造成的錯誤。
若要對程式實際執行期間所發生的錯誤進行一些處理,就可以使用錯誤處理(error handling)的機制,自動對不同的錯誤做出對應的動作,並決定程式是否要繼續執行,或是直接終止。
預設的狀況下,只要程式出現任何錯誤,就會跳出錯誤訊息的視窗,並且終止程式的執行(就像之前的範例那樣),我們可以使用 On Error 自訂錯誤的處理方式,以下是一個簡單的範例。
Sub Hello()
On Error GoTo ErrorHandler ' 啟用錯誤處理機制
Dim x, y, z As Integer
x = 10
y = 0
z = x / y ' 出現除以 0 的錯誤
MsgBox "z = " & z
Exit Sub ' 結束子程序
ErrorHandler: ' 錯誤處理用的程式碼
MsgBox "錯誤 " & Err.Number & ":" & Err.Description
Resume Next ' 繼續往下執行
End Sub
這裡的程式碼可分為上下兩部分,上半部為正常的程式碼,下半部是專門用來處理錯誤的程式碼。
上半部程式碼的第一行,我們使用 On Error 來設定當錯誤發生時的處理方式,錯誤處理的方式有好幾種,最常用的就是使用 GoTo 設定錯誤處理程式碼的位置(也就是這裡的 ErrorHandler),這樣設定的話,當程式發生錯誤時就會直接跳到下方 ErrorHandler: 的位置來處理錯誤。

在這個程式中,我們故意讓程式產生除以零的錯誤,當錯誤發生時就直接跳到下方 ErrorHandler: 的位置,以 MsgBox 輸出錯誤的編號與錯誤的描述。

接著再呼叫 Resume Next 繼續回到上方正常的程式碼中,從出錯的下一行繼續執行,也就是輸出 z 的值,但是因為 z 的值在之前計算時出錯了,所以它的值是沒有意義的。

我們可以調整這部分的錯誤處理程式碼,自行決定是否要繼續執行,或是直接終止程式。若要在錯誤處理完之後,直接離開子程序,就把 Resume Next 那一行刪掉即可,這樣程式就會按照正常的方式離開子程序。
忽略錯誤
如果要讓程式忽略任何的錯誤,可以將 On Error 的處理方式指定為 Resume Next。
On Error Resume Next ' 忽略錯誤,繼續執行
Dim x, y, z As Integer
x = 10
y = 0
z = x / y ' 出現除以 0 的錯誤
MsgBox "z = " & z
這樣程式在執行時,不管出了什麼問題,都不會顯示錯誤訊息,而且會繼續執行直到程式結尾。

