VBA Nested On Error GoTo - excel

I have VBA code that is supposed to be nested error checking, but it does not. The code is psuedo as below. However, whenever an error occurs within an error (For instance, an error is tripped in the loop, goto SmallError occurs, and an error occurs in SmallError) The second GoTo is not used. The error then breaks the code.
Ex:
Error in Loop
GoTo SmallError
Error in SmallError
Code Breaks (Here code should GoTo FatalError)
Sub DoThings()
On Error GoTo SmallError
'Coding Happens
Do While(conditionhere)
'Looping things happen
GoTo LoopResume
SmallError:
source = Err.source
descript = Err.Description
On Error GoTo Fatal Error
'Small error processing happens
Resume LoopResume
FatalError:
source = Err.source
descript = Err. Description
On Error GoTo ExitError
'Fatal Error processing happens
ExitError:
Exit Sub
LoopResume:
count = count + 1
Loop
On Error GoTo FatalError
'Finishing code happens
End Sub

You can't use an On Error statement within an error handler. See e.g. this article that explains this.
What you CAN do however is to have a separate routine that handles the "regular error". This routine can have a "fatal error" handler. Your code would then look something like this:
(Edit: Edited the code to enable exit when there is a fatal error):
Sub DoThings()
On Error GoTo SmallError
Dim fatalExit As Boolean
'Coding Happens
Do While(conditionhere)
'Looping things happen
LoopResume:
count = count + 1
Loop
On Error Goto SmallError2
'Finishing code happens
Exit Sub
SmallError:
handleError Err.Source, Err.Description, fatalExit
If fatalExit Then
Exit Sub
Else
Resume LoopResume
End If
SmallError2:
handleError Err.Source, Err.Description, fatalExit
Exit Sub
End Sub
Private Sub handleError(ByVal source As String,ByVal description As String, ByRef fatalExit As Boolean)
On Error Goto FatalError
'Do "small error" handling here
Exit Sub
FatalError:
fatalExit = True
'Do "fatal error" handling here
End Sub

... you have Fatal Error in your Goto rather than FatalError, that won't get you to the right location...
Update your code to:
On Error GoTo FatalError

Related

Why does Err.Description remain empty in Excel / VBA error handling?

I am not able to access the error description (or error number) in Excel VBA error handling.
If I run the following code, the error description remains Empty:
Option Explicit
Sub TestError()
On Error GoTo ErrorHandler
Debug.Print 1 / 0
'Alternative: (Does not display error number either):
'Err.Raise 10000, , "Some error description"
ErrorExit:
Exit Sub
ErrorHandler:
On Error Resume Next
MsgBox Err.Description
Resume ErrorExit
End Sub
If I replace the Debug.Print 1 / 0 with an Err.Raise statement, the description remains empty as well.
However, if I remove the On Error GoTo ErrorHandler, the description and error number is shown as expected.
What am I doing wrong? Is there any other way to access the error description? Thank you!
The only problem here, is the presence of an On Error statement inside the error-handling subroutine: when that code runs, it's too late to tell VBA what to do "on error": it's here because there was an error.
Just remove the On Error Resume Next line, and you're good to go!
However, if I remove the On Error GoTo ErrorHandler, the description and error number is shown as expected.
What you're seeing is an unhandled runtime error, not the MsgBox you're expecting.

Excel VBA run time error is raised by the IDE while there is an error handler set

I have a weird error reported by a user of a VBA based application
and I wonder how this just possible that an error is raised by the VBA IDE considreing the line above is an error handler.
The code is the following. It creates a form of class frmCfgPrjctTm. I used to have some automation errors once in a while with weird message from the VBA IDE.
Run-time error '-2147418105 (800100007)':
Automation error
The object invoked has disconnected from its clients.
I use Excel 2016 32 bits on windows 7.
To work around the problem I had to implement a retry strategy to create the form. This explains the retry loop.
The error is raised on line mForm.Show vbModeless.
The error handler is set with instruction On Error GoTo ErrorHandler the line just before!
Private mForm As frmCfgPrjctTm
''
' U_CfgPrjctTm_OnOpen
Public Sub U_CfgPrjctTm_OnOpen()
Dim iRetry As Integer
iRetry = 0
If (mForm Is Nothing) Then
ErrorExit:
If (iRetry > 1) Then
Call U_UnlockTeam
GoTo ExitSub
End If
iRetry = iRetry + 1
Set mForm = New frmCfgPrjctTm
End If
On Error GoTo ErrorHandler
'>>>>>> the error occurs after this comment
mForm.Show vbModeless
ExitSub:
Exit Sub
ErrorHandler:
Debug.Print "***** Error trapped in U_CfgPrjctTm_OnOpen *****"
GoTo ErrorExit
End Sub
this post raises 2 questions but I am seeking for help or sharing for the following :
why an error is raised by the IDE while there is an error handler set ?
The answer to your question "why an error is raised by the IDE while there is an error handler set ?" is that you use error handling in a wrong way. Look at the following example
Option Explicit
Sub TestErrH()
Dim i As Long
i = 42
ErrorExit:
On Error GoTo ErrorHandler
Debug.Print 42 / i
Debug.Print 1 / 0
Exit Sub
ErrorHandler:
i = 0
GoTo ErrorExit
End Sub
The error handler will raise in the line Debug.print 1/0 and then the error handler will set i = 0 and jump back to the line debug.print 42/i. At that time the error handling is in your hands. You have to make sure the code is fail safe. The error handler will not again jump to the label ErrorHandler instead a run time error will pop up.

Nested Error Handling in Excel VBA

I am trying to run an error handler in an error handler in Excel VBA, but the second error handler never runs. It just gives me an error message. This is my code.
Sub func()
On Error GoTo error1
'code
Exit Sub
error1:
On Error GoTo error2
'code
Resume Next
error2:
'code
Resume Next
Basically, the function can run into 2 possible errors. I try to run the code and if it runs into an error, it tries to fix error1, and if that fails then error2 will fix it. The debug works for error1, but if error2 is the problem, the code will just fail.
This is how to throw two specific errors, based on a password char:
Sub Bar()
Dim password As String
On Error GoTo err1
password = "asd^"
If InStr(1, password, "&") Then Err.Raise 9990, Description:="No &!"
If InStr(1, password, "^") Then Err.Raise 9991, Description:="No ^!"
Exit Sub
err1:
Select Case Err.Number
Case 9990:
Debug.Print Err.Description
Case 9991:
Debug.Print Err.Description & ":("
End Select
End Sub
This is a possible way to do it using -1, as mentioned by #Darren Bartup-Cook in the comments. However, it is strongly not advisable, unless you do not want to write bad code for a reason of your own:
Sub Bar()
On Error GoTo err1
Debug.Print 0 / 0
Exit Sub
err1:
Debug.Print "err1"
On Error GoTo -1
On Error GoTo err2
Debug.Print 5 / 0
Debug.Print "Just testing..."
err2:
Debug.Print "err2"
End Sub
There are plenty of better ways to do it, if you want to catch 2 errors, try the following:
Sub Bar()
On Error GoTo err1
Debug.Print 4 / 0
On Error Resume Next
Exit Sub
err1:
Select Case Err.Number
Case 6:
Debug.Print "Overflow!"
Case 11:
Debug.Print "Division by 0 error!"
Case Else:
Debug.Print "Another error!"
End Select
End Sub
It catches Div/0 and Overflow and gives you info about them in the immediate window.

VBA On Error statement executes without error

I am using the simple code below to handle the error. When there is no error in why does the msgbox appears? How can I make the msgbox appear only when there is an error?
Sub Test()
On Error GoTo ErrHandler
On Error GoTo 0
'rest of the code is here
ErrHandler:
MsgBox "Please make sure the file exists in the current folder."
Exit Sub
End Sub
You should add an exit before the actual error handler and restore the default error handling after having shown the dialog. (The 1st on error goto 0 is probably misplaced).
Sub Test()
On Error GoTo ErrHandler
'rest of the code is here
'Exit before error handlers
Exit Sub
ErrHandler:
MsgBox "Please make sure the file exists in the current folder."
' Reset error handler
On Error GoTo 0
Exit Sub
End Sub

How to manage the no error case when handling errors in VBA? [duplicate]

This question already has answers here:
Why VBA goes to error handling code when there is no error?
(5 answers)
Closed last year.
I need to catch some VBA errors using the GoTo statement:
Sub mySub
On Error GoTo errorHandler:
Workbooks.Open("myWorkbook")
'
' Some Code
'
errorHandler:
MsgBox "ERROR"
End Sub
The problem is that when there is no error the errorHandler section is executed.
I found this discussion but the answer doesn't solve my issue.
I tried adding an Exit Sub statement as explained :
Sub mySub
On Error GoTo errorHandler:
Workbooks.Open("myWorkbook")
Exit Sub
'
' Some Code
'
errorHandler:
MsgBox "ERROR"
End Sub
In this case it exits the method when there is no error.
I also tried :
Sub mySub
On Error GoTo errorHandler:
Workbooks.Open("myWorkbook")
'
' Some Code
'
errorHandler:
MsgBox "ERROR"
Exit Sub
End Sub
But still the same issue: The errorHandler is executed even when no errors occur.
Just put Exit sub in.
Sub mySub
On Error GoTo myHandler:
Workbooks.Open("myWorkbook")
'
' Some Code
'
Exit sub
myHandler:
MsgBox "EROOR !"
err.clear
End Sub
Here's the pattern I prefer:
Sub SomeSub()
On Error GoTo ErrorLabel
'Code goes here
ExitLabel:
'Clean-up code, if any, goes here
Exit Sub
ErrorLabel:
'Error-handling code goes here
Resume ExitLabel
End Sub
Note that Resume clears the error. I like this pattern for a few reasons:
Habitually inserting the exit block before the error-handling block reduces the chance that I'll have the OP's problem of accidentally dropping into the error handler.
I use GoTo ExitLabel for any early exit from the Sub or Function. This way, I'm less likely to skip the clean-up code by accident. Example:
Sub SomeOtherSub()
Dim x As ResourceThatNeedsToBeClosed
Dim i As Long
On Error GoTo ErrorLabel
Set x = GetX
For i = 1 To 100
If x.SomeFunction(i) Then
GoTo ExitLabel
End If
Next
ExitLabel:
x.Close
ErrorLabel:
'Error-handling code goes here
Resume ExitLabel
End Sub
Public Sub MySub
On Error Goto Skip
' Some Codes
Skip:
If err.Number > 0 Then
' Run whatever codes if error occurs
err.Clear
End If
On Error Goto 0
End Su
I am having the exact same issue as you, and the solutions above did not work. They clearly didn't even see you wrote Exit Sub in already in 2 different places in your original post. No site online seems to understand that sometimes there won't be an error (if there was always going to be an error, why did you code it that way?), and when there isn't an error, you obviously don't want to Exit Sub. Nor do you want the myHandler to run when there isn't an error. DUH! This is the solution I cam up with which seems to work.
On Error GoTo ErrorHandler
'This is the thing I am trying to do...
Workbooks("SpreadSolver.xlsb").Activate
'If it works, great.
'Don't touch the error stuff and move on.
'I.e. go to the part that I know works (the rest of the macro)
GoTo ThisPartWorks
'If the thing I am trying to do doesn't work...
ErrorHandler:
MsgBox "Error: Please open Spread Solver and then run the macro."
'Only want to Exit Sub if there is an error.. duh.
Exit Sub
ThisPartWorks:
'the rest of your macro can go here...
'...
End Sub
I use an If statement, within the ErrorHandler, which will stop execution if there is no error. This is achieved by using the Err.Number (Err (object) number (e.g. Run-time error 9: Subscript out of range))
If Err.Number >= 1 Then
MsgBox ("Message")
End
Else: other code
End If
Exit Sub
This is what I have done. Works like a charm
Sub someProgram ()
On Error goto Handler:
x = 7/0
'Some code you wanna execute with or without error
Exit Sub
Handler:
'Write your handler here
Resume next 'After handling error, this line will help you resume the next line
End sub
Use below code in error handler section:
if err.number>0 the
' error handling goes here
else
' some code
end if
sub XYZ ()
on error goto label
"Write your macro"
Label:
If Err.Description <> "" Then
"your code if error occurs for eg:"
msgbox "Error Occured!"
Exit Sub
Else
"Your code when no error occurs for eg"
msgbox " Done."
End If
Exit Sub

Resources