現(xiàn)在看來關于VBA中的錯誤處理語句,應該主要有三種形式:①On Error Resume Next;②On Error Goto 0;③On Error Goto ErrorHnadler.可以說這三種就涵蓋了幾乎所有的錯誤處理語句.下面是關于這三種錯誤處理語句的一點認識:
啟動一個錯誤處理程序并指定該子程序在一個過程中的位置;也可用來禁止一個錯誤處理程序。
語法
On Error GoTo line
On Error Resume Next
On Error GoTo 0
On Error 語句的語法可以具有以下任何一種形式:
語句
描述
On Error GoTo line
啟動錯誤處理程序,且該例程從必要的 line 參數(shù)中指定的 line 開始。line 參數(shù)可以是任何行標簽或行號。如果發(fā)生一個運行時錯誤,則控件會跳到 line,激活錯誤處理程序。指定的 line 必須在一個過程中,這個過程與 On Error 語句相同; 否則會發(fā)生編譯時間錯誤。
On Error Resume Next
說明當一個運行時錯誤發(fā)生時,控件轉到緊接著發(fā)生錯誤的語句之后的語句,并在此繼續(xù)運行。訪問對象時要使用這種形式而不使用 On Error GoTo。
On Error GoTo 0
禁止當前過程中任何已啟動的錯誤處理程序。
說明
如果不使用 On Error 語句,則任何運行時錯誤都是致命的;也就是說,結果會導致顯示錯誤信息并中止運行。
在任何過程中,一旦錯誤處理程序處理了錯誤,在當前過程中就會從 Resume 語句指定的位置恢復運行。
注意
一個錯誤處理程序不是 Sub 過程或 Function 過程。它是一段用行標簽或行號標記的代碼。
錯誤處理程序依靠 Err 對象的 Number 屬性中的值來確定錯誤發(fā)生的原因。在其它任何錯誤發(fā)生之前,或在調用一個可能會導致錯誤發(fā)生的過程之前,錯誤處理程序應該先測試或存儲 Err 對象中相關的屬性值。Err 對象中的屬性值只反映最近發(fā)生的錯誤。Err.Description 中包含有與 Err.Number 相關聯(lián)的錯誤信息。
On Error Resume Next
會使程序從緊隨產生錯誤的語句之后的語句繼續(xù)執(zhí)行,或是從緊隨最近一次調用含有 On Error Resume Next 語句的過程的語句繼續(xù)運行。這個語句可以置運行時錯誤于不顧,使程序得以繼續(xù)執(zhí)行??梢詫㈠e誤處理程序放置在錯誤發(fā)生的地方,而不必將控件傳輸?shù)竭^程中的其它位置。
On Error GoTo 0
停止在當前過程中處理錯誤。即使過程中包含編號為 0 的行,它也不把行 0 指定為處理錯誤的代碼的起點。如果沒有 On Error GoTo 0 語句,在退出過程時,錯誤處理程序會自動關閉。
在錯誤未發(fā)生的時候,為了防止錯誤處理程序代碼運行,請像在下段程序中那樣,在緊靠著錯誤處理程序的前面寫入 Exit Sub、Exit Function 或 Exit Property 語句。
Sub InitializeMatrix(Var1, Var2, Var3, Var4) On Error GoTo ErrorHandler
. . .
Exit Sub
ErrorHandler:
. . .
Resume Next
End Sub
錯誤處理程序代碼在 Exit Sub 語句之后,而在 End Sub 語句之前,從而與過程中的流程分開。
On Error 語句示例
本示例先使用 On Error GoTo 語句在一個過程中指定錯誤處理的代碼所在。本示例中,試圖刪除一已經打開的文件從而生成的錯誤碼為 55。這個錯誤將由示例中的錯誤處理程序碼來處理,處理完後,控制會回到發(fā)生錯誤的語句處。On Error GoTo 0 語句關閉錯誤陷阱。然后 On Error Resume Next 語句用來改變錯誤陷阱,以便發(fā)覺下一個語句產生的錯誤的范圍。請注意示例中使用 Err.Clear 在錯誤處理完後,清除 Err 對象的屬性。
Sub OnErrorStatementDemo()
On Error GoTo ErrorHandler '
打開錯誤處理程序。
Open "TESTFILE" For Output As #1 '
打開輸出文件。
Kill "TESTFILE" '
試圖刪除已打開的文件。
On Error Goto 0
'
關閉錯誤陷阱。
On Error Resume Next '
改變錯誤陷阱。
ObjectRef = GetObject("MyWord.Basic") '
試圖啟動不存在的對象
'
檢查可能發(fā)生的
Automation
錯誤。
If Err.Number = 440 Or Err.Number = 432 Then
'
告訴用戶出了什么事。然后清除
Err
對象。
Msg = "There was an error attempting to open the Automation object!"
MsgBox Msg, , "Deferred Error Test"
Err.Clear '
清除
Err
對象字段。
End If
Exit Sub '
退出程序,以避免進入錯誤處理程序。
ErrorHandler: '
錯誤處理程序。
Select Case Err.Number '
檢查錯誤代號。
Case 55 '
發(fā)生“文件已打開”的錯誤。
Close #1 '
關閉已打開的文件。
Case Else
'
處理其他錯誤狀態(tài)
. . .
End Select
Resume '
將控制返回到產生錯誤的語句。
End Sub
關于Resume語句的解釋
在錯誤處理程序結束后,恢復原有的運行。
語法
Resume [0]
Resume Next
Resume line
Resume 語句的語法可以具有以下任何一種形式:
語句
描述
Resume
如果錯誤和錯誤處理程序出現(xiàn)在同一個過程中,則從產生錯誤的語句恢復運行。如果錯誤出現(xiàn)在被調用的過程中,則從最近一次調用包含錯誤處理程序的過程的語句處恢復運行。
Resume Next
如果錯誤和錯誤處理程序出現(xiàn)在同一個程序中,則從緊隨產生錯誤的語句的下個語句恢復運行。如果錯誤發(fā)生在被調用的過程中,則對最后一次調用包含錯誤處理程序的過程的語句(或 On Error Resume Next 語句),從緊隨該語句之后的語句處恢復運行。
Resume line
在必要的 line 參數(shù)指定的 line 處恢復運行。line 參數(shù)是行標簽或行號,必須和錯誤處理程序在同一個過程中。
說明
在錯誤處理程序之外的任何地方使用 Resume 語句都會導致錯誤發(fā)生。
下面是一個關于錯誤處理的例子:
樣表如下所示:
現(xiàn)在想計算B列與C列的比值的大小,明顯的"計劃/實際"值肯定會出現(xiàn)除數(shù)為0的現(xiàn)象,現(xiàn)在要做的是如何處理這個錯誤,使程序可以跳過錯誤行繼續(xù)運行,并且在將錯誤的原因標明.
程序如下:
Sub 如何處理錯誤()
On Error GoTo ErrorHandler
Dim i As Long
Dim TotalR As Long
TotalR = Range("A65536").End(xlUp).Row
For i = 2 To TotalR
Cells(i, 4).Value = Cells(i, 2).Value / Cells(i, 3).Value
Next i
Cells.Columns.AutoFit
Exit Sub
ErrorHandler:
Cells(i, 4).Value = 0
Resume Next'此處意思為返回到出錯語句的下一句繼續(xù)運行,若略掉Next,則從出錯語句繼續(xù)運行,那么就會造成死循環(huán).樣表如第3個圖所示
End Sub
處理后的樣表如下所示:
程序將出錯的單元格賦值為0,并且可以繼續(xù)運行,避免了程序的中斷與錯誤處理.
這是不加Next時的效果,程序運行后會一直運行出錯語句,導致程序死循環(huán).由此看出,上面的程序并沒有糾正錯誤的原始數(shù)據(jù),想想也是這個道理,很多時候,要做的工作以原始數(shù)據(jù)為基礎,得出一定的結論,有時錯誤的結論也是一種結論.
可捕獲的錯誤
可捕獲的錯誤通常發(fā)生在應用程序運行時,但也有一些會發(fā)生在開發(fā)期間或編譯時間??墒褂?On Error 語句與 Err 對象來探測并回應可捕獲的錯誤。1 – 1000 之間未使用的錯誤號都是保留給 Visual Basic 以后使用的。
3沒有返回的GoSub
5無效的過程調用
6溢出
7內存不足
9數(shù)組索引超出范圍
10此數(shù)組為固定的或暫時鎖定
11除以零
13類型不符合
14字符串空間不足
16表達式太復雜
17不能完成所要求的操作
18發(fā)生用戶中斷
20沒有恢復的錯誤
28堆??臻g不足
35沒有定義 子程序、函數(shù),或屬性
47DLL 應用程序的客戶端過多
48裝入 DLL 時發(fā)生錯誤
49DLL 調用規(guī)格錯誤
51內部錯誤
52錯誤的文件名或數(shù)目
53文件找不到
54錯誤的文件方式
55文件已打開
57 I/O 設備錯誤
58文件已經存在
59記錄的長度錯誤
61磁盤已滿
62輸入已超過文件結尾
63記錄的個數(shù)錯誤
67文件過多
68設備不可用
70沒有訪問權限
71磁盤尚未就緒
74不能用其他磁盤機重命名
75路徑/文件訪問錯誤
76找不到路徑
91尚未設置對象變量或 With 區(qū)塊變量
92For循環(huán)沒有被初始化
93無效的模式字符串
94Null 的使用無效
97不能在對象上調用 Friend 過程,該對象不是定義類的實例
298系統(tǒng) DLL 不能被加載
320在指定的文件中不能使用字符設備名
321無效的文件格式
322不能建立必要的臨時文件
325源文件中有無效的格式
327未找到命名的數(shù)據(jù)值
328非法參數(shù),不能寫入數(shù)組
335不能訪問系統(tǒng)注冊表
336ActiveX 部件不能正確注冊
337未找到 ActiveX 部件
338ActiveX 部件不能正確運行
360對象已經加載
361不能加載或卸載該對象
363未找到指定的 ActiveX 控件
364對象未卸載
365在該上下文中不能卸載
368指定文件過時。該程序要求較新版本
371指定的對象不能用作供顯示的所有者窗體
380屬性值無效
381無效的屬性數(shù)組索引
382屬性設置不能在運行時完成
383屬性設置不能用于只讀屬性
385需要屬性數(shù)組索引
387屬性設置不允許
393屬性的取得不能在運行時完成
394屬性的取得不能用于只寫屬性
400窗體已經顯示,不能顯示為模式窗體
402代碼必須先關閉頂端模式窗體
419允許使用否定的對象
422找不到屬性
423找不到屬性或方法
424需要對象
425無效的對象使用
429ActiveX 部件不能建立對象或返回對此對象的引用
430類不支持自動操作
432在自動操作期間找不到文件或類名
438對象不支持此屬性或方法
440自動操作錯誤
442連接至型態(tài)程序庫或對象程序庫的遠程處理已經丟失
443自動操作對象沒有默認值
445對象不支持此動作
446對象不支持指定參數(shù)
447對象不支持當前的位置設置
448找不到指定參數(shù)
449參數(shù)無選擇性或無效的屬性設置
450參數(shù)的個數(shù)錯誤或無效的屬性設置
451對象不是集合對象
452序數(shù)無效
453找不到指定的 DLL 函數(shù)
454找不到源代碼
455代碼源鎖定錯誤
457此鍵已經與集合對象中的某元素相關
458變量使用的型態(tài)是 Visual Basic 不支持的
459此部件不支持事件
460剪貼板格式無效
461未找到方法或數(shù)據(jù)成員
462遠程服務器機器不存在或不可用
463類未在本地機器上注冊
480不能創(chuàng)建 AutoRedraw 圖象
481圖片無效
482打印機錯誤
483打印驅動不支持指定的屬性
484從系統(tǒng)得到打印機信息時出錯。 確保正確設置了打印機
485無效的圖片類型
486不能用這種類型的打印機打印窗體圖象
520不能清空剪貼板
521不能打開剪貼板
735不能將文件保存至 TEMP 目錄
744找不到要搜尋的文本
746取代數(shù)據(jù)過長
31001內存溢出
31004無對象
31018未設置類
31027不能激活對象
31032不能創(chuàng)建內嵌對象
31036存儲到文件時出錯
31037從文件讀出時出錯