how to get error detail in VBA programming? - excel

How can I get error details like line number, error message in VBA.
It displays simple message like "Compile error", but does not show detail and line number of error.

How can I get error details like line number, error message in VBA.
Compile error will not let you compile the code and will directly take you to the line which has the error. For other runtime errors, you need to add line numbers to your code and then use ERL to get the line number. For example
Option Explicit
Sub Sample()
Dim i As Long
10 On Error GoTo Whoa
20 i = "Sid"
30 Debug.Print i
Whoa:
40 MsgBox Err.Description & ". Error on line " & Erl
End Sub
Tip: I use MZ-Tools which helps in inserting/removing line numbers. I think (I am not sure) rubberduck also does that.

If your VBA code doesn't contain line numbers, then VBA can not show it.
Purpose of displaying line number is to trace and resolve an error which you can handle using:
On Error GoTo ErrHandler
And then Error Handler Block
ErrHandler:
Refer this.

Compile error is different than runtime error.
The compile error will not let the application build and run and the line of code which causes the error is highlighted. On the other hand, runtime error is when the application runs but something unexpected happens which raises an error, a division by zero for exampe.
Once you have sorted out the compile error and the app runs, you can handle rutime errors like this:
Option Explicit
Sub Something()
On Error GoTo Trap
'your code here
Leave:
On Error GoTo 0
Exit Sub
Trap:
MsgBox Err.Number & " - " & Err.Description, vbCritical
Resume Leave
End Sub

Related

Excel VBA: On Error GoTo the Line Number Pointed by a Value [duplicate]

I'm trying to find the line number where my code crashes but many explanation on this site seems to complicated for my level.
My code is basically as below and I have no idea where it's breaking.
Sub1
Call function1
Call function2
End Sub
Other answers on this website seems to be just a short function. But I don't know where to call the function in my code or how to get a popup message. If I'm meant to put my sub1 code into their function, I don't know where either. Beginner here.
If your code doesn't have line numbers, then VBA has no way of giving you line numbers.
You can write VBA and make it look 1980-like to do this:
Sub1
On Error GoTo 100
10 Call Function1
20 Call Function2
90 Exit Sub
100 Debug.Print Err.Message & " on line " & Erl
End Sub
But you don't want to do that. Really, you don't need a line number.
You need smaller functions that handle runtime errors.
On Error GoTo ErrHandler
When a runtime error occurs, execution jumps to the line label called ErrHandler.
...
Exit Sub
ErrHandler: '<< the line label is denoted with a colon
What goes in that handler? If you're debugging, you might want to just Stop execution there and inspect your locals:
Stop
Then add Resume on the next line, and press F8 to step into it. Resume will return to the call that caused the error. If that's a function call, then you need to handle runtime errors in that function.
Make sure you never leave Stop and Resume instructions in production code:
Sub WhenWillThisEnd()
On Error GoTo ErrHandler
Debug.Print 42/0
Exit Sub
ErrHandler:
Resume 'jumps back to the line that caused the error
Resume Next 'resumes execution on the line right after the one that went boom
End Sub

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.

VBA: compile Error: expected function on err.Number

I've been trying to make this work and I just can't seem to figure it out. I have this test piece of code that I got from here.
Sub UsingErr()
On Error GoTo eh
Dim total As Long
total = "aa"
Done:
Exit Sub
eh:
Debug.Print "Error number: " & err.Number _
& " " & err.Description
End Sub
This is supposed to help me understand error management but when it's ran I get a: Compile Error: Expected Function or Variable on err.Number; it specifically highlights err.
Any help would be appreciated.
One minor thing I noticed in your code is the "err" is lower case. When I pasted your code into a blank workbook and ran it, Excel automatically capitalized "Err" in the code. As people mentioned in the comments, this probably means that you have something else open which has a conflicting definition of "err" in it. Try running your code without any other files open.

VBA Change error handling method during code execution

I have a macro, and part of the code is concerned with:
1) detecting if a column contains empty cells - if so filling them with some value
2) detecting if a column contains cells containing errors (such as N/A) and if so filling them with some value
Now if there are no error/empty cells in the column, the line that finds them gives a "Run-time error 1004 no cells were found".
I use error handling to skip this with GoTo.
Below is the code - the first error handling GoTo works perfectly, while the second gives the expected error, although there is Error handling GoTo set, that does not seem to work. Code with comments:
On Error GoTo EErrorOne
'depending on file I get, below line will generate error and code successfully skips to ErrorOne label
Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).SpecialCells (xlCellTypeBlanks)
' code to be skipped
Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).Select
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.Value = "Some Value"
' end of code to be skipped
EErrorOne:
' successfully skipped error line by now. Below line should set a new Error handling procedure.
On Error GoTo EErrorTwo
Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).Select
' Below line generates an error but does not skip to EErrorTwo label as detailed in the current Error handling procedure
Selection.SpecialCells(xlCellTypeFormulas, 16).Select
' code to be skipped
Selection.SpecialCells(xlCellTypeFormulas, 16).Select
Selection.Value = "Some Value"
' end of code to be skipped
EErrorTwo:
' Below line should reset error handling procedure to normal for subsequent handling of other errors:
On Error GoTo 0
It seems that error handling procedure (GoTo specific label) is ignored, and instead, an error message is shown as if the error handling was reset to GoTo 0. How do I skip the second error?
You're not clearing your errors when they occur, just trying to jump over them and the code is wondering what's going on with the error.
As Chip Pearson says on his site:
When the first error is raised, execution transfers to the line
following Err1:. The error hander is still active when the second
error occurs, and therefore the second error is not trapped by the On
Error statement
and continues with
The Resume statement instructs VBA to resume execution at a specified
point in the code. You can use Resume only in an error handling
block; any other use will cause an error. Moreover, Resume is the only
way, aside from exiting the procedure, to get out of an error handling
block. Do not use the Goto statement to direct code execution out of
an error handling block. Doing so will cause strange problems with
the error handlers.
http://www.cpearson.com/excel/errorhandling.htm
The ideal way is to avoid the error in the first place - check the workbook exists before opening it, check the sheet exists in the workbook before trying to reference it and if an error occurs jump out of the main body of the routine, deal with the error and then jump back in again.
As an example:
Sub Test()
On Error GoTo ERR_HANDLE
'.... code ....
FAST_EXIT:
'Code to tidy up, clear references etc before finishing.
Exit Sub
ERR_HANDLE:
Select Case Err.Number
Case 1004
'Code to resolve error
'.
'.
'Resume - clear error, jump back to line that caused it.
'Resume Next - clear error, jump to line after the one that caused error.
'Resume FAST_EXIT - clear error and go to line label.
Case 92 'Do something else to resolve error.
Case Else
End Select
End Sub
Inside error handling routines, it seems as though defining new error handling routines won't work, unless you clear the previously set error routine (https://excelmacromastery.com/vba-error-handling/):
'...
EErrorOne:
On Error GoTo -1 'Clears error trap flag
On Error GoTo EErrorTwo 'Reset error handling
'...
Edit after accepted:
As was discussed in the comments, On Error GoTo -1 clears the error trap flag, while Err.Clear only clears the error.
The code below illustrates this by creating two errors and trying to trap them.
On Error Goto -1 allows the second error to be trapped by the On Error GoTo NextLabel line and the code jumps to the label when the error occurs.
Err.Clear keeps the first error live, so when the second error occurs the error message is displayed rather than the code jumping to the label.
Sub ClearErr()
Dim x As Long
Dim y As Worksheet
'Jump to label when "Division by 0" occurs.
On Error GoTo ErrorLabel
x = 1 / 0
Debug.Print x
ErrorLabel:
'On Error GoTo -1 'Next error is trapped.
Err.Clear 'Untrapped error on y=Worksheets(1)
'Jump to label when "Object Variable not set" occurs.
On Error GoTo NextLabel
y = Worksheets(1)
Debug.Print y.Name
NextLabel:
End Sub

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.

Resources