VBA Excel Error Handling - especially in functions - Professional Excel Development Style

后端 未结 3 577
盖世英雄少女心
盖世英雄少女心 2020-12-28 22:26

I got the book \"Professional Excel Development\" by Rob Bovey and it is opening up my eyes.

I am refitting my code with error handling. However, there is a lot I do

3条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-28 22:49

    That is an amazing book by Rob.

    My two cents of Error Handling (Either for a procedure or a Function) is based on KISS (Keep it simple Silly)

    Understand what do you want from your error handler?

    This is usually what I want/expect from my error handler...

    1. Line on which the error happened
    2. Error Number
    3. Error Message
    4. Reset Events if applicable

    Lets break the above. As you are by now already aware how your error handler looks like, Consider this example.

    Sub Sample()
        Dim i As Integer, j As Integer
    
        On Error GoTo Whoa
    
        Application.ScreenUpdating = False
    
        i = 1111111111
    
        For j = 1 To i
            Debug.Print ThisWorkbook.Sheets(1).Cells(i, 1).Value
        Next i
    
    LetsContinue:
        Exit Sub
    Whoa:
        MsgBox Err.Description
        Resume LetsContinue
    End Sub
    

    This is a very basic error handler but it's of very less help to me. So let's now tweak it to make it more useful. If you run the above code you get an error message like shown in the screenshot below and if you notice, it's not of much help.

    enter image description here

    Let's now tackle all the points that I mentioned in the Logic above

    1. Line on which the error happened

    There is a property called ERL which very few people are aware of. You can actually use it to get the line number of the code where the error happened. For that you have to ensure you number your code. See this example.

    Sub Sample()
        Dim i As Integer, j As Integer
    
    10      On Error GoTo Whoa
    
    20      Application.ScreenUpdating = False
    
    30      i = 1111111111
    
    40      For j = 1 To i
    50          Debug.Print ThisWorkbook.Sheets(1).Cells(i, 1).Value
    60      Next j
    
    LetsContinue:
    70      Exit Sub
    Whoa:
    80      MsgBox Erl
    90      Resume LetsContinue
    End Sub
    

    When you run the above code, you will get this

    enter image description here

    So now I know that the error happened on Line 30 which is i = 1111111111

    Moving on to next

    1. Error Number
    2. Error Message

    The error number and the error message can be retrieved from Err.Number and Err.Description respectively. So now let's combine Erl, Err.Number and Err.Description

    Check this example

    Sub Sample()
        Dim i As Integer, j As Integer
    
    10      On Error GoTo Whoa
    
    20      Application.ScreenUpdating = False
    
    30      i = 1111111111
    
    40      For j = 1 To i
    50          Debug.Print ThisWorkbook.Sheets(1).Cells(i, 1).Value
    60      Next j
    
    LetsContinue:
    70      Exit Sub
    Whoa:
    80      MsgBox "The Error Happened on Line : " & Erl & vbNewLine & _
               "Error Message : " & Err.Description & vbNewLine & _
               "Error Number : " & Err.Number
    90      Resume LetsContinue
    End Sub
    

    When you run this code, you will get something like this.

    enter image description here

    You can choose to further customize the Error Message to make it more user friendly. For example

    '~~> Message you want to deliver to the user in case the error happens
    Const sMsg As String = "Please take a screenshot of this message and contact the developer for a resolution"
    '~~> Title of your message box
    Const sTitle As String = "Oopsie Daisies"
    
    '~~> Change the above as applicable
    
    Sub Sample()
        Dim i As Integer, j As Integer
    
    10      On Error GoTo Whoa
    
    20      Application.ScreenUpdating = False
    
    30      i = 1111111111
    
    40      For j = 1 To i
    50          Debug.Print ThisWorkbook.Sheets(1).Cells(i, 1).Value
    60      Next j
    
    LetsContinue:
    70      Exit Sub
    Whoa:
    80      MsgBox "The Error Happened on Line : " & Erl & vbNewLine & _
               "Error Message : " & Err.Description & vbNewLine & _
               "Error Number : " & Err.Number & vbNewLine & vbNewLine & _
               sMsg, vbCritical, sTitle
    90      Resume LetsContinue
    End Sub
    

    enter image description here

    On to the next one :)

    Reset Events if applicable

    When you are working with events and an error occurs, if there is no error handling, the code breaks. Unfortunately that doesn't reset the events. It is very important that you reset the events in the Error handler.

    If you notice in the above code we are setting the Application.ScreenUpdating = False. When the code breaks, that event doesn't get reset. You will have to handle that in the Error handler LetsContinue in this case. See this example.

    '~~> Message you want to deliver to the user in case the error happens
    Const sMsg As String = "Please take a screenshot of this message and contact the developer for a resolution"
    '~~> Title of your message box
    Const sTitle As String = "Oopsie Daisies"
    
    '~~> Change the above as applicable
    
    Sub Sample()
        Dim i As Integer, j As Integer
    
    10      On Error GoTo Whoa
    
    20      Application.ScreenUpdating = False
    
    30      i = 1111111111
    
    40      For j = 1 To i
    50          Debug.Print ThisWorkbook.Sheets(1).Cells(i, 1).Value
    60      Next j
    
    LetsContinue:
    70      Application.ScreenUpdating = True
    80      Exit Sub
    Whoa:
    90      MsgBox "The Error Happened on Line : " & Erl & vbNewLine & _
               "Error Message : " & Err.Description & vbNewLine & _
               "Error Number : " & Err.Number & vbNewLine & vbNewLine & _
               sMsg, vbCritical, sTitle
    100     Resume LetsContinue
    End Sub
    

    Like Philippe, I also strongly suggest that you use MZ-Tools for VBA. I have been using it now for donkey years...

    Hope this helps.

提交回复
热议问题