vba - 您能否帮助我更多地了解有关VBA错误处理的良好做法?

标签 vba excel error-handling

我花了最后两天的时间来更好地了解VBA错误处理,但是实际发生的问题仍然存在。下面的文本描述了我已经实现并嵌入到描述中的一些问题。我真的很想别人帮助我增进理解,并给我一些指导。我掌握了通常的基础知识,并且我试图将更多的精力放在细微的功能上。

我期待您的任何答复!

重要的是要意识到在VBA中发生错误时会发生两种不同的情况。

  • 实例化错误对象并设置其属性(即err.number,err.desciption,err.source等)
  • 要执行的下一行更改。
    接下来执行哪一行取决于最后执行的“On Error Goto”语句-如果有的话。

  • 这些是独立但相关性很高的主题,实际上,您将编写不同但相互交织的代码来管理它们。

    当发生任何错误或使用Err.Raise时,总是设置Err对象。即使使用了“On Error Resume next”或其他任何On error语句。

    所以总是可以使用这样的代码:
    Dim i as integer 
    On error resume next 
    i = 100/0  ' raises error
    if err.number <> 0 then 
       ' respond to the error
    end if
    

    真正重要的是要意识到,当错误对象的err.number值非零时,会引发异常,并且如果您随后尝试执行任何“On Error Goto”语句,这样做本身就会引发错误,并且执行将传递给调用当前过程的任何代码。 (或者在程序未通过任何代码调用的情况下,给出了通常的VBA错误对话框)。因此,在此示例情况下,“出现错误时转到ALabel1”不会将下一行更改为带有Label1:的行。

    例如
    Sub ErrorTest()
    
        Dim dblValue        As Double
    
        On Error GoTo ErrHandler1
        dblValue = 1 / 0
    
    ErrHandler1:
        debug.print "Exception Caught"
        debug.print Err.Number
    
        On Error GoTo ALabel1    
        dblValue = 1 / 0   '' THIS LINE ACTUALLY WILL RAISE AN unhandled ERROR!
    
    Exit sub
    ALabel1:
        debug.print "Again caught it."
    
    End Sub
    

    将err.number属性设置为非零后,可以使用重置为零。
    On Error Goto -1 
    

    请注意,Err.Clear还将其重置为零,但实际上等效于:
    On Error Goto -1 
    On Error Goto 0
    

    即Err.Clear删除当前已存在的“On Error Goto”。因此,最好使用:
    On Error Goto -1   
    

    就像使用Err.clear一样,您通常需要添加一条额外的行来恢复已设置的错误处理程序,或者恢复其他状态。
    Err.Clear
    On Error Goto MyErrorHandlerLabel
    

    “或者,您可以将错误号设置为零(Err.Number = 0),但是由于它不会清除描述属性,因此它不如Clear方法有效。” (来自MSDN页面)

    我阅读了我认为的MSDN上的下一段,并且不了解如何将错误对象实例化(即err.number <> 0),将其值传递给执行End Sub时的任何调用过程。

    Q1:帮忙!

    “值得注意的是,VBA在执行任何类型的Resume语句,Exit Sub,Exit Function,Exit Property或任何On Error语句时,都会隐式执行Err.Clear。” (来自MSDN页面)

    您还可以将错误对象设置为您喜欢的任何数字

    错误编号:=,来源:=,说明:=

    Err.Raise非常重要,因为它允许您将错误传播到调用程序,并完全“向上”传播到与用户打交道的顶级程序。您还可以提出自己的错误编号,称为“用户定义的错误”。这提供了一种告诉调用程序由于某种原因它无法继续运行的方法(即,发生意外错误或业务规则被破坏)。

    通过这种方式,调用过程可以决定如何处理错误,而不是错误发生的过程(对于正在执行的操作,用户一无所知,而用户在执行过程中却一无所知。 !)

    Q2:我对吗?
    问题3:您是否会为此目的引发用户定义的异常?

    您可以使用以下语句来控制接下来执行哪一行代码
    On Error Goto ALabelName
    
    On Error Goto ANonZeroLineNumber
    


    On Error Goto 0
    

    On Error Goto 0是一个特例,因为它实际上表示“在当前范围内(通常是一个子或函数),如果发生错误,则将错误对象传递回调用当前子或函数的代码,在当前子或函数中不再执行任何代码。

    在VBA中使用简单的错误处理非常简单,但是当事情变得更加棘手时,经常会发现自己陷入了困境。

    没有SQL Server和VBA拥有的常用TRY CATCH语句是可耻的,所以我现在已经成功地在这里进行了模拟:

    https://codereview.stackexchange.com/questions/94415/try-catch-statement-in-vba-using-the-standard-vba-error-handling-statements

    希望以上博文可以让您对自己一直在做的实验有更多的了解,并帮助您理解我为何苦苦挣扎。

    简而言之,尽管那里有一些有用的站点,例如:

    http://www.cpearson.com/excel/errorhandling.htm

    但是,我觉得我可以提供更多指导。

    哈维

    最佳答案

    询问良好的作法,这是我诚实的答案:

    真正的好习惯是使用尽可能少的VBA。

    如果您打算创建一个更大的项目,那么我建议在C#中创建一个模块,然后在C#中调用office函数。

    然后将您的代码用作外接程序或函数库。换句话说:仅使用VBA来调用模块的主要输入功能。但是在C#中实现主要功能。

    我们生活在2015年。借助C#和Visual Studio,您现在手头上拥有强大的强大工具。但是VBA是在90年代引入的。语言和IDE受到限制。对于许多事情,例如正确的错误处理,您需要可怕的解决方法。

    顺便说一句,VBA语言在其诞生之时就已经过时了。在90年代,我们已经有了更好的面向对象的概念。遗憾的是,微软从未为其办公产品创建更好的语言。他们为了“向后兼容”而牺牲了更好的语言,并使他们的用户最容易过渡。恕我直言,这是一个错误的决定。因此,今天,我们在全局范围内以有限而简陋的语言编写了数百万个项目。

    关于vba - 您能否帮助我更多地了解有关VBA错误处理的良好做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31007009/

    相关文章:

    error-handling - IHttpModule 实现的错误处理在 IIS6 中不起作用,在 IIS5.1 中起作用

    Excel宏: ignore error

    vba - 如何知道细胞是否存在

    vba - 函数/命令超时

    Excel VBA 偏移函数

    java - 虚方法错误和NullPointerException错误

    html - VBA复制网站数据

    excel - 对工作簿 1 中的工作簿 2 中的数据进行排序

    excel - 复制一系列单元格,仅选择包含数据的单元格,仅选择值而不是公式

    c - 声明一个数组 fib[22]。如果用户要求第 22 个或更大的斐波那契数,则输出错误消息