Vba 错误类型:调试和解决方案
与任何其他编程语言一样,VBA 在出现错误时并不幸运,无论如何您都必须处理它们。它们可能来自不同的来源,例如错误的编码、不可能的操作(例如除以零)或意外错误。
处理这个问题的最佳方法是充分了解使用代码可以实现的所有可能结果。请看下面的示例,其中我们有一个 VBA 代码,该代码使用所选单元格中的值计算数字的平方根。
Sub Square_Root() ActiveCell. Value = ActiveCell. Value ^ (1 / 2) End Sub
但是,如果活动单元格的值不是数字,您将收到运行时错误,如下所示。
VBA 中的错误参数(错误捕获)
在 VBA 选项中,您可以在开始编写代码之前配置设置以处理错误。要打开 VBA 设置,请转到“工具”➤“选项”➤“常规”➤“错误捕获”。这里有三个选项可供您使用。
- 出现所有错误时停止:如果启用此选项,即使您使用了各种错误处理技术,VBA 也会停止所有类型错误的代码。
- 篡改类模块:使用此选项,VBA 将停止所有未通过任何技术处理的代码。如果您使用像用户表单这样的对象,它也会分解这些对象并突出显示错误所在的确切行。
- Break on Unhandled Errors :这是默认设置,可帮助您了解未使用任何错误处理技术的所有错误,并针对所有未处理的错误停止代码。 (但是,如果您使用像用户窗体这样的对象,这不会突出显示导致对象中错误的行,而只会突出显示引用该对象的行)。
VBA 错误的类型
为了理解VBA错误,您可以将它们分为四类,下面是这些类型错误的解释。
1. 语法错误
在编写 VBA 代码时,您必须遵循特定的语法,当您忽略它或不按应有的方式编写它时,您可能会遇到语法错误(也称为语言错误)。这就像您在编写代码时犯下的打字错误。
那么,VBA 通过显示错误消息来报告这些错误,从而帮助您。您只需确保 VB 编辑器中启用了“自动语法检查”即可。
转到“工具”➤“选项”并确保选中“自动语法检查”框。这样,只要出现语法错误,VBA 就会显示错误消息。
但如果禁用“自动语法检查”,VBA 仍会突出显示有错误的代码行,但不显示错误消息。
2. 编译错误
当您编写代码来执行某项活动,但该活动无效或 VBA 无法执行时,就会发生这种情况。最好的例子是,您有一些使用 IF 语句的代码,但您错过了在语句末尾添加 END IF,现在当您运行此 VBA 时,您会显示编译错误消息。
除此之外,还有其他编译错误的例子:
3. 运行时错误
执行代码时发生运行时错误。请记住我上面与您分享的示例,当时代码计算了数字的平方根。
当执行代码时发生运行时错误时,它会停止代码并向您显示错误对话框,该错误框会说明您所遇到的错误的性质。假设您编写了从指定位置打开工作簿的代码,但该工作簿现在已被某人移动或删除。
因此,当您运行代码时,VBA 将显示运行时错误,因为它在此位置找不到该文件。您在运行时错误中收到的消息描述了原因,可帮助您了解错误的原因。
当发生运行时错误时,它会停止代码执行。如果单击“调试”按钮,它会以黄色突出显示包含此错误的代码行。或者您可以单击“结束”按钮来停止代码执行并关闭错误消息。
4、逻辑错误
这不是错误,而是编写代码时的错误。这些类型的错误有时会给您在查找和修复它们时带来麻烦。
假设您正在编写一些代码,并且在声明变量时使用了错误的数据类型或者使用了错误的计算步骤。在这种情况下,您的代码将正常工作,并且您不会轻易发现此错误。处理这类问题的最好办法就是逐行运行每一行代码。
在 VBA 中使用调试工具
VBA 为您提供了一组工具来调试代码并消除代码中的错误。
1.编译VBA工程
在 Visual Basic 编辑器中,有一个选项可以在完成代码后立即使用。这些编译选项会分析代码的每一行,并在代码中存在错误时显示消息框。
注意: “编译 VBA”选项仅跟踪语法和编译错误,而不跟踪运行时错误,因为这些错误仅在代码运行时发生。要使用编译 VBA 项目,请转到 ➤ 调试 ➤ 编译 VBA 项目。
运行“编译 VBA 项目”并且代码中没有错误后,选项将显示为灰色。
2.逐行运行每一行代码
我就是这样做的。当我完成代码时,我只是逐行运行它来检查是否有错误。这可能需要一些时间,但它可以帮助您解决所有错误(语法、编译和执行)。
在“调试工具栏”上有一个“单步执行”按钮,您可以使用该按钮逐行运行代码,或者只需按 F8 运行一行,然后再次按它即可运行代码中的下一行。
使用“On ERROR”语句处理 VBA 错误
检查代码并在所有可用的调试方法中查找可能的错误非常重要。但最好、最有效的方法是创建错误处理指令,可以处理错误并使代码在执行时完美无缺。让我们来探讨一下这些陈述。当 VBA 代码中发生错误时,处理该错误的最佳方法可以是:
- 让VBA忽略错误并运行代码
- 当错误发生时,让一组特殊的指令执行。
在这两种解决方案中,您都可以使用“On Error”语句。以下是您可以使用的四个“On Error”语句。现在让我们一一看看每一个陈述。
1. 如果你犯了错误,请重新开始
这行简单的代码允许 VBA 在发生错误的情况下继续执行代码。想法很简单:如果在执行过程中任何地方检测到错误,则移至下一行代码。
在下面的代码中,有两行代码:
- 第一行表示单元格 A1 中的值是 25 除以 0
- 第二行表示单元格值 A2 是 10 除以 5
现在你网上的代码有问题。如您所知,如果将任何值除以 0,结果都会出错。因此,当您运行此代码时,VBA 将显示错误消息“运行时错误 ’11’ 除以零”并停止执行。
但是,当您在代码的最开头添加“On Error Resume Next”并运行代码时,VBA 只是忽略发生错误的代码行并继续执行第二行,并将该值添加到单元格 A2 中。
Sub myDivide() On Error Resume Next Range ("A1"). Value = 25 / 0 Range ("A2"). Value = 10 / 5 End Sub
因此,每当您希望代码在任何地方发生错误时都能运行,只需在代码中使用“On Error Resume Next”语句即可。
但您还应该注意一件事:它只会忽略随后发生的错误。
假设第 5 行发生错误,并且您在第 8 行添加了“On Error Resume Next”,则它不会跳过此错误。因此,最好的方法是将其添加为过程中的第一行代码。
2. 如果出现 GoTo 0 错误
这是 VBA 的默认行为,当发生错误时,它会停止代码执行。
好吧,使用“On Error GoTo 0”对你的代码没有什么影响。 VBA 将简单地停止代码并显示一条包含错误描述的消息。那么我为什么要费心去使用它呢?聪明的问题。让我们使用上面“ On Error Resume Next ”中使用的示例。
在此代码中,每当发生错误时,VBA 都会获取下一行代码并执行它,并且您不会看到任何错误消息。但是,假设您的代码中有更多行,并且如果代码中存在错误,您不希望超出这些行。
因此,如果您在第二行代码后输入“On Error GoTo 0” ,它将恢复 VBA 的默认错误处理程序,该处理程序会在发生错误时显示错误消息。
3. 如果出现 GoTo 错误 [标签]
想一想在紧急情况下您可以前往建筑物中的某个地方。同样,使用“On Error GoTo [Label]”,您可以简单地在主代码中创建一个单独的代码块来处理错误。
事实上,“On Error GoTo [Label]”是一种更好、更方便的错误处理方式。在下面的代码中,您可以看到“On Error GoTo Oh!”错误”现在在这一行声明中,单词“哦!”错误”是标签。
如果您查看代码的末尾,其中有一个以标签名称开头的特定开头,然后是消息框的代码,代码上有一条消息。
现在如果发生错误会发生什么,VBA 将跳转到标签“哦! Error”并将执行该标签后面的代码块。
但您需要注意一件事:如果没有发生错误,则代码中的标签将被执行。您需要做两件事:
- 首先,确保在代码末尾添加错误标签。
- 其次,在错误标签前添加“Exit Sub”。
这样,您在这两种情况下都会受益。假设如果发生错误并且 VBA 切换到您指定的标签,则只会有从标签本身到代码的代码。如果没有发生错误,则标签之前的“Exit Sub”语句将退出过程而不执行错误标签。
4. 如果出现GoTo错误-1
在我们开始讨论之前,让我先与您分享一些内容。当代码中发生错误时,VBA 会将此错误日志存储在其内存中,并且仅在例程完成时才将其清除。
噢,VBA!活在当下
要处理 VBA 代码中的第二个错误,必须从 VBA 内存中清除第一个错误。在下面的代码中,有两个“On Error GoTo [Label]”语句,用于处理来自两个不同代码块的错误。
但如果运行此代码,当第二个错误时,VBA 将不会跳转到您设置的标签,而是显示“类型不匹配”错误消息。
Sub Square_Root() On Error GoTo myError1 Range ("A1"). Value = Range ("A1"). Value ^ (1 / 2) myError1: MsgBox "There's some problem with the value you have in the cell A1." On Error GoTo myError2 Range ("A2"). Value = Range ("A2"). Value ^ (1 / 2) myError2: MsgBox "There's some problem with the value you have in the cell A2." End Sub
要解决此问题,您可以使用“On Error GoTo -1”,它允许 VBA 从其存储中删除当前错误。
Sub Square_Root() On Error GoTo myError1 Range("A1").Value = Range("A1").Value ^ (1 / 2) myError1: MsgBox "There's some problem with the value you have in the cell A1." On Error GoTo -1 On Error GoTo myError2 Range("A2").Value = Range("A2").Value ^ (1 / 2) myError2: MsgBox "There's some problem with the value you have in the cell A2." End Sub
现在,当您运行此代码时,“On Error GoTo -1”会从内存中删除错误,并且 VBA 根据需要处理第二个语句中的错误。
为了处理 VBA 中的错误,我还需要了解什么?
除了使用错误处理技术之外,您还可以使用其他一些方法来更好地处理错误。
对象错误
当执行代码时发生错误时,您可以使用 Err 对象来获取有关错误的详细信息。有一些属性和方法可以与 Err 对象一起使用。让我们一一学习它们。
特性
以下是可与 Err 对象一起使用的属性:
- Err.Number :发生错误时,Err 对象中会存储一个数字。在下面的代码中,当发生这种情况时,消息框会显示错误号。
- Err.Description :该属性显示错误描述,可以帮助您了解错误的原因。
- Err.Source:此属性告诉您在哪个项目中发生了错误。
- Err.HelpContext:此属性返回帮助文件中错误的帮助上下文 ID。
- Err.HelpContext:这是帮助文件位置的字符串值。
通常,当您使用错误处理技术处理错误时,您不会在代码中过多使用 Err 对象。但下面是一个使用它的简单示例。
Sub Square_Root() On Error GoTo myError1 Range("A1").Value = Sqr(Range("A1").Value) Exit Sub myError1: MsgBox "There's some problem with the value you have in the cell A1." & vbCrLf & _ "Error Number: " & Err.Number & vbCrLf & _ "Error Description: " & Err.Description End Sub
当您运行上述代码时,如果发生错误,它将显示一个消息框,其中包含错误号和错误描述。
方法
对于 Err 对象,您还可以使用两种方法。
- Err.Clear:此方法从 VBA 内存中清除错误号和错误描述(这与“On Error GoTo -1”不同,因为它不会完全重置错误)。
- Err.Raise:使用此方法,您可以故意在代码中生成运行时错误,语法如下:
Err .Raise [编号]、[来源]、[描述]、[帮助文件]、[帮助上下文]
错误处理的快速提示
您可以使用以下一些快速提示来更好地处理 VBA 错误。
- 仅当您确定发生错误并且可以跳过有错误的代码行并安全地移至下一行时,才使用“On Error Resume Next”。
- 处理运行时错误的最佳方法是使用“Error Handler”和“On Error GoTo [Label]”。这可以确保每当错误发生时,您都会收到通知,但不会显示令人讨厌的错误消息。
- 每次使用错误处理程序时,请确保先使用“Exit Sub”。