2017-02-23 15 views
1

私はさまざまな関数を呼び出すマクロを作成しています。これらの関数はすべて文字列を返し、結果をテキストボックスに表示します。Excel VBAエラー処理コード

私は良いエラー処理方法について読んでいますが、実際に多くのことを理解するのには苦労しています。私はこれについてどうやって行くのかについていくつかの意見を期待しています。

基本的に、エラー処理のためにこれまで実装してきた方法は、エラーハンドラを私のさまざまな関数の冒頭に置いて、その関数でエラーが発生した場合、ユーザに通知するが、他の機能を計算し続ける。

私の機能のそれぞれは任意の考えおよび/またはアドバイスははるかに高く評価されるだろう。この

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 

のようになります!

答えて

1

エラー処理(私の意見では)あなたが書いている種類のマクロ、それらを使っている人、そして誰がそれらをデバッグしているのか、本当に分かります。適切で徹底したエラー処理はベストプラクティスですが、デバッグ時に唯一のものであれば、カスタムエラーを必要とする唯一のものになります。これはあなたの組織によって変わりますが、必要なものになります。

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 

それはデバッグに便利です値のいくつかの種類を返すためにも最適です:言われて、あなたのコードのいくつかのメモこと

。シンプルな文字列を返すことは無意味ですが、エラーの種類を示す値を返す方が便利です。

+0

BrettDJの答えに対するコメントを参照してください。本当にありがとう!! –

2

は、あなたがこのために、デフォルトでのErrorHandlerのセクションを実行しないであろうと提案する、すなわちいずれか

  • は、有効な回答を得、その後
  • 機能を終了(以下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 
+0

恐ろしいが、そんなにありがとう!私は皆さんがどちらかというと私が物事をちょっと分かりやすく理解するのを助けてくれたので、ここでは「答え」となる一つのコメントを選ぶ必要がありません。私は "出口機能"の行について知りませんでした!今は事がもっと意味を成しています。 –

+0

問題はありません。すぐにクローズして応答してください。うれしかったのでうれしいよ! – brettdj

0

私はいつも何をしているか教えてあげます。私はマクロを終了するためのサブルーチンを持っています(私はexitPointと呼んでいます)、私はmain()と呼ばれるブール値を持つmainの最初にフローを制御するサブルーチンを持っています。 mainの最後をfalseに設定し、最後にexitPointを呼び出します。各サブルーチンまたは関数には、エラートラップがあり、ExitPointに制御を渡し、エラーが発生したルーチンを示す文字列を返します。exitPointは、badExitがtrueまたはfalseであるかどうかによって、一連のクリーンアップおよびエラーハンドリングコードを実行します。

私はサポートを提供しています。もしマクロであれば、もう一度それを見ない人に手渡していました。私はたくさんの防御的なコーディングと役に立つエラーメッセージをそこに入れています。エラー番号とそのための特定のメッセージを例えば与えます。

SOこのような何か(これは私は説明するために外のコードの多くをカットしてきた実際のマクロです):

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