用于运行时错误处理的元素

错误和错误处理

编写应用程序时,必须考虑出现错误时应该怎么办。 有两个原因会导致应用程序中出错。 第一,在运行应用程序时某些条件可能会使原本正确的代码产生错误。 例如,如果代码尝试打开一个已被用户删除的表,就会出错。 第二,代码可能包含不正确的逻辑,导致不能执行所需的操作。 例如,如果在代码中试图将数值被 0 除,就会出现错误。

如果没有做任何错误处理,则在代码出错时 Visual Basic 将停止运行并显示一条出错消息。 当发生这种情况时,用户很可能对此感到迷惑和沮丧。 通过将完整的错误处理例程包含在代码中来处理可能发生的所有错误,可以预防许多问题。

当将错误处理代码添加到过程中时,应当考虑在出现错误时过程将如何控制执行顺序。 在将执行交给错误处理程序的步骤中,第一步是通过将某种形式的 On Error 语句包含在过程中来启用错误处理程序。 On Error 语句在错误事件中对执行进行定向。 如果没有 On Error 语句,在出现错误时 Visual Basic 只是简单地中止程序执行并显示一条出错消息。

如果过程中发生了错误并且启用了错误处理程序,Visual Basic 将不会显示正常的错误消息。 而是会将执行权转交给错误处理程序(如果存在)。 执行权转交给启用的错误处理程序后,错误处理程序变为活动状态。 在活动的错误处理内,可以确定发生的错误类型以及选择处理错误的方式。 Access 提供三个对象,其中包含有关已发生的错误的信息:ADO Error 对象、Visual Basic Err 对象和 DAO Error 对象。

发生错误时路由执行

错误处理程序指定发生错误时过程如何响应。 例如,您可能希望在发生特定的错误时终止过程的运行,或者希望更正导致错误的条件并继续执行。 On ErrorResume 语句确定发生错误时执行的方式。

On Error 语句

On Error 语句启用或禁用错误处理例程。 如果启用了错误处理例程,则当发生错误时执行权会传递给错误处理例程。

On Error 语句有三种形式:On Error GoTolabelOn Error GoTo 0On Error Resume NextOn Error GoTolabel 语句启用错误处理例程,该例程从这个语句出现的代码行开始执行。 应当在可能出现错误的第一行代码前启用错误处理例程。 在错误处理程序处于活动状态下发生错误时,将传递执行到由label参数指定的行。

label 参数指定的行应是错误处理例程的开头。 例如,以下过程指定如果发生错误,则执行将传递到标记为的行:

Function MayCauseAnError() 
    ' Enable error handler. 
    On Error GoTo Error_MayCauseAnError 
    .            ' Include code here that may generate error. 
    . 
    . 
 
Error_MayCauseAnError: 
    .            ' Include code here to handle error. 
    . 
    . 
End Function

On Error GoTo 0 语句在过程中禁用错误处理。 即使过程中包含有标号为 0 的代码行,该语句也不把 0 行指定为错误处理代码的起始。 如果代码中没有 On Error GoTo 0 语句,则在过程运行完成时将自动禁用错误处理程序。 On Error GoTo 0 语句会重置 Err 对象的属性,这与 Err 对象的 Clear 方法具有相同的效果。

On Error Resume Next 语句会忽略导致错误的代码行并将执行路由到错误代码行的下一行。 此时过程执行并没有中止。 如果要在预计会发生错误的行之后立即检查 Err 对象的属性,并在过程中而不是错误处理程序中处理错误,请使用 On Error Resume Next 语句。

Resume语句

Resume 语句将执行权从错误处理例程重定向到过程的主体。 如果要从过程某一特定点上继续执行程序,则可以在错误处理例程中包含 Resume 语句。 不过 Resume 语句并不是必需的;也可以在运行完错误处理例程之后就结束过程。

Resume 语句有三种形式。 其中 ResumeResume 0 语句将执行返回到发生错误的代码行。 而 Resume Next 语句将执行返回到错误代码行的下一行。 Resumelabel 语句则将执行返回到由 label 参数指定的代码行。 label 参数必须指定一个行标签或一个行号。

通常如果要求用户必须更正错误,则可以使用 ResumeResume 0 语句。 例如,如果提示用户输入一个表的名称以便打开该表,而用户输入了一个并不存在的表名,则可以再次提示用户并在导致错误的语句上继续程序的执行。

如果代码在错误处理程序中更正了错误,并且想继续执行而无需再次运行引起错误的代码行,可以使用 Resume Next 语句。 如果想在过程中由 label 参数指定的其他代码行上继续执行,则可以使用 Resumelabel 语句。 例如,可以在退出例程上恢复程序的运行,如以下章节所述。

退出过程

在过程中包含一个错误处理例程的同时,还应该包括一个退出例程,以便只有在发生错误时才运行错误处理例程。 可以像指定错误处理例程一样用行标签指定退出例程。

例如,可以将退出例程添加到前面章节的示例中。 如果没有出现错误,退出例程在过程主体之后运行。 而如果出现错误,则在运行完错误处理例程之后执行将传到退出例程。 退出例程包含一个 Exit 语句。

Function MayCauseAnError() 
    ' Enable error handler. 
    On Error GoTo Error_MayCauseAnError 
    .            ' Include code here that may generate error. 
    . 
    . 
 
Exit_MayCauseAnError: 
    Exit Function 
 
Error_MayCauseAnError: 
    .            ' Include code to handle error. 
    . 
    . 
    ' Resume execution with exit routine to exit function. 
    Resume Exit_MayCauseAnError 
End Function

处理嵌套过程中的错误

当没有启用错误处理程序的嵌套过程中发生错误时,Visual Basic 会向后搜索另一个过程中已启用的错误处理程序的调用列表,而不仅仅是停止执行。 这为代码提供了在另一个过程中更正错误的机会。 例如,假设过程 A 调用过程 B,过程 B 调用过程 C。如果在过程 C 中发生错误,并且没有启用的错误处理程序,Visual Basic 会检查过程 B,然后是过程 A,以查找已启用的错误处理程序。 如果存在,则执行将传递给该错误处理程序。 否则,执行将停止,并显示错误消息。

当活动的错误处理程序中出现错误时,Visual Basic 也会通过向后搜索调用列表来查找已启用的错误处理程序。 可以使用 Err 对象的 Raise 方法在活动错误处理程序中引发错误,从而强制 Visual Basic 向后搜索调用列表。 这在处理错误处理程序中出现预料外的错误时很有用。 如果出现预料之外的错误,而在错误处理程序中又重新生成了该错误,则执行将按照调用列表的逆序传递以查找其他可能被设置来处理该错误的错误处理程序。

例如,假设过程 C 有一个已启用的错误处理程序,但并未纠正已经出现的错误。 当该错误处理程序检查了所有预料之中的错误之后,它可以重新产生原有的错误。 此时执行将按照调用列表的逆序传给过程 B 中的错误处理程序(如果存在该程序的话),给该错误处理程序纠正错误的机会。 如果过程 B 没有错误处理程序或者如果不能纠正错误并重新生成了错误,则执行将传给过程 A 中的错误处理程序(假设该误处理程序存在)。

若要以另一种方式说明此概念,假设你有一个嵌套过程,其中包括类型不匹配错误的错误处理,这是你预料到的错误。 在某个时候,过程 C 中会出现未预料到的被零除错误。如果已包含用于重新生成原始错误的语句,则执行会将调用列表备份到另一个已启用的错误处理程序(如果存在)。 如果在调用列表中的另一个过程中更正了除以零的错误,则将更正该错误。 如果代码未重新生成错误,则该过程将继续运行,而不会更正除以零的错误。 这反过来可能会导致嵌套过程集中出现其他错误。

总之,在以下情况下 Visual Basic 会按照逆序在调用列表中搜索已启用的错误处理程序:

  • 在不包含已启用的错误处理程序的过程中出现错误。

  • 在活动的错误处理程序中出现错误。 如果使用 Err 对象的 Raise 方法来产生一个错误,就可强制 Visual Basic 向后搜索调用列表以查找已启用的错误处理程序。

获取有关错误的信息

执行权传递给错误处理例程之后,代码必须确定发生了什么错误并处理它。 Visual Basic 和 Access 提供了几个可用来获取特定错误信息的语言元素。 每种语言元素都适用于不同类型的错误。 因为错误将发生在应用程序的不同部分,所有需要根据所预期的错误在代码中选择使用不同的语言元素。

可用于错误处理的语言元素有:

Err 对象

Err 对象是由 Visual Basic 提供的。 当出现 Visual Basic 错误时,有关该错误的信息将存储在 Err 对象中。 Err 对象每次只维护一个错误的信息。 当出现新的错误时,Err 对象将更新为新的错误信息。

若要获取有关特定错误的信息,可以使用 Err 对象的属性和方法:

  • Number 属性是 Err 对象的默认属性;它返回发生的错误的标识号。
  • Err 对象的 Description 属性返回与 Visual Basic 错误关联的描述性字符串。
  • Clear 方法从 Err 对象中清除当前错误信息。
  • Raise 方法生成特定错误,并使用有关该错误的信息填充 Err 对象的属性。

下面的示例说明了如何在可能导致类型不匹配错误的过程中使用 Err 对象:

Function MayCauseAnError() 
    ' Declare constant to represent likely error. 
    Const conTypeMismatch As Integer = 13 
 
    On Error GoTo Error_MayCauseAnError 
        .            ' Include code here that may generate error. 
        . 
        . 
 
Exit_MayCauseAnError: 
    Exit Function 
 
Error_MayCauseAnError: 
    ' Check Err object properties. 
    If Err = conTypeMismatch Then 
        .            ' Include code to handle error. 
        . 
        . 
    Else 
        ' Regenerate original error. 
        Dim intErrNum As Integer 
        intErrNum = Err 
        Err.Clear 
        Err.Raise intErrNum 
    End If 
    ' Resume execution with exit routine to exit function. 
    Resume Exit_MayCauseAnError 
End Function

请注意在上面的示例中,Raise 方法用来重新产生原有的错误。 如果出现类型不匹配以外的错误,执行权将按照调用列表的逆序传递给其他的错误处理程序(如果存在该程序的话)。

Err 对象提供了您所需的有关 Visual Basic 错误的全部信息。 然而,它并没有提供有关 Microsoft Access 错误或 Microsoft Access 数据库引擎错误的完整信息。 Microsoft Access 和数据访问对象 (DAO) 提供了附加的语言元素来帮助处理这些错误。

Error 对象和 Errors 集合

Error 对象和 Errors 集合是由 ADO 和 DAO 提供的。 Error 对象代表一个 ADO 或 DAO 错误。 单个 ADO 或 DAO 操作可能引起几个错误,特别是执行 DAO ODBC 操作时。 在特定数据访问操作过程中发生的每个错误都有一个关联的 Error 对象。 与特定的 ADO 或 DAO 对象关联的所有 Error 对象都存储在 Errors 集合中,其中最低级别的错误为集合中的第一个对象,最高级别的错误为集合中的最后一个对象。

出现 ADO 或 DAO 错误时,Visual Basic 的 Err 对象包含 Errors 集合中第一个对象的错误编号。 若要确定是否出现了其他的 ADO 或 DAO 错误,可检查 Errors 集合。 Errors 集合中第一个 Error 对象的 ADO Number 或 DAO Number 属性和 ADO Description 或 DAO Description 属性应该与 Visual Basic Err 对象的 NumberDescription 属性值相匹配。

AccessError 方法

使用 Err 对象的 Raise 方法可生成实际未发生的 Visual Basic 错误,并确定与该错误关联的描述性字符串。 然而,不能使用 Raise 方法产生 Access 错误、ADO 错误或 DAO 错误。 若要确定与实际上并未发生的 Access 错误、ADO 错误或 DAO 错误相关的描述性字符串,可使用 AccessError 方法。

错误事件

使用 Error 事件捕获 Access 窗体或报表上发生的错误。 例如,当用户试图在数据类型为“日期/时间”的字段中输入文本就会发生 Error 事件。 如果把 Error 事件过程添加到"雇员"窗体上,然后试图在"雇佣日期"字段中输入一个文本值,Error 事件过程就会运行。

Error 事件过程有一个整型参数 DataErr。 在运行 Error 事件过程时,DataErr 参数将包含出现的 Access 错误的编号。 确定发生错误的编号的唯一方法就是在事件过程中检查 DataErr 参数。 在发生 Error 事件之后,Err 对象并不为错误信息所填充。 将 DataErr 参数的值与 AccessError 方法结合使用,以确定错误数及其描述性字符串。

注意

提供 Error 语句和 Error 函数的目的只是为了向后兼容。 在编写新代码时,请使用 ErrError 对象、AccessError 函数和 Error 事件来获取错误信息。

关于参与者

UtterAccess社区的社区成员图标提供的链接

UtterAccess 是主要的 Microsoft Access Wiki 和帮助论坛。

另请参阅

支持和反馈

有关于 Office VBA 或本文档的疑问或反馈? 请参阅 Office VBA 支持和反馈,获取有关如何接收支持和提供反馈的指南。