Excel VBA - Using Error Traps where Another Routine is Called - excel

I have a module with several routines where each routine is run by a Call statement. I am trying to put Error Traps in each routine, but the the Error Traps are triggered even if there is no error.
Example
public sub Macro1()
*some DIM statements*
On Error GoTo Errhandler
*some code
*
errhandler: MsgBox "Error! Contact developer"
Exit Sub
Call AnotherRoutine
End Sub
I have tried moving the errhandler statement below the Call statement in case this was to do with the order of the coding, but I still got the same problem

Macro1 is not valid syntax. I think you meant End Sub after the error handler. Error handling isn't like handling conditions with an If. The label is simply a place in the code to jump to when there is an error.
You can wrap the message box in an If to test for an error or you can add an Exit Sub just above the label.
Public Sub Macro1()
On Error Goto ErrHandler
...
If Err > 0 Then MsgBox MYMESSAGE
End Sub

Related

Stop processing when there was an error in the previous of consecutively called subs

I have three subs that runs one after another, the subs are called DataTrimming, Pivot and Email.
Sub AllTogether()
DataTrimming
Pivot
Email
End Sub
I put an error handler inside Sub DataTrimming, so when there is an error, there will be an error message and exit the sub.
When I run sub AllTogether, it shows the error message when there is an error from Sub DataTrimming and it continues to run sub Pivot and sub Email.
Is there a way to exit sub AllTogether and not run the rest of the subs when an error occurs in sub DataTrimming?
Use an On Error statement to handle runtime errors and redirect execution to a line label:
Sub AllTogether()
On Error GoTo CleanFail
DataTrimming
Pivot
Email
CleanExit:
Exit Sub
CleanFail:
'break here and debug if needed; use Resume without a label to get back to the failing call.
Resume CleanExit
End Sub
If any of the called procedures have their own respective error-handling subroutines, then you'll want to re-throw the error in that procedure in order to have it handled in the scope of the AllTogether procedure, using Err.Raise like so:
Sub DataTrimming()
On Error GoTo CleanFail
'...do stuff...
CleanExit:
Exit Sub
CleanFail:
'...handle errors locally
Err.Raise Err.Number 'rethrows the same error with the same message
End Sub
Side note, the procedures have a temporal coupling issue because they are clearly side-effecting procedures that must be invoked in a particular specific order. To fix this, you would turn DataTrimming into a Function procedure that returns the data that the Pivot procedure needs to intake as parameters; similarly, making Pivot a function that returns data that the Email procedure needs as parameters, would remove the coupling and reduce (or remove!) reliance on global state - in the end it might look something like this:
Dim trimmedData As Object
Set trimmedData = DataTrimming
Dim pivotedData As Object
Set pivotedData = Pivot(trimmedData)
Email pivotedData
See this post for various ways of passing data around procedures without involving globals.
One way of doing this would be to change your three subs DataTrimming, Pivot and
Email to Functions instead, each of which returns a Boolean. Return True from each unless they hit an error, in which case return False.
In Altogether(), check the value that comes back from DataTrimming before continuing to Pivot (if False, Exit Sub) and the same for continuing from Pivot to Email.
Error Handling Among Procedures
You could rewrite your DataTrimming procedure as a function returning a boolean (e.g. True if successful) and use the boolean in the calling procedure (give it a better name though).
Option Explicit
Sub AllTogether()
If wasDataTrimmingSuccessful Then
Pivot
Email
End If
End Sub
Function wasDataTrimmingSuccessful() As Boolean
On Error GoTo clearError
' DataTrimming code in here
wasDataTrimmingSuccessful = True
ProcExit:
Exit Function
clearError:
'Debug.Print "Run-time error '" & Err.Number & "':" & Err.Description
Resume ProcExit
End Function

Code is getting into errorhandler even when the task is done without errors

I use a workbook that copy information from others workbooks, using the following Code:
Sub importarbens()
On Error GoTo ErrorHandler
{...}
ErrorHandler:
Workbooks(nomearq2).Close
MsgBox "Arquivo Incompatível"
Exit Sub
End Sub
But apparently my code always get in the ErrorHandler, even when the code runs withouth erros and after the task is done. The message in message box appears
When I disable the errorhandler the code works well
You need to add Exit Sub:
Sub importarbens()
On Error GoTo ErrorHandler
{...}
Exit Sub '<< end of the "happy path" for your code....
ErrorHandler:
Workbooks(nomearq2).Close
MsgBox "Arquivo Incompatível"
Exit Sub '<< Don't really need this since you're already
' at the end of the sub
End Sub

How to use error handling for my Excel VBA code

I am trying to add error handling for one of the code. I am assigning worksheet with specific name to the sheet objects, now I am trying to add OnError statements if in case user changes the names of sheets then code should gracefully exit the sub after displaying a message to correct the file names.
But the problem is as I provide the structure as below then the sub exit code always executes even if the file name is ok.
The problem is, as I provide the details in the structure as below then the sub exit code always executes even if the file name is ok.
Private Sub DoSomething()
On Error GoTo CleanFail
'...code...
CleanExit:
'cleanup code here
Exit Sub
CleanFail:
If Err.Number = 9 Then 'subscript out of range
Err.Clear
Resume Next
Else
MsgBox Err.Description
Resume CleanExit
End If
End Sub
On Error GoTo ErrorFailLoad
Set LoadSheet = Application.ActiveWorkbook.Worksheets("Load_Template")
ErrorExit:
End Sub
ErrorFailLoad:
MsgBox "Main File name must be Load_Template. Please change and re-run Macro"
Resume ErrorExit
On Error GoTo ErrorFailEquip
Set EquipSheet = Application.ActiveWorkbook.Worksheets("EQUIP")
ErrorExit:
End Sub
ErrorFailEquip:
MsgBox "Equipment File name must be EQUIP. Please change and re-run Macro"
Resume ErrorExit
I expect the code to just check if the file name is not available then just show error message and exit. Actual results is code exit even after correct file name.

How can I pause the execution of vba code when error?

I wish to pause the execution of my VBA code once an error appears, and continue the execution when corrected?! Because I have a very long execution, so it always goes from the beginning...
you need to use an error handler. Something like
On Error GoTo errorTrap
at the beginning of your code directly after your dims and other setup.
Then for the actual errortrap you would write this before the End Sub.
The whole thing would look like this.
Sub test()
Dim v As Variant, x As Integer 'etc etc
On Error GoTo errorTrap
'run your code here. An example is below
x = "hello" 'this will create an error since hello is not an integer
MsgBox "finished"
End 'ignore the error trap when done
errorTrap:
Debug.Print Err.Description
Stop 'stop here and figure out what is going on.
'any other code needed to fix the error
Resume Next
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