On Error Resume Next

J

Joanne

I've gone from being a total newbie, to an OK beginner programmer but error
handling has got me flummoxed. Where do I put an "On Error Resume Next"
statement? Just one in the whole module? And how exactly does it work? I
understand that it's supposed to skip the offending line of code and I assume
the code keeps executing but, oh I don't know - just a general explanation of
error handling would be greatly appreciated if someone had the time.

Thanks,
Joanne
 
J

Jonathan West

Joanne said:
I've gone from being a total newbie, to an OK beginner programmer but
error
handling has got me flummoxed. Where do I put an "On Error Resume Next"
statement? Just one in the whole module? And how exactly does it work?
I
understand that it's supposed to skip the offending line of code and I
assume
the code keeps executing but, oh I don't know - just a general explanation
of
error handling would be greatly appreciated if someone had the time.

Hi Joanne

If you want error handling, it must go in each routine where you want it.

The simplest form of error handling is On Error Resume Next.

What this does is ignore the line of code with the error, and resume
execution from the next line of code.

The other form of error handling within VBA is On Error Goto <label> The way
this works is as follows. You have the On Error Goto command in your
routine, usually (but not necessarily) at the start. When a line triggers an
error, execution jumps to the label. A very simple example of a routine with
this kind of error is as follows

Sub ShowCustomProp()

On Error Goto Errhandle

MsgBox ActiveDocument.CustomDocumentProperties("Test property")
Exit Sub

Errhandle:
Err.Clear
MsgBox "The 'Test property' custom property does not exist"
Resume Next

End Sub

What this does is display the value of the "Test property" custom document
property. If the property doesn't exist, an error is thrown, and execution
jumps to the Errhandle label. The error is cleared, a message box displayed
telling the user what has happened, and execution resumed from the line
below where the error occured.

The Exit Sub command ensures that the normal excution path of the macro
doesn't drop into the error handler.

There are a number of approaches to error handling, including the following

1. Write your code such that errors cannot occur.
2. Write routine-specific error handlers for the special cases where you
anticipate errors can occur
3. Use On Error Resume Next
4. Have a general-purpose error handler that you apply to every routine, and
tweak it for special cases as necessary.

There are almost as many opinions on good error handling as there are
experienced programmers, so don't regard my opion (or any other for that
matter) as being authorititave, but I will provide my opinion anyway.

In many short routines, option #1 is a perfectly valid way of programming.
For instance, if you are toggling the Bold status of the selection, then
that is such a short routine that an error handler is really not necessary.

Option #2 is a valid approach in cases such as the code sample I gave, where
you know what sort of errors might occur, and you write specific exception
handling routines for them.

Option #3 is also perfectly adequate in many cases. The code sample above
could equally well have been written as follows

Sub ShowCustomProp()
Dim strProp as String
On Error Resume Next

strProp = CStr(ActiveDocument.CustomDocumentProperties("Test property"))
If Len(strProp) > 0 Then
MsgBox strProp
Else
MsgBox "The 'Test property' custom property does not exist"
End If

End Sub

Option #4 is in my opinion unnecessary for most projects. If you are
developing a project, and you hit an unexpected error, then about the most
helpful thing that can happen is what happens by default - execution stops
and the error code and description is displayed. For many routines, adding
an error handler is only useful if you are getting paid for each line of
code you write irrespective of whether it actually does anything. If an
error handler is actually required for a particular routine, then it is
probably required to do something quite specific, in which case you are back
into the territory of option #2.

Remember that error handling is not primarily for the purpose of debugging,
it is for handing cases where you deliberately allow individual lines of
code to run which will trigger an error in certain circumstances. In other
words, error handling is a program flow control mechanism just as valid as
If-Then or Do-Loop (though generally used less often than them). As such is,
it misleadingly named. I prefer to describe it as "exception handling". But
since Error is the keyword used in VBA, I'm always going to be fighting a
losing battle on that front!
 
G

Greg

Jonathan.

Thanks. Can you elaborate a little on the use of On Error GoTo 0 and
the On Error Resume "Some Label"

I have seen and used both, but I don't really understand what is
happening.
 
J

Jay Freedman

Greg said:
Jonathan.

Thanks. Can you elaborate a little on the use of On Error GoTo 0 and
the On Error Resume "Some Label"

I have seen and used both, but I don't really understand what is
happening.

Hi Greg,

On Error GoTo 0 means "turn off error handling". After that line executes,
it's just as if you had never put in any On Error statement. You might use
this in a routine where you're doing several things, and you want to
error-trap only one of them. You'd put an On Error Resume Next or an On
Error GoTo <label> before the code of interest, and On Error GoTo 0 after
that part. The rest of the macro would have the default behavior, stopping
with an error message generated by VBA.

There is no such syntax as On Error Resume <label>. If this is what you
need, use the keyword GoTo instead of Resume.

Just to clarify a couple of points: A GoTo or On Error GoTo can send
execution back toward the beginning of the macro, not just toward the end.
And you can use line numbers (gasp!) instead of labels -- although you risk
being mistaken for a dinosaur if you do. This still works, even in Word 2003
VBA:

Sub foo()
On Error GoTo 20

Documents.Open "C:\foo.doc"
10 Exit Sub

20 MsgBox "no such file"
GoTo 10
End Sub

If it makes your eyes hurt, now you know why the old original BASIC language
died. :)
 
G

Greg Maxey

Jay,

Yes I was wrong. I meant Resume "Some Label" The replace with Autotext
Macro that Graham Mayor and I worked on uses a line:

Resume Get Input

http://www.gmayor.com/Autotext_replace.htm

I don't remember who it was, but about a year ago I was advised to avoid
GoTo statements in my code. That same person told me to use Resume "Some
Label" instead of GoTo "SomeLabel." Both seem to move forward or backward
in the macro. I wonnder if there is any inherent downside to using either.


Thanks for the post.
 
J

Jonathan West

Greg Maxey said:
Jay,

Yes I was wrong. I meant Resume "Some Label" The replace with Autotext
Macro that Graham Mayor and I worked on uses a line:

Resume Get Input

http://www.gmayor.com/Autotext_replace.htm

I don't remember who it was, but about a year ago I was advised to avoid
GoTo statements in my code. That same person told me to use Resume "Some
Label" instead of GoTo "SomeLabel." Both seem to move forward or backward
in the macro. I wonnder if there is any inherent downside to using
either.

Hi Greg


On Error Goto 0 means "from here on, there is no error handling"

On Error Resume Label is not valid syntax.

Resume can only be used in an error handler, and has the following
variations

Resume 'returns to the line that caused the error
'and executes it again

Resume Next 'returns to the line immediately after the
'one that caused the error


Resume <label> 'continues execution from the named label.


The last is equivalent to a Goto statement, but is used only within an error
handler.

The issue of avoiding Goto is treated by some with a religious fervour that
the matter really doesn't deserve. The point is quite simple. In most cases,
using Do-Loop, If-Then, Select Case or othere structured branching
mechanisms gives you code that is easier to read, particularly if you indent
it consistently. Code that is easy to read is easy to debug. Goto statements
don't lend themselves to indented code so the general preference is to avoid
them.

But there are times when the program flow is such that judicious use of Goto
is appropriate. For instance, if you are inside two nested For-Next loops
and you want to exit the outer one. Using Exit For will only exit the inner
loop. You could convert the outer loop to a Do-Loop structure instead of a
For-Next structure, and then use Exit Do to get out. But there is a cost in
readability, and you may return to the code months later and wonder "why on
earth did I code that outer loop as a Do-Loop instead of For-Next?" A Goto
statement pointing to a label below the end of the outer loop is by far the
simpler solution, and perfectly readable if you comment it stating the
purpose of the jump and indicating where the destination is.

Of course, in VBA, Goto is the *only* means of directing program flow for
error-handling. So you must use it if you need error handling.
 
J

Jay Freedman

Hi Greg
[snip]

The issue of avoiding Goto is treated by some with a religious fervour that
the matter really doesn't deserve. The point is quite simple. In most cases,
using Do-Loop, If-Then, Select Case or othere structured branching
mechanisms gives you code that is easier to read, particularly if you indent
it consistently. Code that is easy to read is easy to debug. Goto statements
don't lend themselves to indented code so the general preference is to avoid
them.

The "religious fervor" seems to have started with a 1968 paper by
Edsger Dijkstra, one of the most respected computer scientists of the
20th century, titled "Go To Statement Considered Harmful"
(http://www.acm.org/classics/oct95). A lot of people at the time
thought he was delivering Gospel, and tried to stamp out GoTo
completely.
But there are times when the program flow is such that judicious use of Goto
is appropriate. For instance, if you are inside two nested For-Next loops
and you want to exit the outer one. Using Exit For will only exit the inner
loop. You could convert the outer loop to a Do-Loop structure instead of a
For-Next structure, and then use Exit Do to get out. But there is a cost in
readability, and you may return to the code months later and wonder "why on
earth did I code that outer loop as a Do-Loop instead of For-Next?" A Goto
statement pointing to a label below the end of the outer loop is by far the
simpler solution, and perfectly readable if you comment it stating the
purpose of the jump and indicating where the destination is.

It did become clear, as the fuss over Dijkstra's pronouncement
subsided, that there are some situations where GoTo is useful, but
they're comparatively rare in most block-oriented languages. In many
years of programming in C++, I think I found one case where it was
warranted.
Of course, in VBA, Goto is the *only* means of directing program flow for
error-handling. So you must use it if you need error handling.

This is one of the reasons VBA is often considered a "toy" language.
"Real" languages have gone to structured exception handling (try-catch
blocks, multilevel exception passing, and exception classes).

But there are some (including me) who feel that the more Word's macros
become "real programming", the less accessible they become to the mass
of users who need them. If you have to study programming theory for a
couple of years before you can write a crummy macro, what use are
they?
 
G

Greg Maxey

Thanks Jay. The support and instruction that you and your peers provide are
outstanding.

--
Greg Maxey/Word MVP
A Peer in Peer to Peer Support

Jay said:
Hi Greg
[snip]

The issue of avoiding Goto is treated by some with a religious
fervour that the matter really doesn't deserve. The point is quite
simple. In most cases, using Do-Loop, If-Then, Select Case or othere
structured branching mechanisms gives you code that is easier to
read, particularly if you indent it consistently. Code that is easy
to read is easy to debug. Goto statements don't lend themselves to
indented code so the general preference is to avoid them.

The "religious fervor" seems to have started with a 1968 paper by
Edsger Dijkstra, one of the most respected computer scientists of the
20th century, titled "Go To Statement Considered Harmful"
(http://www.acm.org/classics/oct95). A lot of people at the time
thought he was delivering Gospel, and tried to stamp out GoTo
completely.
But there are times when the program flow is such that judicious use
of Goto is appropriate. For instance, if you are inside two nested
For-Next loops and you want to exit the outer one. Using Exit For
will only exit the inner loop. You could convert the outer loop to a
Do-Loop structure instead of a For-Next structure, and then use Exit
Do to get out. But there is a cost in readability, and you may
return to the code months later and wonder "why on earth did I code
that outer loop as a Do-Loop instead of For-Next?" A Goto statement
pointing to a label below the end of the outer loop is by far the
simpler solution, and perfectly readable if you comment it stating
the purpose of the jump and indicating where the destination is.

It did become clear, as the fuss over Dijkstra's pronouncement
subsided, that there are some situations where GoTo is useful, but
they're comparatively rare in most block-oriented languages. In many
years of programming in C++, I think I found one case where it was
warranted.
Of course, in VBA, Goto is the *only* means of directing program
flow for error-handling. So you must use it if you need error
handling.

This is one of the reasons VBA is often considered a "toy" language.
"Real" languages have gone to structured exception handling (try-catch
blocks, multilevel exception passing, and exception classes).

But there are some (including me) who feel that the more Word's macros
become "real programming", the less accessible they become to the mass
of users who need them. If you have to study programming theory for a
couple of years before you can write a crummy macro, what use are
they?
 
J

Jezebel

A further clarification: On error Goto 0 switches off error handling only in
the current procedure. You might still have a current error handler in a
higher-level procedure. This is significant when you get to the next level
of sophistication in your coding, which is when you raise your own errors:

Err.Raise Number:=vbObjectError, Description:="This is my own error"

There are times when you don't want to handle the error in a low-level
function, but pass it back up the line to a top-level calling function.





Greg Maxey said:
Thanks Jay. The support and instruction that you and your peers provide
are outstanding.

--
Greg Maxey/Word MVP
A Peer in Peer to Peer Support

Jay said:
Hi Greg
[snip]

The issue of avoiding Goto is treated by some with a religious
fervour that the matter really doesn't deserve. The point is quite
simple. In most cases, using Do-Loop, If-Then, Select Case or othere
structured branching mechanisms gives you code that is easier to
read, particularly if you indent it consistently. Code that is easy
to read is easy to debug. Goto statements don't lend themselves to
indented code so the general preference is to avoid them.

The "religious fervor" seems to have started with a 1968 paper by
Edsger Dijkstra, one of the most respected computer scientists of the
20th century, titled "Go To Statement Considered Harmful"
(http://www.acm.org/classics/oct95). A lot of people at the time
thought he was delivering Gospel, and tried to stamp out GoTo
completely.
But there are times when the program flow is such that judicious use
of Goto is appropriate. For instance, if you are inside two nested
For-Next loops and you want to exit the outer one. Using Exit For
will only exit the inner loop. You could convert the outer loop to a
Do-Loop structure instead of a For-Next structure, and then use Exit
Do to get out. But there is a cost in readability, and you may
return to the code months later and wonder "why on earth did I code
that outer loop as a Do-Loop instead of For-Next?" A Goto statement
pointing to a label below the end of the outer loop is by far the
simpler solution, and perfectly readable if you comment it stating
the purpose of the jump and indicating where the destination is.

It did become clear, as the fuss over Dijkstra's pronouncement
subsided, that there are some situations where GoTo is useful, but
they're comparatively rare in most block-oriented languages. In many
years of programming in C++, I think I found one case where it was
warranted.
Of course, in VBA, Goto is the *only* means of directing program
flow for error-handling. So you must use it if you need error
handling.

This is one of the reasons VBA is often considered a "toy" language.
"Real" languages have gone to structured exception handling (try-catch
blocks, multilevel exception passing, and exception classes).

But there are some (including me) who feel that the more Word's macros
become "real programming", the less accessible they become to the mass
of users who need them. If you have to study programming theory for a
couple of years before you can write a crummy macro, what use are
they?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top