Excel VBAerror handling代码

我正在创build一个调用各种函数的macros,所有函数都返回string,并将结果显示在文本框中。

我开始阅读良好的error handling实践,但是有一个艰难的时间真的很了解它。 我希望对此有所了解。

基本上,到目前为止我已经实现了用于error handling的方法是在每个函数的开始处放置一个error handling程序,并对其进行设置,以便在该函数中发生错误时通知用户,但是继续计算其他function。

我的每个function都与这个相似

Function fnGetNumbers() As String On Error Goto ErrorHandler // Code to extract numbers from text If NumbersInText = vbNullString Then fnGetNumbers = vbNullString Else fnGetNumbers = "The numbers in the text are: " & NumbersInText End If ErrorHandler: If Error <> 0 Then fnGetNumbers = "An error occurred while extracting numbers from the text." End If End Function 

任何想法和/或build议将不胜感激!

error handling(在我看来)是真的要归结为你正在写的macros,谁在使用它们,谁在debugging它们。 虽然正确和彻底的error handling是最好的做法,如果你是唯一的在debugging它们,那么你将是唯一一个需要自定义错误。 这取决于你的组织,但这取决于你的需要。

这就是说,你的代码的一些说明:

 Function fnGetNumbers() As String ' Instead of returning a string, you can return a boolean and pass in a ' holder string for returning the value. This allows you to check TRUE/FALSE ' instead of checking if a string holds an error. On Error Goto ErrorHandler // Code to extract numbers from text If NumbersInText = vbNullString Then fnGetNumbers = vbNullString Else fnGetNumbers = "The numbers in the text are: " & NumbersInText End If Exit Function ' Always have this before your error block. ErrorHandler: fnGetNumbers = "An error occurred while extracting numbers from the text." Exit Function ' While not necessary if ' it is the only error handling block, it can be good practice. End Function 

返回某种对debugging有用的值也是最好的。 返回一个简单的string是无用的,而返回一个描述错误types的值更有用。

build议您不要为此默认运行ErrorHandler部分,也就是说

  • 得到一个有效的答案,然后退出该function
  • 得到一个错误(testing下面的Err.Raise 999

如果我正在运行一个长子程序清理(即恢复Application设置,那么我会有ErrorHandler高于默认清理(以及处理错误发生的事实)。

所以也许这(不能抵制轻微调整的IF – fnGetNumbers默认为空,所以不需要设置它)

 Function fnGetNumbers() As String On Error GoTo ErrorHandler `test the error Err.Raise 999 If NumbersInText <> vbNullString Then fnGetNumbers = "The numbers in the text are: " & NumbersInText Exit Function ErrorHandler: fnGetNumbers = "An error occurred while extracting numbers from the text." End Function 

我会告诉你我通常做什么 我有一个专门用于退出macros的子程序(我称之为exitPoint),我有一个子程序控制stream(我称之为主),在主的开始我有一个布尔值称为badExit设置为true,并在主要结束我把它设置为false,然后最后调用exitPoint。 每个子例程或函数都有一个错误陷阱,它将把控制权交给ExitPoint,并用一个string来指明错误在哪个例程中。然后exitPoint运行一系列的清理和error handling代码,这取决于badExit是true还是false。

基本上这个想法是我会提供支持,如果它是一个macros,我将它交给别人再也看不到了,我会在那里放更多的防御性编码和有用的错误信息 – 你可以testing一个错误号码并给出一个具体的信息,例如。

所以像这样(这是一个实际的macros,我已经削减了很多代码,只是为了说明):

 Option Explicit Option Private Module ... Private mbBadExit As Boolean Private msMacroWbName As String Private msMacroWbPath As String Private miSaveFormat As String Private miSheetsInNewWb As String Private mcolWorkbooks As New Collection Private mwbkNew As Workbook ... Sub Main() ' --------------------------------------------------------------------- ' Control procedure ' --------------------------------------------------------------------- Debug.Print "Main Start " & Time 'set exit state mbBadExit = True 'set macro document name and path msMacroWbName = ThisWorkbook.Name msMacroWbPath = ThisWorkbook.Path miSaveFormat = Application.DefaultSaveFormat miSheetsInNewWb = Application.SheetsInNewWorkbook 'disable some default application behaviours for macro effeciency With Application .Calculation = xlCalculationManual .ScreenUpdating = False .DisplayAlerts = False .EnableEvents = False .DisplayStatusBar = False .DefaultSaveFormat = xlOpenXMLWorkbook 'for excel 2007 compatability .SheetsInNewWorkbook = 3 End With Debug.Print "AddNew Start " & Time AddNew 'creates new workbook which the rest of the macro works with Debug.Print "Import Start " & Time Import 'import bobj CP_Import file and scalepoint data Debug.Print "Transform Start " & Time Transform 'various data munging to final state mbBadExit = False 'set exit state for clean exit Debug.Print "ExitPoint Start " & Time ExitPoint 'single exit point End Sub Private Sub ExitPoint(Optional ByVal sError As String) ' --------------------------------------------------------------------- ' Single exit point for macro, handles errors and clean up ' --------------------------------------------------------------------- Dim mwbk As Workbook 'return application behaviour to normal On Error GoTo 0 With Application .DisplayAlerts = True .Calculation = xlCalculationAutomatic .ScreenUpdating = True .EnableEvents = True .DisplayStatusBar = True .DefaultSaveFormat = miSaveFormat .SheetsInNewWorkbook = miSheetsInNewWb End With 'handle good or bad exit If mbBadExit = False Then 'no problem MsgBox "Process complete" 'close this workbook, leaving result workbook open Application.DisplayAlerts = False Set mcolWorkbooks = Nothing 'destroy collection object Workbooks(msMacroWbName).Close 'close macro wbk Application.DisplayAlerts = True Else 'an error occured 'show user error details MsgBox prompt:="Macro process has ended prematurely. Contact ... for support." _ & IIf(sError <> vbNullString, vbCrLf & sError, vbNullString) & vbCrLf _ & Err.Description, Title:="Error " & IIf(Err.Number <> 0, Err.Number, vbNullString) On Error Resume Next 'clean up open workbooks For Each mwbk In mcolWorkbooks mwbk.Close Next End If Debug.Print "Finish " & Time End End Sub Private Sub AddNew() ' --------------------------------------------------------------------- ' Creates new workbook which is the base workbook for ' The rest of the macro ' --------------------------------------------------------------------- On Error GoTo errTrap Set mwbkNew = Workbooks.Add mcolWorkbooks.Add mwbkNew With mwbkNew .Title = "CP HR Import" .Subject = "CP HR Import" End With Exit Sub errTrap: ExitPoint ("Error in AddNew sub routine") 'pass control to error handling exitpoint sub End Sub Private Sub Import() ' --------------------------------------------------------------------- ' Connect to source file (xlsx) with ADO, pull data into a recordset ' with SQL, then pull data to the workbook from the recordset to a ' querytable. Kill connection etc.. ' --------------------------------------------------------------------- On Error GoTo errTrap ...Code here... Exit Sub errTrap: ExitPoint ("Error in Import sub routine") 'pass control to error handling exitpoint sub End Sub Sub Transform() ' --------------------------------------------------------------------- ' Looks for records with an increment date and inserts a new record ' showing the new scalepoint from the increment date with the new ' salary ' --------------------------------------------------------------------- On Error GoTo errTrap ...code here... Exit Sub errTrap: ExitPoint ("Error in Transform sub routine") 'pass control to error handling exitpoint sub End Sub Sub ColumnsToText(rngColumns As Range) ' --------------------------------------------------------------------- ' Takes a column as a range and converts to text. UK date safe but ' not robust, use with care. ' --------------------------------------------------------------------- Dim avDates As Variant avDates = rngColumns.Value With rngColumns .NumberFormat = "@" .FormulaLocal = avDates End With Exit Sub errTrap: ExitPoint ("Error in ColumnsToText sub routine") 'pass control to error handling exitpoint sub End Sub