【发布时间】:2019-08-05 13:58:53
【问题描述】:
我有一个单独的模块和一个很长的工作子例程。
我决定把它切成小块。
我现在有六个模块,其中几个模块包含多个子例程(比如 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()。我不想要这个。我希望程序在运行完错误处理程序子程序后结束。
【问题讨论】:
-
在不涉及重构代码的情况下,您可以使用
Exit Substatement 甚至Endstatement 立即终止宏的执行——但您应该注意,这种类型的立即关闭不是一定是一个“干净”的出口,您可以在其中保存/擦除/撤消中间数据或您的程序已完成一半的其他事情。 -
Peter 的建议应该有效,只是为了澄清这一点,您应该将“Exit Sub”语句放在调用之后和“End If”之前。如果您希望在调用子程序时始终终止执行,您可以将“结束”语句放在 LogError() 子程序的最后。不过请记住彼得的警告。
-
谢谢...我希望收到一个可能如此简单的解决方案。哪个会更好...退出潜艇?还是结束?或者使用它们之间的优点/缺点/区别是什么?另外,您说“没有可能重构您的代码”。你这是什么意思?有没有更好/不同的方式来组织我的代码?
-
好的...我想通了...在第一个模块中,我将“on error goto error handler”放在第一个模块中。错误处理程序调用“Sub LogError(ErrorMsg As String)”,然后在子运行后它返回到错误处理程序并且程序结束......最后,我将 if 语句更改为 (Err.Raise Number:=vbObjectError + 513 , 说明:="不是 .csv 或 .txt 文件")。实际上,人为地创建了一个错误,将程序自动从子模块发送到母模块中的错误处理程序。
-
您可能想查看函数,它们可以返回值。在大多数情况下,您应该避免使用全局变量。
标签: excel vba error-handling