首页 > 解决方案 > 多个模块和子程序之间的错误处理

问题描述

我有一个模块和一个很长的工作子例程。

我决定把它切成小块。

我现在有六个模块,其中几个模块包含多个子例程(比如 6 个或更少)。例如,一个模块包含我的所有功能(如 10 个功能)。一个子程序 (RT_CMM_DATA_COMPILER_MAIN) 定义了几个变量并调用其他模块,如下所示:

Sub RT_CMM_DATA_COMPILER_MAIN()

    Public Path As String
    Public wkbTemp As Workbook
    Public StartTime As Double
    Public CurrentDateTime As Date
       'Etc....

       'Do some stuff....

    Call RT_SETUP_WKBTEMP
    Call RT_COMPILE_TABLE_HEADER
    Call RT_RUN_LOG
    Call RT_SAVE_WORKBOOKS

       'Do some stuff....

    Application.Quit

End Sub

Sub LogError(ErrorMsg As String)

    wkbErrorLog.Activate

    On Error Resume Next

    Range("A" & LRow).Value = CurrentData_FilePath
    Range("B" & LRow).Value = CurrentDateTime
    Range("C" & LRow).Value = ErrorMsg
        'Etc....

    wkbErrorLog.Save
    wkbErrorLog.Saved = True

    Application.Quit

    Application.DisplayAlerts = True
    Application.EnableEvents = True

End Sub

除了一个例外,这使得代码的使用变得更加容易。我不确定如何处理错误处理。例如,我的部分代码检查文件是 txt 还是 csv 文件。如果两者都不是,我希望它转到Sub LogError(ErrorMsg As String). 我的目的是创建一个错误处理程序,供所有各种模块和子程序使用。

Sub RT_SETUP_WKBTEMP()

    If File_Extension = "txt" Then
        Call RT_FORMAT_TXT_FILE
    ElseIf File_Extension = "csv" Then
        Call RT_FORMAT_CSV_FILE
    Else
        Call LogError("Not a .csv or .txt file")
    End If

        'Do some more stuff.....

End Sub

但是,我看到因为“调用”错误处理程序子例程,它在运行完错误处理程序子例程后又Sub RT_SETUP_WKBTEMP()回到了中断的地方。Sub RT_SETUP_WKBTEMP()我不想要这个。我希望程序在运行完错误处理程序子例程后结束。

标签: excelvbaerror-handling

解决方案


正如您在评论中已经指出的那样,您可以引发自定义错误并使用错误处理程序进行处理。您还可以使用 On Error... 记录整个调用堆栈。一旦发生错误,当前过程中的 On Error... 将不再适用,错误处理将传递给调用过程,您可以从中编写另一个错误日志条目:

Public Path As String
Public wkbTemp As Workbook
Public StartTime As Double
Public CurrentDateTime As Date
   Etc....

Sub RT_CMM_DATA_COMPILER_MAIN()
    Do some stuff....

    On Error GoTo ErrHandlerMain
    Call RT_SETUP_WKBTEMP
    Call RT_COMPILE_TABLE_HEADER
    Call RT_RUN_LOG
    Call RT_SAVE_WORKBOOKS

    Do some stuff....
ErrorExit:
    'Clean up and exit
    On Error Resume Next
    Application.Quit

    Application.DisplayAlerts = True
    Application.EnableEvents = True

    Exit Sub

ErrHandlerMain:
    Call LogError("Error in Sub RT_CMM_DATA_COMPILER_MAIN")
    Resume ErrorExit 'Go to the clean-up code and Exit Sub
End Sub

Sub RT_SETUP_WKBTEMP()
    Const iCUSTOM_ERROR As Integer = 513 
    On Error GoTo ErrHandlerSetup
    If File_Extension = "txt" Then 
        Call RT_FORMAT_TXT_FILE 
    ElseIf File_Extension = "csv" Then 
        Call RT_FORMAT_CSV_FILE 
    Else
        'This error will be handled by ErrHandlerSetup
        Err.Raise vbObjectError + iCUSTOM_ERROR
    End If

    'Do some more stuff.....

    Exit Sub

ErrHandlerSetup:
    Call LogError("Error in Sub RT_SETUP_WKBTEMP: Not a .csv or .txt file")

    'Raise another error, which will be handled by ErrHandlerMain in Sub RT_CMM_DATA_COMPILER_MAIN
    Err.Raise vbObjectError + iCUSTOM_ERROR
End Sub

Sub LogError(ErrorMsg As String)
    'Modified to not include any clean-up code
    wkbErrorLog.Activate

    On Error Resume Next

    Range("A" & LRow).Value = CurrentData_FilePath
    Range("B" & LRow).Value = CurrentDateTime
    Range("C" & LRow).Value = ErrorMsg
        Etc....

    wkbErrorLog.Save
    wkbErrorLog.Saved = True

End Sub

在这种情况下,错误日志将如下所示:

Error in Sub RT_SETUP_WKBTEMP: Not a .csv or .txt file
Error in Sub RT_CMM_DATA_COMPILER_MAIN


推荐阅读