A few Miscellaneous points that might have been missed, or not explicitly stated, or just added much later, to clarify, or revise things…..
around March 2023
..
On Error GoTo 0 “works” in both normal and aroused states .. but
An error handler can be replaced in normal state without using On Error GoTo 0
_ If we have an error handler enabled but not active, then we know that On Error GoTo 0 will take us back to the default VBA error handling situation. That code line removes or disables or unplugs the error handler. So just to be clear: On Error GoTo 0 will also remove the error handler from VBA’s memory of it even if the error handler is active and has put us in the aroused exception state/ given us an erecting. So if the On Error GoTo 0 is used in the aroused exception state, then after a resume or On Error GoTo -1 , we will go back to the default VBA error handling situation
What may not be obvious or intuitive is that in the inactive state, we can effectively replace the error handler with a new one by passing either a On Error Resume Next or On Error Resume LabelOrLineNumber error handler statement code line
Ending a code effectively does On Error GoTo -1 and On Error GoTo 0
As far as errors are concerned, then , at least theoretically , the ending of a routine removes the exception and returns error handling to the default VBA error handler. ( There are occasionally reports that after occurrence of errors, a full system restart may be advisable due to some bugs resulting in “something being left over” after an exception has been raised and theoretically cleared )
On Error GoTo -1 followed by a resume:
Probably not of much practical use: just an observation. As noted, the resumes effectively do a On Error GoTo -1 . There would not be a lot of use in including that in the error handling code section if you were then going to use any of the resumes.
But if you did then, curiously the resumes no longer take you to where you might expect: they all take you to the On Error GoTo -1.
In the demo code below, without the On Error GoTo -1 , any of the resumes will allow for another try of the formula, with a modified value of the variable Destrominator, which should work due to us adding a value which would mean that if it had been zero, then the addition of 1 will prevent it from being zero for the next try. However the On Error GoTo -1 causes any resume to go to the On Error GoTo -1 code line
Code:
Sub OnErrorGoTo_1resume()
On Error GoTo GetMilk ' Don't come back .. you're not welcome here .. stay away .. https://imgur.com/MKMjW0b .. FOB
'
Dim Destrominator As Long: Let Destrominator = 0
Dim RslTwat As Long
'
Try: Let RslTwat = 10 / Destrominator ' Will error due divide by zero, unless Destrominator is changed in error to a value other than zero
Let RslTwat = 10 / Destrominator ' for an attempt after Resume Next
' you never come here
Exit Sub
GetMilk:
Dim cnt
On Error GoTo -1 ' this causes any of the resumes to bring you here
Let cnt = cnt + 1 ' Count how many times I come here
MsgBox prompt:="This is the " & cnt & " time you were here" ' You come here three times
If cnt = 3 Then Exit Sub ' without this you loop infinitely
Let Destrominator = Destrominator + 1
Resume Try ' or Resume Next or Resume In this code these all have the same effect
End Sub
resumes “work” in the procedure that they are in.
If an error occurs in a called routine or function, then the call line is treated as a single line: the resuming will take place just before or just after the call line or at the specified line in the main code. To allow error handling within the function at the error occurrence, an error handler must be placed within function.
The first code below to demo how resume works in the case of a called routine , only has an error handler in the main code, but the error occurs in a called routine.
Resume Next is used at the end of the error handling code section in the main routine , which means we resume just after the called routine, and never get to the end of the called routine.
Code:
Sub ErrorInFunctionWithNoFunctionErrorHandler() ' Main routine
On Error GoTo Bed
'
Dim Rng As Range ' Preparing the variable for the range type object. I have not assigned a specific range to it yet.
Let Rng.Value = "AnyFink" ' Errors, as I have no range assigned to the variable Rng and so cannot give a non existant range a .Value
'
Call EmBed(0)
' You come here after Resume Next
Exit Sub
Bed:
MsgBox prompt:="An error occured in the main routine or the Called routine" & vbCrLf & "If the error was in the called routine then I will resume just after the Call line" & vbCrLf & " if using Resume Next"
Resume Next
End Sub
Sub EmBed(ByVal Destructinator As Long) ' Called routine
'
Dim RslTwat As Double
Let RslTwat = 10 / Destructinator
' You never come here
MsgBox prompt:="You will never see this", Title:="Purgatory"
End Sub
The code below includes an error handler in the called routine.
Note also that in this code I have included a second error in the main code after the Call of the called routine. Once the second routine is ended, the same error handler as that which handled the first error in the main routine, once again kicks in to handle the third overall error which is the second error in the main routine. I assume VBA somehow stores “on hold” , as they say “in the stack” , everything about the main routine, including any registered user error handler. It does this as the main routine is “put on hold” / pauses / “freezes”, at the time that the function starts. Then when the function ends ( in the first effectively code after the error and the second code at the normal function End ) the main code restarts “unfreezes” as it was left.
Code:
Sub GoInBed() ' main routine
Dim cnt As Long ' to count how many times I was at the error handler in this main routine
On Error GoTo Bed
'
Dim Rng As Range ' Preparing the variable for the range type object. I have not assigned a specific range to it yet.
Let Rng.Value = "AnyFink" ' Errors, as I have no range assigned to the variable Rng and so cannot give a non existant range a .Value
'
Call InBed(0)
' You come here after the error in this main code.
Let Rng.Value = "AnyFink" ' Errors, as I have no range assigned to the variable Rng and so cannot give a non existant range a .Value
'
MsgBox prompt:="You are leaving the main code now" & vbCrLf & "You used the error handler in the main code " & cnt & " times."
Exit Sub
Bed:
Let cnt = cnt + 1 ' Increase the count of how many times you were here
MsgBox prompt:="An error occured in the main routine of" & vbCrLf & Err.Description & vbCrLf & "The count of how many times you were here is " & cnt
Resume Next
End Sub
Sub InBed(ByVal Destructinator As Long) ' Called routine
On Error GoTo EmBed
Dim RslTwat As Double
Let RslTwat = 10 / Destructinator
' come here after error in this called routine
Exit Sub
EmBed:
MsgBox prompt:="You have an error in the Called routine of " & vbCrLf & Err.Description
Resume Next
End Sub
Bookmarks