Reputation: 445
Info: Thanks to Gary McGill I could improve the source code of my question.
In my current project I have got a sub which handles all errors. The following should happen:
The main point here is to find out in which line the error occured.
Private Sub Foo()
On Error GoTo ErrorHandling
a = 7 / 0
Exit Sub
ErrorHandling:
errorNumber = Err.Number
errorSource = Err.Source
errorDescription = Err.Description
errorHelpFile = Err.HelpFile
errorHelpContext = Err.HelpContext
On Error GoTo 0
Call HandleError(errorNumber, errorSource, errorDescription, errorHelpFile, errorHelpContext)
End Sub
Public Sub HandleError(errorNumber As Integer, errorSource As String, errorDescription As String, errorHelpFile As String, errorHelpContext As String)
Call SendMail(subject, body, mail)
Err.Raise errorNumber, errorSource, errorDescription, errorHelpFile, errorHelpContext
End Sub
But if I do it that way, the newly created error window simply points to the Err.Raise
line, not the actual line in which the error occured. Numbering the lines with an addon is no solution since my companies restrictions do not allow addons.
Are there any other possible solutions?
Edit
So instead of this, the line a = 7 / 0
should be highlighted
Edit 2
Sadly, this does not work:
Private Sub Foo()
On Error GoTo ErrorHandling
a = 7 / 0
Exit Sub
ErrorHandling:
...
Call HandleError(...)
GoTo 0
End Sub
Upvotes: 4
Views: 1453
Reputation: 27634
If you use error handling in VBA and want to get the line where the runtime error occured, you need Erl() - and for that you need line numbers, plain and simple.
Numbering the lines with an addon is no solution since my companies restrictions do not allow addons.
You should really ask them to rethink this policy. Programming VBA without MZ-Tools isn't fun, the Global Search and Procedure Callers functions alone are invaluable.
Of course you don't have line numbers on when developing, you add them when giving the code into production.
Upvotes: 1
Reputation: 418
You can use Stop
and Resume
to return to the line that threw an error however you couldn't use this in production code. What this will do is stop the code running, you can then use F8 to Step Into the next line of code which will return you to the line that raised the error.
Private Sub Foo()
On Error GoTo ErrorHandling
a = 7 / 0
Exit Sub
ErrorHandling:
errorNumber = Err.Number
errorSource = Err.Source
errorDescription = Err.Description
errorHelpFile = Err.HelpFile
errorHelpContext = Err.HelpContext
HandleError errorNumber, errorSource, errorDescription, errorHelpFile, errorHelpContext
Stop
Resume
End Sub
Public Sub HandleError(errorNumber As Integer, errorSource As String, errorDescription As String, errorHelpFile As String, errorHelpContext As String)
Call SendMail(Subject, body, mail)
End Sub
If you need something which will provide error reports from production code I don't believe there is a way to return the Line that threw the error without numbering your lines and using Erl
. The alternative to this would be to implement your own error raising with meaningful codes which would allow you to identify which part of your code caused an error.
Upvotes: 0
Reputation: 27516
There are a few issues with the code as (originally) posted:
On Error Goto 0
in HandleError
will clear the values of Err.Number
etc. All the On Error
variants effectively do an Err.Clear
. You could try saving those values at the start of the function for later use.HandleError
will raise an error, which in turn will go un-handled, and drop through to your ErrorHandling
error handler again, which will just loop? So actually, you might need to catch the various error values in the error handler, then disable the error handler, and then pass them to the HandleError
function as parameters. Maybe something like this:.
Public Sub Foo()
On Error Goto ErrorHandling
number = 7/0
Exit Sub
ErrorHandling:
errorNumber = Err.Number
errorSource = Err.Source
errorDescription = Err.Description
errorHelpFile = Err.HelpFile
errorHelpContext = Err.HelpContext
On Error Goto 0
Call HandleError(errorNumber, errorSource, errorDescription, errorHelpFile, errorHelpContext)
End Sub
Public Sub HandleError(errorNumber As Integer, errorSource As String, errorDescription As String, errorHelpFile As String, errorHelpContext As String)
Call SendMail(subject, body, mail)
Err.Raise errorNumber, errorSource, errorDescription, errorHelpFile, errorHelpContext
End Sub
I've not tried it, but it looks like it might work.
Upvotes: 3