Excel Macro : How to get notification when a VBA script stops execution - excel

I am running a macro on a remote PC which executes every 5 seconds throughout the day.
Now I want that if something goes wrong and the macro stops execution I should be informed or notified via an Email.
How can I do that?

Error handling.
Sub MySub()
On Error GoTo ErrorHandler
' Work done here...
' Screen for an expected error
If somethingWentWrong = True Then
Err.Raise Number:=myErrorNumber, Source:="MySub", _
Description:="This thing went wrong."
' Will now go to ErrorHandler
End If
' More work done here...
ExitProcedure:
On Error Resume Next
'Cleanup code goes here...
Exit Sub
ErrorHandler:
' If an error occurs (anticipated or not), the following will be executed.
Call SendEmailNotification( _
Recipient:="you#there.com", _
Subject:="Something went wrong.", _
Message:=Err.Number & vbCrLf & Err.Description & vbCrLf & Err.Source)
' Any other error handling goes here...
Resume ExitProcedure
End Sub
To send an e-mail, there are various solutions out there. Search for CDO, MAPI, Sockmail. Searching on those will give you examples for how to write your SendEmailNotification sub. Heads up: None of these are exactly straightforward.

You can add a mail send functionality within your error handling. If the machine the macro is being executed has Outlook properly set, I believe you can use ActiveWorkbook.SendMail.
If this PC doesn't have the Outlook set, you'll need to find out for a mail solution that fits your environment.
It would then looks like:
Sub MySub()
On Error GoTo ProcError
'Your stuff
ProcExit:
Exit Sub
ProcError:
ActiveWorkbook.SendMail "your.mail#yourdomain.com", "Application failed!"
Resume ProcExit
End Sub

Related

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.

Not able to handle runtime error 9 with on error go to [label]

I have the followin code. But the error does not get handled
Sub Some_sub()
Some code here
On Error GoTo resumeCode
If Workbooks("Some file.xlsm").ReadOnly Then
GoTo readOnlyError
End If
resumeCode:
On Error GoTo fileNotOpen
Workbooks("Some file.xlsm").Activate
some more code here
Exit Sub
fileNotOpen:
MsgBox "Error: Claims followup.xlsm is not open." & Chr(10) & Chr(10) &
"Open the file in read/write"
Exit Sub
End Sub
When I run debug mode it shows me this line: Workbooks("Some file.xlsm").Activate in yellow. Instead of handling the error and going to the label.
Within VBA under Tools -> Options -> General Tab: Break on Unhandled Errors active.
When I have the file open it runs the code like it should. When it is closed it does not handle the error.
What am I doing wrong?
Thanks in advance for your help
That's it. As I said in the comments, when an error occurs, and you handle it, you cannot setup a new On Error mechanism until you explicitly invoke the Resume keyword in any way.
One possible way to achieve it, if you dont want to change the flow of your routine, is just to add a label before your new On Error statement and Resume on it. Like this, for example:
Sub Some_sub()
' Some code ...
On Error GoTo resumeCode
If Workbooks("Some file.xlsm").ReadOnly Then
GoTo readOnlyError
End If
' Some more code ...
resumeCode:
Resume ResumeHere ' <---------------------------------------- Invoke Resume
ResumeHere: ' <------------------------------------- Add some label
On Error GoTo fileNotOpen
Workbooks("Some file.xlsm").Activate
Exit Sub
fileNotOpen:
msgBox "Error: Claims followup.xlsm is not open." & Chr(10) & Chr(10) & "Open the file in read/write"
Exit Sub
End Sub
You should be careful though, the keyword Resume will itself raise an error if the error status is blank and it is reached from normal flow, In that case you should put the error handling sections, each apart, in the end of your routine and resume at any labels within the normal flow from there. This is generally the usual approach.

Close a Workbook if opened

I would like an error handler to handle closing an Excel workbook that is not open.
I tried below code.
If Workbooks("Combo.xlsx").IsOpen Then
Workbooks("Combo.xlsx").Close SaveChanges:=False
Else: Resume Next
MsgBox "Error: (" & Err.Number & ") " & Err.Description, vbCritical
End If
This gives me an error message:
Run time Error: 9 Subscript Out of Range.
All you really need is
On Error Resume Next
Workbooks("Combo.xlsx").Close SaveChanges:=False
On Error Goto 0
You can ignore the error if there is no workbook open with that name.
I had the same problem that the On Error Resume Next didn't seem to work for this. My settings are only to break on unhandled errors so I can't understand why it keeps breaking when trying to close.
Anyway, I made this simple workaround subroutine to call when closing the workbook:
Private Sub closeWorkbookIfOpen(wb As Workbook)
On Error GoTo NotOpen
wb.Close
NotOpen:
End Sub
Not sure why the Resume Next doesn't work, but this seems to do the trick!

Simple Error handling in Excel VBA

I need a simple error handling code for my small macro, I have search the web but have nothing simple, seems to be all very complicated.
I down load sales reports in .txt form on a weekly basis, I run separate macro to do stuff and then add to a master page. Not every week do sales reports download as there may not have been sales for that particular region.
I need a simple error handler so that if it does not find the report, it moves to the next sub.
Any help appreciated
Sub MXM_POS()
Workbooks.OpenText Filename:="C:\Users\903270\Documents\Excel\MXMPOS*.txt"
‘Run macro code
Run ("DLK_POS")
End Sub
Here is a simple basic structure that you can expand on as needed:
Sub MXM_POS()
On Error GoTo ErrHandler
' code here
ExitSub:
' shutdown code here
Exit Sub
ErrHandler:
If Err.Number <> 0 Then
Dim mbr As VbMsgBoxResult
mbr = MsgBox( _
"Error #" & Err.Number & ": " & Err.Description & vbNewLine & _
"Would you like to continue?", vbExclamation Or vbYesNo)
If mbr = vbYes Then Resume ExitSub
Application.Quit
End If
End Sub
When I desire a stack dump I construct that within the Source property of the Err object using concatenation with a newline, and then only display the MsgBox result at the top of the calling stack, usually either the Event Handler that launched the code or the top-level macro invoked by the user.

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