簡體   English   中英

Excel VBA錯誤處理代碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM