Simple code but error trap fails?

User avatar
ErikJan
5StarLounger
Posts: 1185
Joined: 03 Feb 2010, 19:59
Location: Terneuzen, the Netherlands

Simple code but error trap fails?

Post by ErikJan »

Getting a "run-time error '53' - "File not found" in the "GetAttr" line. But I'm trapping the error...??

This is a simplified version of a tool that needs to search files with a certain extension (pref. on all local disks). The code below is only scanning (so safe to test). Got this off the Internet and it seems to make sense. I'm open to a better (and faster code as well)

Code: Select all

Option Explicit

Sub loopAllSubFolderSelectStartDirectoryS()
    Call LoopAllSubFoldersS("c:\")
End Sub
'
Private Sub LoopAllSubFoldersS(ByVal FolderPath As String)
    Dim FileName As String, FullFilePath As String
    Dim NumFolders As Long, Folders() As String, i As Long
    '
    If Right(FolderPath, 1) <> "\" Then FolderPath = FolderPath & "\"
    On Error Resume Next
    FileName = Dir(FolderPath & "*.*", vbDirectory)
    On Error GoTo 0
    '
    While Len(FileName) <> 0
        If Left(FileName, 1) <> "." Then
            FullFilePath = FolderPath & FileName
            On Error GoTo Skip
            If (GetAttr(FullFilePath) And vbDirectory) = vbDirectory Then
                ReDim Preserve Folders(0 To NumFolders) As String
                Folders(NumFolders) = FullFilePath
                NumFolders = NumFolders + 1
            Else
                'Debug.Print FolderPath & FileName
            End If
Skip:
            On Error GoTo 0
        End If
        FileName = Dir()
    Wend
    '
    For i = 0 To NumFolders - 1
        LoopAllSubFoldersS Folders(i)
    Next
End Sub


User avatar
HansV
Administrator
Posts: 78237
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: Simple code but error trap fails?

Post by HansV »

That's a weird error - VBA should trap it.
Try using FileSystemObject instead:

Code: Select all

Private fso As Object
Private Folders() As String
Private NumFolders As Long

Sub LoopAllSubFolderSelectStartDirectoryS()
    Set fso = CreateObject("Scripting.FileSystemObject")
    NumFolders = 0
    Erase Folders
    Call LoopAllSubFoldersS("C:\")
    Debug.Print "Total number of folders: " & UBound(Folders)
End Sub

Private Sub LoopAllSubFoldersS(ByVal FolderPath As String)
    Dim fld As Object
    Dim sfl As Object
    Debug.Print FolderPath
    NumFolders = NumFolders + 1
    ReDim Preserve Folders(1 To NumFolders)
    Folders(NumFolders) = FolderPath
    Set fld = fso.GetFolder(FolderPath)
    On Error Resume Next
    For Each sfl In fld.Subfolders
        Call LoopAllSubFoldersS(sfl.Path)
    Next sfl
End Sub
The On Error Resume Next is needed to prevent errors for (sub)folders you don't have permission to read.
Best wishes,
Hans

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

Re: Simple code but error trap fails?

Post by Doc.AElstein »

The way you are doing it, VBA will trap the first error, only...

some info about Error handling in VBA might help you.. ..

When an error occurs, VBA goes into a certain state, often called an exception state. In this state VBA does things a bit differently. For one thing it won’t respond to anymore Error handling statement. Any more errors will be handled in the default way.
Your code line ( Error handling statement ) On Error GoTo Skip tells VBA to go to Skip when an error occurs, so it does that. But after that it is in this new state and so wont take any notice of your code line ( Error handling statement ) On Error GoTo Skip after the occurrence of the first error

I suppose you could say that you are trapping only the first error.

All 3 of these macros will get you as far as 2

Code: Select all

Sub TrapFirstError()
On Error GoTo Skip
Dim Cnt As Long, Oops As Double
    For Cnt = 1 To 10
     MsgBox prompt:=Cnt
     Let Oops = 1 / 0
Skip:
    Next Cnt
End Sub
Sub TrapFirstError2()
On Error GoTo Skip
Dim Cnt As Long, Oops As Double
    For Cnt = 1 To 10
     MsgBox prompt:=Cnt
     Let Oops = 1 / 0
Skip:
    On Error GoTo 0
    Next Cnt
End Sub

Sub TrapFirstError2b()
Dim Cnt As Long, Oops As Double
    For Cnt = 1 To 10
     On Error GoTo Skip
     MsgBox prompt:=Cnt
     Let Oops = 1 / 0
Skip:
    On Error GoTo 0
    Next Cnt
End Sub
They get you as far as the second loop, but you are then in the exception state.
On Error GoTo 0 doesn’t help you much , because that disables your error handling statement. But it does not clear off the exceptional state thing


This will get you 10

Code: Select all

Sub TrapAllErrors()
On Error GoTo Skip
Dim Cnt As Long, Oops As Double
    For Cnt = 1 To 10
     MsgBox prompt:=Cnt
     Let Oops = 1 / 0
Skip:
    On Error GoTo -1
    Next Cnt
End Sub
On Error GoTo -1 does clear off the exceptional state thing. Note also, my error handling statement is outside the loop. But it works every time because On Error GoTo -1 does not disable any error handler that you make

This next would still only get you 2, because I disabled the error handler as well

Code: Select all

Sub TrapAnError() ' get as far as 2
On Error GoTo Skip
Dim Cnt As Long, Oops As Double
    For Cnt = 1 To 10
     MsgBox prompt:=Cnt
     Let Oops = 1 / 0
Skip:
    On Error GoTo -1
    On Error GoTo 0
    Next Cnt
End Sub
( By the way, I am not sure where you got your macro from , but an awful lot of Blog sites still make this mistake on their coding, and they never noticed that they were only trapping an error once, when they thought they were trapping any amount of them. I expect they test the code in a case of when they are expecting an error , so when it works for that they assume it works for any subsequent error as well... )

Possibly the short answer for you is to change your On Error GoTo 0 to On Error GoTo -1. You can put your error handling statement On Error GoTo Skip outside the loop if you like, but you don’t have to.
Best is to use a macro with as little error handling as possible, IMO, as there are a few awkward things like this you come across…

Alan



Ref
https://web.archive.org/web/20180101022 ... ent-141631
Last edited by Doc.AElstein on 06 Jan 2021, 11:55, edited 4 times in total.
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
ChrisGreaves
PlutoniumLounger
Posts: 15498
Joined: 24 Jan 2010, 23:23
Location: brings.slot.perky

Re: Simple code but error trap fails?

Post by ChrisGreaves »

ErikJan wrote:
18 Dec 2020, 18:34
Getting a "run-time error '53' - "File not found" in the "GetAttr" line. But I'm trapping the error...??
Me? I'd put my money on the "On Error" solutions.

But I'd also put a side-bet on something else.:-

I have a zillion MP3 tracks some of which are downloaded from YouTube.
I build an array of filenames (using FSO), and then process the files one by one as I loop through the array,
But in that loop, when the code comes across a file path and/or name with an illegal character, I get a "file not found" type of error.

It is a source of annoyance to me that Windows will allow me to download or copy a file with an illegal character in the name and say nothing about it.
For years Windows will allow me to back up that folder/file to a backup drive and not complain.
Windows allows me to play back the file in WinAmp, and WinAmp does not complain.
Some of the files were d/l as MP4 videos and then converted with "Free M4a to MP3 Converter", still no problem.

But when the day comes that I want to DO something with the file, I loop through the Windows-delivered array and get a "file not found" sort of error - because an umlaut or other diacritical mark (did I get that right?) was sitting there in the path/file name all this time.

Cheers
Chris
An expensive day out: Wallet and Grimace

User avatar
ErikJan
5StarLounger
Posts: 1185
Joined: 03 Feb 2010, 19:59
Location: Terneuzen, the Netherlands

Re: Simple code but error trap fails?

Post by ErikJan »

Oh... that story on "on error goto -1" is really cool and insightful. I had no idea and always use "goto 0".

Thank you so much (and also thans to Hans of course for the alternative code that did not seem to generate errors in the first place).

PS. The only thing I miss is the last example with "goto -1" and then "goto 0". Why does that stop @ 2, wouldn't -1 clear everything?

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

Re: Simple code but error trap fails?

Post by Doc.AElstein »

ErikJan wrote:
18 Dec 2020, 22:06
...
PS. The only thing I miss is the last example with "goto -1" and then "goto 0". Why does that stop @ 2, wouldn't -1 clear everything?

For last example… ( Note that for last example, On Error GoTo Skip is outside the loop. It is just enabled ( turned ON ), once at the start.... )
In the loop we have....
"goto -1" - this just takes VBA out of the strange “exception state”. That's all
After that code line your error handler , On Error GoTo Skip is still enabled. So it would still work.
But then in next code line we do have "goto 0".
"goto 0" then disables your error handler , On Error GoTo Skip, and so it wont work. We are now back to the default error handling.

If you moved your error handler , On Error GoTo Skip, into the loop it would work 10 times, since we then turn it back on. –
In this next macro below, we turn it on 10 times, ( and turn it off 10 times )

Code: Select all

Sub TrapAllErrorsTurnOnOff()
Dim Cnt As Long, Oops As Double
    For Cnt = 1 To 10
     On Error GoTo Skip ' turn our error handler   ON ( enable it )
     MsgBox prompt:=Cnt
     Let Oops = 1 / 0
Skip:
    On Error GoTo -1
    On Error GoTo 0 '  ' turn our error handler   OFF ( disable it )
    Next Cnt
End Sub
In the above macro ....
Loop 1 ( Cnt=1)
We turn it On - , On Error GoTo Skip
We turn it Off - On Error GoTo 0
Loop 2 ( Cnt=2)
We turn it On - , On Error GoTo Skip
We turn it Off - On Error GoTo 0
Loop 3 ( Cnt=3)
We turn it On - , On Error GoTo Skip
We turn it Off - On Error GoTo 0
Loop 4 (Cnt=4)
We turn it On - , On Error GoTo Skip
We turn it Off - On Error GoTo 0

….etc…

On Error GoTo -1 does not disable the error handler, it does not turn it Off. It just takes VBA out of the strange exception state.
It is the strange exception state that many people do not know about. That is why people often get the problem you had originally.
In the exception state, an error handler statement like On Error GoTo Skip is ignored by VBA. I don't know why it was made to be like that. I expect there is some good reason for it to be made to be like that which i don't know about.
( I personally always prefer a code that does not use an error handler, if there is an alternative which can be done without error handling, But that is just personal choice)

Ref
On Error GoTo -1 ... Resets the active error status (exception) to Nothing without disabling any currently enabled error handler
http://web.archive.org/web/201910051527 ... ost4357648
Last edited by Doc.AElstein on 27 Dec 2020, 15:10, edited 4 times in total.
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
ChrisGreaves
PlutoniumLounger
Posts: 15498
Joined: 24 Jan 2010, 23:23
Location: brings.slot.perky

Re: Simple code but error trap fails?

Post by ChrisGreaves »

Doc.AElstein wrote:
18 Dec 2020, 22:44
"goto -1" - this just takes VBA out of the strange “exception state”. That's all
After that code line your error handler , On Error GoTo Skip is still enabled. So it would still work.
But then in next code line we do have "goto 0".
"goto 0" then disables your error handler , On Error GoTo Skip, and so it wont work. We are now back to the default error handling.
Thank you, Doc, for introducing this business of "On Error GoTo -1"

Let's put it to the acid test and see if Greaves has Grasped the concept (Greaves not having heard of "On Error GoTo -1" until mid-week)

(1) Without any error-handling code (programmed or executed), execution problems will raise a Run-Time Error(RTE) and the application program code will stop dead in the water and ask the application user to do something. About the only thing the user can do is click on the OK button and pick up the phone.

(2) When a "On Error GoTo 0" is executed the application program reverts to a state that is as if the issue of error-handling had never been mentioned/programmed/executed. A paraphrase would be Execution of every VBA application program starts with a hidden "On Error GoTo 0"; I know it isn't a hidden instruction, but "On Error GoTo 0" pretty well sends us back to the state we were in immediately before the program began executing.
The behaviour described in (1) will apply from this time forward.

(3) "On Error GoTo -1" executed while we are in the midst of handling an RTE says, effectively, "OK, thank you, we (VBA and I) have trapped and recognized the error, and while I am back in control and dealing with the problem, if another RTE occurs before I have completed the job of dealing with the problem, switch execution back to the original error-handling".

Suppose I trapped the most stupid RTE which appears in all the training manuals - division by zero. The application programmer has written A=B/C and C turns out to have the value Zero.

Code: Select all

On Error Go To Failed
...
Failed: ' at this point I am dealing with a DIV/0 RTE
On Error GoTo -1 ' OK, I got it, let me handle it
...
X=Y/0 ' A really stupid piece of code, and the next instruction executed will be at "Failed:"
If I have got it right so far, then I understand that "On Error GoTo -1" does not set another error trap, but merely re-invigorates an existing trap.

That being the case, if I plan to use "On Error GoTo -1" i probably should be using a switch of my own, so that if/when I do get sent back to "Failed:", I should have my own switch to tell me "Wait on a minute here; I am still trying to deal with the first instance; this second instance indicates a different problem, a problem within my own "dealing with the problem" error-handling".

stackoverflow has an interesting point that "GoTo -1" in VBA is telling the code to branch to "Line -1" of the program, which would be two lines before Line 1; in other words, "the line just before we began execution".

Thanks
Chris
An expensive day out: Wallet and Grimace

User avatar
ChrisGreaves
PlutoniumLounger
Posts: 15498
Joined: 24 Jan 2010, 23:23
Location: brings.slot.perky

Re: Simple code but error trap fails?

Post by ChrisGreaves »

Doc.AElstein wrote:
18 Dec 2020, 22:44
( I personally always prefer a code that does not use an error handler, if there is an alternative which can be done without error handling, But that is just personal choice)
I feel the same way. When I got paid for writing VBA I wore two hats; one hat was labeled "application programmer" and the other hat was labelled "system programmer".

As "application programmer" I ought NEVER to write error-handling code with the "On Error" tribe of excuses. Division-by-zero should be trapped by me, the "application programmer", by using an IF statement to test the divisor before executing the arithmetic statement. I mean, when I write an On Error block to deal with division by zero, I have to write that code anyway! So why not write it up front, and test for it up front?

As "system programmer" my job was to provide an environment for the "application programmer", so in the early days of VBA it was my job to write a procedure to test for existence of a file:-

Code: Select all

Public Function blnFileExists(strFileName) As Boolean
   On Error GoTo Failed
   blnFileExists = ( FileLen(strFileName) = FileLen(strFileName) )
Failed:
End Function
This code sat in a Library of utility routines; i was in effect extending the language VBA so that the application programmer never needed to wrestle with "unanticipated errors".

There is a deep philosophical business here, along the lines of "The world of programming digital computers is a completely deterministic world", but I have not yet had my second coffee :evilgrin:

Cheers
chris
An expensive day out: Wallet and Grimace

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

Re: Simple code but error trap fails?

Post by Doc.AElstein »

Hi Chris,
I was re-pondering and checking that I had everything correct over my morning coffee, as you posted …
I am on the third coffee now, and should be going outside soon, since the snow isn’t here yet – bl#### global warming spoiling my pretty Winter world again :(
Every time I answer a question related to this VBA error handling stuff I perfect my understanding a bit more.
I am long off the best authority on this, but as I get better I notice more and more of the experts got it not quite right….

Comments on this post….
_ Your (1) and (2) are as I understand it
_ Your (3) I am not 100% sure about what you wrote there. It may be correct or wrong. I am not sure. If I had to put money on it I would say you have not quite got it right. *** or not
As I ( currently ) understand it, On Error GoTo -1 puts us back into the normal running as if we had had no error. It forgets about it.
In such a situation where I use On Error GoTo -1 , I think the code never stopped running, -it just switches back from “exception state” to “normal state”.
On Error GoTo -1 switches back from “exception state” to “normal state”.
“Normal state” will either mean that we are
_ in the default VBA error handling
or
_ back to any user defined error handling ( such as like On Error GoTo Skip ) . This will be the case if we had ever previously before the error passed a statement like On Error GoTo Skip and also had never passed a statement like On Error GoTo 0
Re reading what you wrote, you said “switch execution back to the original error-handling” – If you meant what I just said, then we are in fact in agreement. *** ( But don’t ask me if we are both correct or both wrong! )
I could not quite follow what you were saying in your pseudo code snippet, but this bit that you wrote seems approximately correct to me….If I have got it right so far, then I understand that "On Error GoTo -1" does not set another error trap, but merely re-invigorates an existing trap. I say approximately because we are don’t re investigate anything. What we do is go back to using in the case of an error what ever we were using before the last error occurred. We forget about the error that occurred. We pretend it never happened. We run the coding further normally as if nothing bad had happened
(By the way, I don’t think your Failed: is an instruction. It is a spring point or label. We actually go to the code line under it. ( https://eileenslounge.com/viewtopic.php ... 20#p278820 ) . The statement wording is not quite correct, ( I mean the makers of VBA probably don’t quite know what they were talking about ) It would be more accurate to say
On Error Go To the code line under this label named Failed )
_._________________
ChrisGreaves wrote:
19 Dec 2020, 08:52
......
stackoverflow has an interesting point that "GoTo -1" in VBA is telling the code to branch to "Line -1" of the program, which would be two lines before Line 1; in other words, "the line just before we began execution"....
That is very interesting, thanks, I must look at that in more detail later , or tomorrow . I had not seen that Thread before, but the first time I “blogged” on error handling, that is how I tried to explain "GoTo -1" in the Layman’s terms that I could understand….


_.__________________________

Error handling is a tricky subject. You have to be careful when you mention it in forums and blog sites.. It is one of those things that often triggers off some psychotic disturbance problem in a lot of experts and they go ape s### when you mention it. I am not sure why.
I must have made a comment to correct a dozen well known Blog sites that got their error handling wrong because they did not quite understand it correctly. I showed them how to do it correctly.
Sometimes they removed their blog, sometime not. They never corrected the post to get it right. In most cases my comment vanished some time later, and my normal Email and IP address was blocked from ever posting there again..

Alan
Last edited by Doc.AElstein on 19 Dec 2020, 20:49, edited 1 time in total.
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

Re: Simple code but error trap fails?

Post by Doc.AElstein »

One Last variation, just for completeness, the outcome of which I was not sure about. In this last example I have the error handler , On Error GoTo Skip at the start and outside the loop, so its just enabled ( “switched ON” ) once. I have both goto -1 and goto 0 at the Skip place, but this time I have the goto 0 before the goto -1
So that means that the code line goto 0 will be done whilst in the exception state.
The result is that the macro crashes out with the default error handler at loop 2. So this suggests that in the exception state, the statement On Error GoTo 0 is not ignored . I was not expecting that, as I have read that all error handling statements are ignored at places referring to On Error GoTo 0 as one of the error handling statements. This is another reason why I don’t personally like having anything to do with error handling if possible. Even Blog sites explaining error handling in detail don’t seem quite right. I think I got it not quite right a few times in the past when I explained it to people as well, Oops! :)

Code: Select all

 Sub TrapAllErrorsOops()
On Error GoTo Skip ' turn our error handler,  ON ( enable it )
Dim Cnt As Long, Oops As Double
    For Cnt = 1 To 10
     MsgBox prompt:=Cnt
     Let Oops = 1 / 0
    Application.Wait Time:=(Now + TimeValue("0:00:10")) ' This code line will never be done
Skip:
    On Error GoTo 0 '  ' turn our error handler,  OFF ( disable it )
    On Error GoTo -1
    Next Cnt
End Sub
If you edit out the code line On Error GoTo 0 , then the above macro does not crash out and goes through the 10 loops. That is as expected, … I think. I that case we are back to turning the error handler, On Error GoTo Skip On once, but never turning it off.

Every time I answer a question related to this VBA error handling stuff I perfectly my understanding more. What I am taking form this post is to refine this typically heard sentence
In the exception state further error handling statements are ignored
We probably should be saying more explicitly
In the exception state, VBA does not disable any user defined error handling statements of the form like On Error GoTo Skip, but it no longer uses them. In addition it will ignore any attempt to enable another user defined error handling statement like On Error GoTo Skipit2
If we had enabled a user defined error handler, such as with On Error GoTo Skip , and then an error occurred, our error handler is still enabled but wont work. Using On Error GoTo -1 takes us out of the exception state, and then any enabled error handler would begin to work again without us having to take any other action. The way we turn Off ( disable ) any error handler and so revert back to the default VBA error handling, is to use On Error GoTo 0. That will turn OFF ( disable ) our error handler and revert us back to default error handling. That appears to work , that is to say to will turn OFF ( disable ) our error handler and revert us back to default error handling, in both a macro running in the normal state ot a macro running in the exception state after an error had occurred
.

The problem is that a Blog to explain explicitly and correctly VBA error handling would need to be so long that probably no one would ever read it, so no one will ever understand it fully. Those that do possibly understand error handling in VBA, will never explain it fully or correctly, for fear of being banned or similar…
Last edited by Doc.AElstein on 19 Dec 2020, 11:00, edited 1 time in total.
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
ErikJan
5StarLounger
Posts: 1185
Joined: 03 Feb 2010, 19:59
Location: Terneuzen, the Netherlands

Re: Simple code but error trap fails?

Post by ErikJan »

Doc.AElstein wrote:
18 Dec 2020, 22:44
On Error GoTo -1 does not disable the error handler, it does not turn it Off. It just takes VBA out of the strange exception state.
It is the strange exception state that many people do not know about. That is why people often get the problem you had originally.
In the exception state, an error handler statement like On Error GoTo Skip is ignored by VBA. I don't know why it was made to be like that. I expect there is some good reason for it to be made to be like that which i don't know about.
( I personally always prefer a code that does not use an error handler, if there is an alternative which can be done without error handling, But that is just personal choice)
Clear, thanks again!

User avatar
ErikJan
5StarLounger
Posts: 1185
Joined: 03 Feb 2010, 19:59
Location: Terneuzen, the Netherlands

Re: Simple code but error trap fails?

Post by ErikJan »

Let me try a two line summary (with the BIG risk of confusing and being wrong)... ;-)

on error goto 0 -- disables error trapping but does not reset the error state. Any new error trapping is ignored until the state is reset
on error goto -1 -- resets the error state, restoring error trapping as it was before the error occurred

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

Re: Simple code but error trap fails?

Post by Doc.AElstein »

ErikJan wrote:
19 Dec 2020, 10:58
..
on error goto 0 -- disables error trapping but does not reset the error state. Any new error trapping is ignored until the state is reset
on error goto -1 -- resets the error state, restoring error trapping as it was before the error occurred
I think that is correct.
It is useful to have another way of saying it, Thanks
I have not used the word "error trapping" much before in my explanations. I think I will from now on.
Alan
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
HansV
Administrator
Posts: 78237
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: Simple code but error trap fails?

Post by HansV »

On the other hand: the macro

Code: Select all

Sub Test()
    Dim x
    On Error Resume Next
    x = 1 / 0
    Debug.Print "Error code before On Error GoTo 0: : " & Err.Number
    On Error GoTo 0
    Debug.Print "Error code after On Error GoTo 0: " & Err.Number
End Sub
produces the following output in the Immediate window:

Error code before On Error GoTo 0: : 11
Error code after On Error GoTo 0: 0


So On Error GoTo 0 appears to clear the error state.
Best wishes,
Hans

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

On Error Resume Next

Post by Doc.AElstein »

I am not sure what’s going on there. Maybe to explain it we need to know exactly what On Error Resume Next and On Error GoTo 0 does
The short response to your last post, Hans, could be, I don’t know for sure….
Maybe:
On Error GoTo 0 didn’t clear the state, because there wasn’t a state to be cleared.
On Error GoTo 0 cleared the Err register thing

_.__________________________________________________________________________-
I don’t know for 100% sure.
In more detail, Maybe this…..

On Error GoTo 0
Possibly On Error GoTo 0 also clears the Err register thing.
Possibly the Err register thing gets filled with information when an error occurs, regardless of anything else.
I am fairly sure , that On Error GoTo 0 disables the error handler ( disables the error trapping ).
( As of a few hours ago it seems to me that it also does it in the exception state).


On Error Resume Next
Possibly On Error Resume Next prevents the exception state ever being. So in your last macro the error state was never there. On Error Resume Next tells VBA not to go into the exception state, but it does not prevent the Err register thing being filled.
These variation of your last macro let me change the error trap. This suggest to me that On Error Resume Next prevented the error state ever being raised
The second macro is also telling me that the Err register thing gets filled with new information again after a different error occurs.

Code: Select all

 Sub TestTraps()
    Dim x
    On Error Resume Next
    x = 1 / 0
    Debug.Print "Error  before On Error GoTo Bed:  " & Err.Number & Err.Description
    On Error GoTo Bed
    Debug.Print "Error  after On Error GoTo Bed: " & Err.Number & Err.Description
    x = 1 / 0
Exit Sub
Bed:
 Debug.Print "Error  in Bed: " & Err.Number & Err.Description
End Sub
Sub TerrorTraps()
    Dim x, arrSpt() As Variant
    On Error Resume Next
    x = 1 / 0
    Debug.Print "Error  after divide by 0 : " & Err.Number & Err.Description
    arrSpt() = Split("1 2", " ", 2, vbBinaryCompare) ' This will error because  Split  function returns an array of  string  type elements
    Debug.Print "Error  after Type mismatch : " & Err.Number & Err.Description
    On Error GoTo Bed
    Debug.Print "Error  after On Error GoTo Bed: " & Err.Number & Err.Description
    x = 1 / 0
    Application.Wait Time:=(Now + TimeValue("0:00:10")) ' This code line will never be done
Exit Sub
Bed:
 Debug.Print "Error  in Bed: " & Err.Number & Err.Description
End Sub

What I am saying, ( or rather suggesting because I don’t know for sure ), is, regardless of what error handling/ trapping we are doing, the Err register thing gets filled with the relevant information every time an error occurs. We can clear that register by either On Error GoTo 0 or by changing the error trap to a different one, ( which I can do if I used On Error Resume Next because I don’t have an error state ever if I used that)

In this next macro, my last erroring code line chucks up the default VBA error handler, but it does give me the correct information, so possibly this further confirms that the Err register thing is filled even in the exception state, if I assume that the default VBA error handling takes its info from that Err register thing.

Code: Select all

 Sub TerrorWonks()
    Dim x, arrSpt() As Variant
    On Error Resume Next
    x = 1 / 0
    Debug.Print "Error  after divide by 0 : " & Err.Number & Err.Description
    arrSpt() = Split("1 2", " ", 2, vbBinaryCompare)
    Debug.Print "Error  after Type mismatch : " & Err.Number & Err.Description
    On Error GoTo Bed
    Debug.Print "Error  after On Error GoTo Bed: " & Err.Number & Err.Description
    x = 1 / 0
    Application.Wait Time:=(Now + TimeValue("0:00:10")) ' This code line will never be done
Exit Sub
Bed:
 Debug.Print "Initial Error in Bed: " & Err.Number & Err.Description
 Let arrSpt() = Split("1 2", " ", 2, vbBinaryCompare)
 Debug.Print "Error  after Type mismatch : " & Err.Number & Err.Description 'this wont be done, but the default error handling tells me that I have a type mismatch, so possibly that is getting its infomation from the  Err  register thing
End Sub
_._______________


You often hear it said that On Error Resume Next “suppresses” the error. I don’t know for sure if that means the same as it doesn’t let the error state occur, ( or it only lets it exist for a short split second or so, so that the Err register thing gets filled , then it went back to normal state but did not clear the Err register thing )

The short response to your last post, Hans, could be, I don’t know for sure….
Maybe:
On Error GoTo 0 didn’t clear the state, because there wasn’t a state to be cleared.
On Error GoTo 0 cleared the Err register thing

Code: Select all

Sub ErrorState()
Dim x
On Error GoTo ResumNext
x = 1 / 0
ResumNext:
' I am in exception state, and   Err   will tell me all about what error occured if I ask it
End Sub
Sub NoErrorState()
Dim x
On Error Resume Next
x = 1 / 0
' I am not in exception state, but    Err    will tell me all about what error occured if I ask it
End Sub
I expect nobody knows for sure. Those that possibly ever did , long since forgot.

Ref
On Error WTF
On Error Resume Next
https://www.myonlinetraininghub.com/err ... ing-in-vba
https://excelfox.com/forum/showthread.p ... #post15209
http://www.eileenslounge.com/viewtopic. ... 49#p247149
https://www.myonlinetraininghub.com/exc ... ment-84892
Last edited by Doc.AElstein on 04 Mar 2021, 09:17, edited 2 times in total.
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

LisaGreen
5StarLounger
Posts: 964
Joined: 08 Nov 2012, 17:54

Re: Simple code but error trap fails?

Post by LisaGreen »

I totally adore this sort of thing!!

Lisa

LisaGreen
5StarLounger
Posts: 964
Joined: 08 Nov 2012, 17:54

Re: Simple code but error trap fails?

Post by LisaGreen »

Hi,

A little off topic maybe but my 2 'penneth is that I prefer to add error code inline.

On error resume next
Line that could cause error
lnglErrNumber = Err.Number
On error goto 0
select case lnglErrNumber
Case 0
Case ...
Case ...
Case Else
End select

I have code to add this code and the lnglErrNumber variable around a code line so making it easier. It adds to the number of lines of code but this is offset by being able to handle an error specifically and friendlier.

Lisa

User avatar
ErikJan
5StarLounger
Posts: 1185
Joined: 03 Feb 2010, 19:59
Location: Terneuzen, the Netherlands

Re: Simple code but error trap fails?

Post by ErikJan »

Right, but what do you do after you've handled this? As we (I) have learned, "on error goto 0" doesn't reset the error state, just the trap. If you just resume after your code and there is a new error, your code will break...

User avatar
HansV
Administrator
Posts: 78237
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: Simple code but error trap fails?

Post by HansV »

It's always best to have a generic error handler, so that the end user never sees the End/Debug dialog.
Best wishes,
Hans

LisaGreen
5StarLounger
Posts: 964
Joined: 08 Nov 2012, 17:54

Re: Simple code but error trap fails?

Post by LisaGreen »

That's sort of my point Hans.

My added code works out which line the error may occur on. This can be passed to another routine along with the error line and whatever information you want. This routine could log to a file even.

The user should never be bothered with code bits... Rather a message telling her things and suggesting a fix. "The data has the wrong format at line 302. Please correct and try again." or ".. Would you like me to ignore that data." , "The data source could not be opened. Would you like me to try again".. and so on.

But whatever.... IMHO.. the code FINAL code should try to "deal with" the error.

Lisa