我會告訴你我通常做什麼。我有一個專門用於退出宏(我稱之爲exitPoint)的子例程,並且我有一個子例程控制流(我稱之爲main),在main的開始處我有一個名爲badExit的布爾值設置爲true,並且在主要結束我把它設置爲false,然後最後調用exitPoint。每個子例程或函數都有一個錯誤陷阱,它會將控制權交給ExitPoint,並使用一個字符串來指明錯誤發生在哪個例程中。然後exitPoint運行一系列清理錯誤處理代碼,具體取決於badExit是true還是false。
基本上這個想法是我會提供支持,如果它是一個宏,我將它交給別人再也看不到它,我會在那裏放置更多的防禦性編碼和有用的錯誤信息 - 你可以測試爲一個錯誤號碼,並給出一個特定的消息,例如。
因此,像這樣(這是我剪了大量的代碼出的實際宏只是爲了說明):
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
請參閱BrettDJ的回答評論。感謝一堆! –