在程序结束和错误处理程序中编写结束语句的好习惯是什么?

时间:2014-10-29 12:12:57

标签: vba excel-vba excel

我发现自己在程序结束和错误处理程序中都编写了一些命令。最重要的是,我发现自己在所有功能中都写了这些内容:

    Application.Cursor = xlDefault
    Application.ScreenUpdating = True

ErrHandler:
    MsgBox ("An unforseen problem has occured. Please contact support.")
    Application.Cursor = xlDefault
    Application.ScreenUpdating = True
End Sub

我觉得我在重复自己比我应该做的更多。在程序结束和错误处理程序中编写这些“标准”行是否有更好的做法?

3 个答案:

答案 0 :(得分:4)

您可以简单地将错误处理程序恢复到“清理”状态。在没有错误发生时也执行的代码段:

   Clean_up:
        Application.Cursor = xlDefault
        Application.ScreenUpdating = True
        Exit Sub
    ErrHandler:
        MsgBox "An unforeseen problem has occurred. Please contact support."
        Resume Clean_up
    End Sub

如果您在例程中始终拥有该代码,则可以将其移至您从Clean_up部分调用的单独例程。

答案 1 :(得分:1)

简化此操作的一种方法是使用RAII模式:即编写一个在其Class_Terminate事件过程中进行清理的类。例如,您可以创建类模块" CursorSaver"包含:

Private m_SavedCursor As XlMousePointer
Private m_SavedScreenUpdating As Boolean

Private Sub Class_Initialize()
    m_SavedCursor = Application.Cursor
    m_SavedScreenUpdating = Application.ScreenUpdating
End Sub

Private Sub Class_Terminate()
    Application.Cursor = m_SavedCursor
    Application.ScreenUpdating = m_SavedScreenUpdating
End Sub

然后,您可以在subs和函数的开头创建此类的实例,当函数退出时,类实例将超出范围,并且将自动调用终止代码并恢复初始状态:< / p>

Public Sub MySub
    Dim saver As New CursorSaver
    ...
    Exit Sub
End Sub ' Cursor and ScreenUpdating are automatically restored when the Sub exits

This answer to another question包含一个类似的例子。

答案 2 :(得分:0)

我也发现自己反复在我的程序中添加类似的错误处理代码,至少可以说有点乏味。有一个名为MZTools的VBIDE插件,可以添加您可以轻松嵌入代码中的代码片段,包括错误处理程序。这些片段允许包含占位符,例如过程名称,因此它可以适应目标过程。早期版本是免费的,但v8确实需要花钱,我认为它有点贵,但它有很多其他功能,它是你的选择。

这是一个示例错误处理程序,您可以看到占位符如何工作

Dim mpSettings As ApplicationSettings
Dim mpTopLevel As Boolean

    Const mpProcedure As String = "{PROCEDURE_NAME}"

    On Error GoTo {PROCEDURE_NAME}_Error
    'can be a top-level call or initiated by another
    mpTopLevel = IIf(IsArrayAllocated(mgVecProcStack), False, True)
    PushProcedureStack mpProcedure, mpTopLevel

    {PROCEDURE_NAME}= True

    Call AppSettings(State:="Set", _
                     AppType:=mpSettings, _
                     AppEvents:=True, _
                     AppScreen:=True, _
                     AppAlerts:=False, _
                     AppCalc:=appNotEnabled)

    {PROCEDURE_BODY}

{PROCEDURE_NAME}_Tidy:
    PopProcedureStack      

{PROCEDURE_NAME}_Tear_Down:               

{PROCEDURE_NAME}_Exit:
    Call AppSettings(State:="Reset", _
                     AppType:=mpSettings, _
                     AppEvents:=True, _
                     AppScreen:=True, _
                     AppAlerts:=False, _
                     AppCalc:=appNotEnabled)
    Exit Function

{PROCEDURE_NAME}_Error:
    If Err.Number = mgBypassErrorNum Then Resume {PROCEDURE_NAME}_Tear_Down
    {PROCEDURE_NAME} = False
    If AppErrorHandler(mmModule, mpProcedure, mpTopLevel) Then
        Stop
        Resume
    Else
        Resume {PROCEDURE_NAME}_Exit
    End If

我与MZTools或作者没有关系,它只是我使用的工具,并从中获得了价值。