分享

关于VBA中的错误处理

 lxWXY123 2014-09-13
 
关于VBA中的错误处理  


现在看来关于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 参数中指定的 line 开始。line 参数可以是任何行标签行号。如果发生一个运行时错误,则控件会跳到 line,激活错误处理程序。指定的 line 必须在一个过程中,这个过程与 On Error 语句相同; 否则会发生编译时间错误。

On Error Resume Next
说明当一个运行时错误发生时,控件转到紧接着发生错误的语句之后的语句,并在此继续运行。访问对象时要使用这种形式而不使用 On Error GoTo。

On Error GoTo 0
禁止当前过程中任何已启动的错误处理程序。

说明

如果不使用 On Error 语句,则任何运行时错误都是致命的;也就是说,结果会导致显示错误信息并中止运行。

在任何过程中,一旦错误处理程序处理了错误,在当前过程中就会从 Resume 语句指定的位置恢复运行。

注意

一个错误处理程序不是 Sub 过程或 Function 过程。它是一段用行标签或行号标记的代码。

错误处理程序依靠 Err 对象的 Number 属性中的值来确定错误发生的原因。在其它任何错误发生之前,或在调用一个可能会导致错误发生的过程之前,错误处理程序应该先测试或存储 Err 对象中相关的属性值。Err 对象中的属性值只反映最近发生的错误。Err.Description 中包含有与 Err.Number 相关联的错误信息。

On Error Resume Next

会使程序从紧随产生错误的语句之后的语句继续执行,或是从紧随最近一次调用含有 On Error Resume Next 语句的过程的语句继续运行。这个语句可以置运行时错误于不顾,使程序得以继续执行。可以将错误处理程序放置在错误发生的地方,而不必将控件传输到过程中的其它位置。

On Error GoTo 0

停止在当前过程中处理错误。即使过程中包含编号为 0 的行,它也不把行 0 指定为处理错误的代码的起点。如果没有 On Error GoTo 0 语句,在退出过程时,错误处理程序会自动关闭。

在错误未发生的时候,为了防止错误处理程序代码运行,请像在下段程序中那样,在紧靠着错误处理程序的前面写入 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。这个错误将由示例中的错误处理程序码来处理,处理完後,控制会回到发生错误的语句处。On Error GoTo 0 语句关闭错误陷阱。然后 On Error Resume Next 语句用来改变错误陷阱,以便发觉下一个语句产生的错误的范围。请注意示例中使用 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") '
试图启动不存在的对象
'
检查可能发生的
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 '
发生“文件已打开”的错误。
Close #1 '
关闭已打开的文件。
Case Else
'
处理其他错误状态
. . .
End Select
Resume '
将控制返回到产生错误的语句。
End Sub
 关于Resume语句的解释 

在错误处理程序结束后,恢复原有的运行。

语法

Resume [0]

Resume Next

Resume line

Resume 语句的语法可以具有以下任何一种形式:

语句
描述

Resume
如果错误和错误处理程序出现在同一个过程中,则从产生错误的语句恢复运行。如果错误出现在被调用的过程中,则从最近一次调用包含错误处理程序的过程的语句处恢复运行。

Resume Next
如果错误和错误处理程序出现在同一个程序中,则从紧随产生错误的语句的下个语句恢复运行。如果错误发生在被调用的过程中,则对最后一次调用包含错误处理程序的过程的语句(或 On Error Resume Next 语句),从紧随该语句之后的语句处恢复运行。

Resume line
在必要的 line 参数指定的 line 处恢复运行。line 参数是行标签行号,必须和错误处理程序在同一个过程中。

说明

在错误处理程序之外的任何地方使用 Resume 语句都会导致错误发生。

下面是一个关于错误处理的例子:

样表如下所示:

image 现在想计算B列与C列的比值的大小,明显的"计划/实际"值肯定会出现除数为0的现象,现在要做的是如何处理这个错误,使程序可以跳过错误行继续运行,并且在将错误的原因标明.

程序如下:

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'此处意思为返回到出错语句的下一句继续运行,若略掉Next,则从出错语句继续运行,那么就会造成死循环.样表如第3个图所示
End Sub

处理后的样表如下所示:

image 程序将出错的单元格赋值为0,并且可以继续运行,避免了程序的中断与错误处理.

image 这是不加Next时的效果,程序运行后会一直运行出错语句,导致程序死循环.由此看出,上面的程序并没有纠正错误的原始数据,想想也是这个道理,很多时候,要做的工作以原始数据为基础,得出一定的结论,有时错误的结论也是一种结论.


 

 

 

 

可捕获的错误   
可捕获的错误通常发生在应用程序运行时,但也有一些会发生在开发期间或编译时间。可使用 On Error 语句与 Err 对象来探测并回应可捕获的错误。1 – 1000 之间未使用的错误号都是保留给 Visual Basic 以后使用的。
3没有返回的GoSub
5无效的过程调用
6溢出
7内存不足
9数组索引超出范围
10此数组为固定的或暂时锁定
11除以零
13类型不符合
14字符串空间不足
16表达式太复杂
17不能完成所要求的操作
18发生用户中断
20没有恢复的错误
28堆栈空间不足
35没有定义 子程序、函数,或属性
47DLL 应用程序的客户端过多
48装入 DLL 时发生错误
49DLL 调用规格错误
51内部错误
52错误的文件名或数目
53文件找不到
54错误的文件方式
55文件已打开
57 I/O 设备错误
58文件已经存在
59记录的长度错误
61磁盘已满
62输入已超过文件结尾
63记录的个数错误
67文件过多
68设备不可用
70没有访问权限
71磁盘尚未就绪
74不能用其他磁盘机重命名
75路径/文件访问错误
76找不到路径
91尚未设置对象变量或 With 区块变量
92For循环没有被初始化
93无效的模式字符串
94Null 的使用无效
97不能在对象上调用 Friend 过程,该对象不是定义类的实例
298系统 DLL 不能被加载
320在指定的文件中不能使用字符设备名
321无效的文件格式
322不能建立必要的临时文件
325源文件中有无效的格式
327未找到命名的数据值
328非法参数,不能写入数组
335不能访问系统注册表
336ActiveX 部件不能正确注册
337未找到 ActiveX 部件
338ActiveX 部件不能正确运行
360对象已经加载
361不能加载或卸载该对象
363未找到指定的 ActiveX 控件
364对象未卸载
365在该上下文中不能卸载
368指定文件过时。该程序要求较新版本
371指定的对象不能用作供显示的所有者窗体
380属性值无效
381无效的属性数组索引
382属性设置不能在运行时完成
383属性设置不能用于只读属性
385需要属性数组索引
387属性设置不允许
393属性的取得不能在运行时完成
394属性的取得不能用于只写属性
400窗体已经显示,不能显示为模式窗体
402代码必须先关闭顶端模式窗体
419允许使用否定的对象
422找不到属性
423找不到属性或方法
424需要对象
425无效的对象使用
429ActiveX 部件不能建立对象或返回对此对象的引用
430类不支持自动操作
432在自动操作期间找不到文件或类名
438对象不支持此属性或方法
440自动操作错误
442连接至型态程序库或对象程序库的远程处理已经丢失
443自动操作对象没有默认值
445对象不支持此动作
446对象不支持指定参数
447对象不支持当前的位置设置
448找不到指定参数
449参数无选择性或无效的属性设置
450参数的个数错误或无效的属性设置
451对象不是集合对象
452序数无效
453找不到指定的 DLL 函数
454找不到源代码
455代码源锁定错误
457此键已经与集合对象中的某元素相关
458变量使用的型态是 Visual Basic 不支持的
459此部件不支持事件
460剪贴板格式无效
461未找到方法或数据成员
462远程服务器机器不存在或不可用
463类未在本地机器上注册
480不能创建 AutoRedraw 图象
481图片无效
482打印机错误
483打印驱动不支持指定的属性
484从系统得到打印机信息时出错。 确保正确设置了打印机
485无效的图片类型
486不能用这种类型的打印机打印窗体图象
520不能清空剪贴板
521不能打开剪贴板
735不能将文件保存至 TEMP 目录
744找不到要搜寻的文本
746取代数据过长
31001内存溢出
31004无对象
31018未设置类
31027不能激活对象
31032不能创建内嵌对象
31036存储到文件时出错
31037从文件读出时出错

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多