PDA

View Full Version : Solved: Regarding On Error GoTo 0



Cyberdude
10-16-2005, 04:28 PM
If I use "On Error GoTo 0" at the end of an active error handler, am I correct in saying that it will "deactivate" that error handler? I know that it "disables" the error handler, whereas "Resume" deactivates and re-enables the error handler. Strangely, everything I've seen about "On Error GoTo 0" just says that it disables the error handler, but never says that it deactivates an active one if you terminate the error handling code with it.

Bob Phillips
10-16-2005, 04:53 PM
To quote help ...

On Error Goto 0 - Disables any enabled error handler in the current procedure.

This extract from help seems to cover it (at least to me)

Remarks

If you don't use an On Error statement, any run-time error that occurs is fatal; that is, an error message is displayed and execution stops.

An "enabled" error handler is one that is turned on by an On Error statement; an "active" error handler is an enabled handler that is in the process of handling an error. If an error occurs while an error handler is active (between the occurrence of the error and a Resume, Exit Sub, Exit Function, or Exit Property statement), the current procedure's error handler can't handle the error. Control returns to the calling procedure. If the calling procedure has an enabled error handler, it is activated to handle the error. If the calling procedure's error handler is also active, control passes back through previous calling procedures until an enabled, but inactive, error handler is found. If no inactive, enabled error handler is found, the error is fatal at the point at which it actually occurred. Each time the error handler passes control back to a calling procedure, that procedure becomes the current procedure. Once an error is handled by an error handler in any procedure, execution resumes in the current procedure at the point designated by the Resume statement.

Note An error-handling routine is not a Sub procedure or Function procedure. It is a section of code marked by a line label or line number.

Error-handling routines rely on the value in the Number property of the Err object to determine the cause of the error. The error-handling routine should test or save relevant property values in the Err object before any other error can occur or before a procedure that might cause an error is called. The property values in the Err object reflect only the most recent error. The error message associated with Err.Number is contained in Err.Description.

On Error Resume Next causes execution to continue with the statement immediately following the statement that caused the run-time error, or with the statement immediately following the most recent call out of the procedure containing the On Error Resume Next statement. This statement allows execution to continue despite a run-time error. You can place the error-handling routine where the error would occur, rather than transferring control to another location within the procedure. An On Error Resume Next statement becomes inactive when another procedure is called, so you should execute an On Error Resume Next statement in each called routine if you want inline error handling within that routine.

Note The On Error Resume Next construct may be preferable to On Error GoTo when handling errors generated during access to other objects. Checking Err after each interaction with an object removes ambiguity about which object was accessed by the code. You can be sure which object placed the error code in Err.Number, as well as which object originally generated the error (the object specified in Err.Source).

On Error GoTo 0 disables error handling in the current procedure. It doesn't specify line 0 as the start of the error-handling code, even if the procedure contains a line numbered 0. Without an On Error GoTo 0 statement, an error handler is automatically disabled when a procedure is exited.


Tony (Jollans) also wrote quite a bit about the same topic a few posts ago.


What is the problem that you are getting?

johnske
10-16-2005, 05:57 PM
If I use "On Error GoTo 0" at the end of an active error handler, am I correct in saying that it will "deactivate" that error handler? I know that it "disables" the error handler, whereas "Resume" deactivates and re-enables the error handler. Strangely, everything I've seen about "On Error GoTo 0" just says that it disables the error handler, but never says that it deactivates an active one if you terminate the error handling code with it.Hi Sid,

I could very well be wrong, but personally I think you're just getting bogged down in semantics here, the usage of "deactivate" and "disables" would seem to be synonymous with "cancel" in this particular case. Yes, it "deactivates", "disables", or "cancels that error handler

----------------------

Let's get right down to cases here. If you don't have some sort of error-handling procedure(s) in place any errors are immediately fatal.

Now your code may contain an action such as activating a range. That action will be fatal if you try to (say) activate row zero (or a negative row) - this will give an "Out of Range" error... So it's best to write your code so as to completely avoid that possibility - that's the very best type of error-handling procedure.

If you don't write your code to avoid the possibility you should at least include an error-trap such as On Error Resume Next, or, On Error Goto ErrHandler.
i.e. you set a TRAP to catch an error that has been raised and stop it from becoming fatal. The trap is usually a message of some form to alert the user that they need to do something else (or whatever). You can then either Exit the procedure or continue from another point.

i) If you choose for the procedure to end when an error has been raised, the "End" clears the error.

ii) If you choose to continue from another point in the code you should clear the error that has been raised with a "Resume" because any second error would then be fatal.

The Resume also re-sets the original error-trap, but if you don't expect any errors after this you can then cancel any further error-trapping with On Error Goto 0

---------------------

Now, let us say that we later get to another (later) part of the procedure that requires a workbook to be opened and this workbook or its' path is (maybe) non-existent (This will give a Run-time error 1004), however, for this case you may not want to just give a message as you did for the first error because you have designed a second error-handling procedure specifically to handle this particular error. So, because the On Error Goto 0 has cancelled the error trapping, you need to set another error-trap for this. (If you didn't use On Error Goto 0 earlier, the second error-trap will simply over-ride the first one anyway)

Does This Help?
John :)

Cyberdude
10-16-2005, 07:04 PM
To xld: Thanks, but I've essentially memorized the Help offering. It doesn't answer my question.
To John: Thanks for the writeup, but I think I understand what you are telling me.
Neither of you have addressed my question. It's a question of states. It matters whether error handling code is enabled, but inactive, or its disabled, but active. This shows up when a called macro has an error it can't handle. The system goes back through the caller chain looking for an error handler that is enabled, but inactive. If it can't find one, then a fatal error occurs.
Maybe I should rephrase the question and ask if disabling the handler code implies that the code is no longer active? No, I know that isn't true, because an active error handler is also disabled so that it can't handle another error if it occurs. The implication here is that On Error GoTo 0 does not inactivate the code.
Incidentally, I found an error about this in the Help, and I've got code to prove it. If you guys aren't interested in the states, that's OK, but I am.

Bob Phillips
10-17-2005, 01:22 AM
[QUOTE=Cyberdude]... I've essentially memorized the Help offering. It doesn't answer my question./QUOTE]

But you said

... If I use "On Error GoTo 0" at the end of an active error handler, am I correct in saying that it will "deactivate" that error handler ...

whereas Help says

... On Error Goto 0 - Disables any enabled error handler in the current procedure...

Subtly different statements. An active error handler is an enabled handler that is in the process of handling an error, so the On Error statement will not kick-in until the error is handled, where it will disable any enabled error handler in the current procedure.

Cyberdude
10-17-2005, 01:44 PM
whereas Help says

... On Error Goto 0 - Disables any enabled error handler in the current procedure...

Subtly different statements. An active error handler is an enabled handler that is in the process of handling an error, so the On Error statement will not kick-in until the error is handled, where it will disable any enabled error handler in the current procedure.
I guess that's where our understanding of the states is different. It is my understanding that an enabled error handler cannot be active. Said differently, an active error handler is disabled. Why? Because only an enabled/inactive error handler can be assigned to handle an error that occurs. If the error handler is in the process of handling an error (i.e., it is "active"), the system prevents it from handling another error that might occur by changing its status to disabled while it is active. A Resume statement changes the error handler back to enabled/inactive status so that it can handle the next error.


If a GoTo is executed the error handler which was previously enabled becomes active; when it is active it is no longer enabled. If another error occurs while an error handler is active, VBA will look up the calling chain for an enabled error handler and execute the first one it finds

This makes sense to me. I believe the Help is mistaken about this point. I've found one or two other errors in the Help on the subject. of error handling.

In the Help quote above it says that "On Error Goto 0 - Disables any enabled error handler in the current procedure." I have no argument with that. It doesn't say anything about the active/inactive status on the error handler. Hence, my question "am I correct in saying that it will "deactivate" that error handler?". In other words, does it
disable AND inactivate an active error handler. The answer affects how an active error handler in a calling procedure reacts when an unhandled error occurs in a procedure it calls. Jeez, this is sure hard to put into words.

TonyJollans
10-17-2005, 02:34 PM
My fault, I fear, but the terminology, like the whole sorry mess, is confusing.

I consider enabled to mean able to trap an error. When an error handler is active neither it, nor any other, is able to trap an error. That, however, isn't quite how Word help describes it; Word help doesn't (AFAIK) go into great detail about how one error handler can be enabled and inactive (yet not able to trap errors) whilst another is disabled and active.

Despite what I may have said to the contrary (and if I have I apologise - it's difficult enough without me getting it wrong) an On Error statement in an active error handler does have an effect on what happens when the active error handler is deactivated.

Cyberdude
10-17-2005, 03:05 PM
I think I may have the answer to my own question. The On Error GoTo 0 statement disables all error handling in the procedure. This says that if an error occurs anywhere including in a called procedure that doesn't handle the error, then error handling in the procdure that executes the On Error GoTo 0 is completely turned off. It will not handle any error within the procedure or a called procedure. That almost certainly is what the system is looking for when it searches up the calling chain for an available error handler. It probably asks the question "Do you have enabled error handler?"
If the answer is no, then it goes farther up the calling chain.
If the answer is yes, then it asks if that error handler is currently active. (Which doesn't make sense, since an active error handler is also disabled, so why ask the question??)
If the answer is yes, then, again, it keeps looking at other callers in the chain.
If the answer is no, then it lets that enabled/inactive error handler take care of the error.

The problem with this is that (according to my understanding) by definition, an enabled error handler cannot also be active. Said differently, if an active error handler is also enabled, then it is a candidate for handling a second error before it finishes handling the first one. That isn't allowed. An error handler can handle only one error at a time. Therefore, an active error handler must also be disabled (unable to respond to another error).

Furthermore, if the On Error GoTo 0 statement disables all error handling in the procedure, then it is moot whether or not an error handler is still active. The next error that occurs will not be handled.

I give up. No more question on error handling, guys.
Thanks for your help! :bug: