Excel VBA 程式設計教學:除錯技巧與錯誤處理

錯誤處理(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: 的位置來處理錯誤。

VBA 錯誤處理

在這個程式中,我們故意讓程式產生除以零的錯誤,當錯誤發生時就直接跳到下方 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

這樣程式在執行時,不管出了什麼問題,都不會顯示錯誤訊息,而且會繼續執行直到程式結尾。

忽略錯誤

更多關於 VBA 的教學文章,請參考 VBA 程式設計

參考資料:Excel EasytutorialspointExcelFunctions.net

Windows, 程式設計

6 留言

  1. YAN

    您好,想請教您一個問題,以下兩種寫法出來的結果是不同的。
    Dim eachdate, justdate As String
    eachdate = “05”
    Cells(1, 1) = eachdate

    justdate = “5”
    Cells(2, 1) = justdate

    If Cells(2, 1) = Cells(1, 1) Then
    MsgBox “great”
    End If
    ———————————–
    Dim eachdate, justdate As String
    eachdate = “05”
    Cells(1, 1) = eachdate

    justdate = “5”
    Cells(2, 1) = justdate

    If eachdate = justdate Then
    MsgBox “great”
    End If
    ——————————–
    只是改了if的條件攔位名稱,結果就不同,想問原因是什麼,感謝您。

    • xLFungx

      你把eachdate和justdate存進cells之後,cell會自動把cell format改成Number,裹面的data就變成了兩個cell都是”5″。
      所以比較兩個cell的時候它們是相同的。
      後面是因為比較string,所以2個string不相同就不相同。

  2. excel vba 程式碼的執行已被中斷

    之前都可使用 直接案下F5 就自動跑了
    現在卻 案F5 卻自動 跳出 “程式碼的執行已被中斷”
    可是案下F8 一步一步的 又很順利阿
    一案F5 又來了 自動 跳出 “程式碼的執行已被中斷” 見鬼了???

  3. Ian

    您好,想請教個問題
    為何以下function 及用with 在幫資料加框線時會無法處理第一個column ?
    要怎麼修改才能符合需求,感謝

    Function getlastrow() As Long ‘找到最后一列-資料範圍
    Dim lngReturn As Long
    Dim wks2 As Worksheet
    Set wks2 = Worksheets(2)
    lngReturn = wks2.Range(“A2”).End(xlDown).Row
    getlastrow = lngReturn
    End Function

    LastRow = getlastrow

    With wks2.Columns(“A:H” & CStr(LastRow)) ‘調整儲存格範圍
    .HorizontalAlignment = xlCenter ‘文字置中對齊
    .VerticalAlignment = xlCenter
    .Font.Name = “calibri” ‘字型
    .Font.Size = 10 ‘字型大小
    .Borders().LineStyle = xlNone ‘儲存格框線的線條樣式
    .Borders().Weight = xlThin ‘儲存格框線粗細設定
    End With

  4. 鄭學隆

    請問現在還有人回答問題嗎?

  5. 徐墩煌

    您好:
    我的Excel是2016版本,執行VBAproject系統提示(不支援此語法)
    .Connection = _
    “URL;https://www.tpex.org.tw/web/stock/aftertrading/daily_trading_info/st43_print.php?l=zh-tw&d=” & Sheets(“設定”).Range(“B5”).Value & “&stkno=” & Sheets(“設定”).Range(“B1”).Value & “&s=0”
    請解惑,謝謝!

Comments are Closed