我没有读过太多关于它的文章,但下面链接的作者建议我不要使用“冒泡”来集中VBA中的错误处理。
Excel Programming Weekend Crash Course via Google Books
但我不确定他为什么推荐这样做,而且他也没有真正解释。
谁能告诉我为什么我应该在每个过程中使用错误处理,而不是使用“冒泡”?或者至少,你知道作者为什么不这么做吗?
谢谢。
发布于 2009-09-13 21:11:54
我不确定VBA的默认错误处理是什么,但由于它的Visual Basic for Applications,以及这些应用程序包括excel和word之类的内容,我假设只会出现一个对用户没有帮助的对话框。
我假设作者已经被不处理错误的代码所困扰,所以他现在推荐所有处理错误的过程。
完整的答案是,您必须意识到可能发生的每个错误,并拥有适当的代码来处理它,无论是尽可能低的错误(您可能不知道该做什么),还是尽可能高的错误(这意味着编写错误处理代码的工作量较小,但不知道错误发生的原因),还是战略性的(就在您应该能够从最常见的错误中恢复的正确位置),或者只是到处(这可能是太多的开发工作)。
发布于 2009-09-13 23:51:06
对你的第一个问题的简短回答是“你不应该在每个过程中都放一个错误处理程序”。但通常情况下,一些例程确实需要它们!
说“每个过程都必须有一个错误处理程序”通常是很糟糕的建议。VBA错误处理的缺陷在其他地方已经讨论了很多。但是,从概念上讲,它与其他语言中更标准的异常处理形式并没有太大的不同。这些语言的大多数最佳实践都适用。您应该在最低级别处理错误,在那里处理它们是有意义的。有时,这是在发生错误的过程中发生的,但很多时候不是。
通常,当发生错误时,内部例程所能做的最有意义的事情就是让它在堆栈中向上传递,这样它就可以到达知道如何处理它的代码。这真的取决于例程以及它如何与程序的其余部分相匹配。
考虑以下示例:
调用过程中的处理程序将处理它调用的例程引发的所有错误。因此,如果一个特定的例程不需要任何清理,那么不要将任何错误处理程序代码放在那里:
Sub Caller()
On Error GoTo HANDLER
ChildProc
On Error GoTo 0
Exit Sub
HANDLER:
Debug.Print Error, "Parent cleanup - something happened in either this procedure or a procedure that it called"
End Sub
Sub ChildProc()
Debug.Print 10 / 0 ' causes error
'Don't bother handling errors here since there's nothing this routine can do about them
End Sub另一方面,您可能需要清理任务,在这种情况下,您需要错误处理程序。
Sub Caller()
On Error GoTo HANDLER
ChildProc
On Error GoTo 0
Exit Sub
HANDLER:
Debug.Print Error, "Parent cleanup"
End Sub
Sub ChildProc()
'Pretend this routine gets ahold of some resource that must be cleaned up when it's done
call get_resources()
On Error GoTo HANDLER
Debug.Print 10 / 0 ' causes error
On Error GoTo 0
'Clean up once we're done
call release_resources()
Exit Sub
HANDLER:
Debug.Print Error, "Child cleanup"
'Clean up in case of an error
call release_resources()
'Raise another error if necessary to let callers know something went wrong
Err.Raise 10000, "ChildProc", Error
End Sub上面的示例只是为了说明为什么在给定的例程中可能需要或不需要错误处理程序。因此,值得注意的是,在实际代码中,使用RAII技术处理“资源”示例通常更好,这种技术将错误处理与资源获取和释放封装在一起-有关https://stackoverflow.com/a/3792280/58845的示例,请参阅VBA。而像是否重新引发捕获的错误这样的事情也是取决于情况的。有时,完全在本地处理错误是可能的,这样就不需要告诉调用者出了什么问题。
第二个问题的答案是,作者似乎不太了解异常处理。他承认错误处理是特定于上下文的,但似乎建议每个过程都应该在“在这里纠正问题并恢复执行”和“终止程序”之间做出本地决定。他遗漏了通常正确的选择,那就是“清理本地,把问题踢上楼”。因此,不需要在本地清理的例程应该让错误“冒泡”。
发布于 2009-09-15 01:26:05
我的2点意见:你应该在所有的公共过程和事件上设置错误处理程序。这意味着位于调用堆栈底部的过程将始终具有错误处理程序。然后在您的其他过程中添加错误处理程序,因为这是有意义的。如果错误发生在没有错误处理程序的过程中,它将“冒泡”到顶级错误处理程序,在那里以专业的方式记录/显示它。您可能希望将错误处理程序添加到私有(较低级别)过程的场景是这样的:代码需要快速。您有一种可以避免的罕见情况,但这将迫使您在循环(或更糟的嵌套循环)中执行代价高昂的逻辑测试。您可以在错误处理程序中执行逻辑测试,如果显示为“罕见发生”,则进行更正并恢复。由于这种情况很少见,因此您将看到大多数情况下的性能提升。如果错误处理程序无法找出并纠正问题,则重新引发错误以使其在堆栈中冒泡。
显然,这只是一种情况。
https://stackoverflow.com/questions/1418777
复制相似问题