[英]Excel VBA Error Handling Code
我正在創建一個調用各種函數的宏,所有函數都返回字符串,並在文本框中顯示結果。
我開始閱讀良好的錯誤處理實踐,但是很難理解其中很多錯誤。 我希望就如何解決這個問題提出一些意見。
基本上,到目前為止我為錯誤處理實現的方法是在每個函數的開頭放置一個錯誤處理程序,並將其設置為如果在該函數中發生錯誤,它將通知用戶但是繼續計算其他功能。
我的每個功能看起來都與此類似
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
任何想法和/或建議將不勝感激!
建議您不要為此默認運行ErrorHandler部分,即
Err.Raise 999
測試) 如果我正在運行一個帶有清理的長子例程(即恢復Application
設置,那么我會將ErrorHandler置於默認清理之上(以及處理錯誤發生的事實)。
所以也許這個(無法抵抗對IF的輕微調整 - fnGetNumbers默認為null,因此無需設置它)
碼
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
錯誤處理(在我看來)實際上歸結為你正在編寫的那種宏,誰在使用它們,以及誰正在調試它們。 雖然正確和徹底的錯誤處理是最佳實踐,但如果您是唯一一次調試它們,那么您將是唯一需要自定義錯誤的人。 這會根據您的組織而變化,但這取決於您的需求。
話雖如此,你的代碼有一些注意事項:
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
最好還是返回一些對調試有用的值。 返回一個簡單的字符串是沒用的,而返回一個描述錯誤類型的值更有用。
我會告訴你我通常做的事情。 我有一個專門用於退出宏的子例程(我稱之為exitPoint),我有一個控制流的子例程(我稱之為main),在main的開頭我有一個名為badExit的布爾值設置為true,並且主要的結尾我把它設置為假,然后最后調用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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.