Results 1 to 14 of 14
  1. #1
    Silver Lounger
    Join Date
    Jun 2001
    Location
    Morden, Surrey, United Kingdom
    Posts
    1,838
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Error checking code (WinNT4/Word97)

    We've recently had an experienced VBA programmer working here, which has been a great help in some ways but less so in others!

    One of the things he has done is to set up an error checking system in a series of massive templates, and to be fair it works very well, bringing up an error message that tells us the exact module, sub and line (they're all numbered) in which the problem has occurred. However, it is horrendously clumsy to work with the code now! For instance, one sub (linking to another function) used to look like this:

    Private Sub cmddeps_Click()
    forClickedPS "deps", "Linked Deposits"
    End Sub

    Now it looks like this:

    Private Sub cmddeps_Click()
    1310 gErr.Push ("frmPostSales - cmddeps_Click")
    1320 If gDebugOn Then
    1330 On Error GoTo PROC_ERR
    1340 End If
    1350 forClickedPS "deps", "Linked Deposits"
    PROC_EXIT:
    1360 gErr.Pop
    1370 Exit Sub
    PROC_ERR:
    1380 gErr.HandleError
    1390 Resume PROC_EXIT
    End Sub

    As you can see it links to various other subs and modules and my question doesn't involve the actual mechanics of the system (at the moment, anyway), just the aesthetics!

    Now, (1) I've got into the habit (with Hans' help) of pulling out unnecessarily repeated code into separate functions/subs and (2) the additional code in the above example is *EXACTLY* the same in *EVERY SINGLE SUB AND FUNCTION* in the template (and that's a lot of subs and functions!), except for one variable in the first line (1310 in this example).

    So, my question is (and it's probably a lot simpler than you think after all the above waffle!) - is there something about error trapping code that means it *has* to be in the sub concerned, or would I be able to make up a couple of functions for the first and second halves of that code and replace them all with a single line top and bottom, one including the variable?

    Many thanks in advance!
    Beryl M


  2. #2
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 28 Times in 28 Posts

    Re: Error checking code (WinNT4/Word97)

    I'm afraid you're stuck with it. All the inner working of the error handling has already been placed in gErr; the lines you have are necessary to set up the error handling.

  3. #3
    Silver Lounger
    Join Date
    Jun 2001
    Location
    Morden, Surrey, United Kingdom
    Posts
    1,838
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Re: Error checking code (WinNT4/Word97)

    Hi Hans; I was afraid you were going to say that! It did seem unlikely that with his skills he would have left something that clumsy if it was not necessary, but I had to ask!

    <img src=/S/sigh.gif border=0 alt=sigh width=15 height=15>
    Beryl M


  4. #4
    3 Star Lounger
    Join Date
    Apr 2004
    Location
    Boston, Massachusetts, USA
    Posts
    389
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Error checking code (WinNT4/Word97)

    Yuck.

    I'm sure your guy had his reasons, but that is not pretty to look at.

    If I was in a position of having to maintain that code, I'd take a closer look at gErr (module? class instance?) to see if it anything could be done to not require that Push/Pop in every single other procedure. If you could eliminate that Push/Pop, and just wait until an error happened to send the procedure name, you could prune that code quite a bit (not to mention improve overall performance).

    Not knowing more about the code you've got, I can't be very specific, but here's a generic implementation of what I'm talking about. The first procedure is just a silly subroutine that's guaranteed to produce an error. The first line could check the value of a global debug variable (I just used 1 here to force the error handling). If you add in the Exit Sub and ERR_HANDLER lines, you're only looking at 3 extra lines per procedure. The second procedure is a rudimentary error reporter that just echoes the error number and description, along with the procedure name.

    With this approach, you'd lose the line numbering, of course, but is that realistically something you want to try and maintain anyway?

    <pre>Sub SomeSubroutine()
    If 1 Then On Error GoTo ERR_HANDLER ' replace 1 with your gDebug variable
    MsgBox 1 / 0 ' just something to force an error
    Exit Sub
    ERR_HANDLER: HandleError("SomeSubroutine")
    End Sub
    '
    Function HandleError(sProcedureName As String)
    MsgBox "Error: " & Err.Number & " (" & Err.Description & ") has occurred " & _
    "in the following procedure: " & sProcedureName
    End Function
    </pre>


    Just my <img src=/S/2cents.gif border=0 alt=2cents width=15 height=15>

  5. #5
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Error checking code (WinNT4/Word97)

    I agree with Andrew's post, but I'd be inclined to have the error-handler report both the module and the procedure, so I'd replace his ERR_HANDLER: HandleError("SomeSubroutine") line with ERR_HANDLER: HandleError("SomeModule", "SomeSubroutine") and then supplement his HandleError procedure along these lines:
    <pre>Function HandleError(sModuleName As String, sProcedureName As String)
    MsgBox "Error: " & Err.Number & " (" & Err.Description & ") " & _
    "has occurred in the " & sProcedureName & " procedure " & _
    "in the " & sModuleName & " module."
    End Function</pre>

    As for the line numbering: I guess I can see a case for that if there might be remote debugging -- i.e., if you might be using this programmer to try to resolve an error situation at times when he's not at your site -- since it will enable you to easily point him to the line causing the error without someone on-site having to figure out what line that is by stepping through the code. Otherwise I'd lean against. In situations where a particular procedure is causing problems on an intermittent basis and it's hard to figure out why, line numbering can always be added to that particular procedure, without the need to have all the lines in that module (much less the whole project) numbered. But note: I'm not a pro. I'd be curious to hear from one or more of the pro Loungers about how common or rare it is for a programmer to line-number an entire VBA project.

  6. #6
    Plutonium Lounger
    Join Date
    Dec 2000
    Location
    Sacramento, California, USA
    Posts
    16,775
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: Error checking code (WinNT4/Word97)

    The reason for doing it with push and pop is probably because the stack is being written to a text file, which will provide the exact sequence of events that led to the error. The Total Source Book from FMS used to contain a similar approach to error handling that required you to push every routine into a stack and then pop it if the routine ended normally. That may be where the idea came from, but this is far more elaborate.
    Charlotte

  7. #7
    3 Star Lounger
    Join Date
    Apr 2004
    Location
    Boston, Massachusetts, USA
    Posts
    389
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Error checking code (WinNT4/Word97)

    That makes sense. I was thinking it was to set up some sort of stack trace, and couldn't think of the mechanism -- writing each procedure to a log file hand't occurred to me. Sort of clever actually. Though it kind of underscores VB's lack of an actual stack trace ability. It's also always bugged me that you have to explicitly pass the procedure name in a situation like this, rather than doing something like $0, a la Perl or Ruby.

    At any rate, thanks for the post -- learn something new every day!

  8. #8
    Plutonium Lounger
    Join Date
    Dec 2000
    Location
    Sacramento, California, USA
    Posts
    16,775
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: Error checking code (WinNT4/Word97)

    Try VB.Net if you want stack tracing. <img src=/S/grin.gif border=0 alt=grin width=15 height=15>
    Charlotte

  9. #9
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Error checking code (WinNT4/Word97)

    > error trapping code that means it *has* to be in

    The VBA help says that *if* you are using "on error" then the target label *has* to be in the same procedure. That suggests that minimal code looks like this, for any procedure in which you want to trap & trace an error. <pre>Sub test()
    On Error GoTo ErrorHandler
    ' dosomething
    Exit Function
    ErrorHandler:
    Call Erl("test")
    End Sub</pre>

    where the error handling routine "Erl" takes at least the identifier of the code that caused the problem.

    I rail against On Error. I think it's a cheap shot for thoughtless programmers. I say that NOT to denigrate Lounge members, but because over the years I've seen too much code in which On Error is used as a substitute for thought.

    That said, you still have several options:
    1) Get rid of the conditional debug mode. If you've got a real error, it's an error, right? Debug mode or not - Program around it or ponder it carefully.
    2) Remove error trapping from any low-level procedure that can't generate an error. Miniscule low-level ('slave" or utility) routines generally don't need error-trapping because (a) they work with extremely small chunks of well-defined code and ([img]/forums/images/smilies/cool.gif[/img] they don't deal with user data or events (which can be somewhat unpredictable). I mean by example that a short string procedure to parse a string ought not be generating any error that could be trapped by an On Error routine. We ought to be testing for zero-length, empty, null, multiple delimiters and so on prior to calling the slave routine.

    You are probably stuck with the module/procedure structure, and can't change the actual working code. You ought, as a minimum, be able to get rid of the conditional stuff with a global edit/replace; is it really doing anything helpful? That the code is identical in every procedure ought to make it VERY tempting for you to sue global edit/replace. Heh heh!

  10. #10
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 28 Times in 28 Posts

    Re: Error checking code (WinNT4/Word97)

    Chris,

    I agree that On Error should not be used as a substitute for careful programming. But no programmer is perfect, it's always possible that a problem occurs that you didn't foresee. An unhandled error is unacceptable in an application for end users - global variables are cleared and event handlers may not be executed any more. A compiled application, such as an .exe created in VB6, simply crashes.

    There are some situations in which On Error is by far the most convenient way to do something. Say that you want to run Excel from Word using Automation. Since starting a new instance of Excel uses up resources, it is preferable to use the already running instance if it is available. GetObject(, "Excel.Application") causes an error if Excel is not running; trapping this with an error handler is easier than performing elaborate checks.

    Like you, I usually don't put error handling in short utility routines, but I do put it in the higher-level routines that call them.

  11. #11
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Error checking code (WinNT4/Word97)

    I don't want to get into a lengthy debate but ... while I agree with you, I do like to maintain a distinction between the different uses of On Error.
    An unplanned error is just that, it seems to me.

    Trapping a trappable error with On Error and dealing with specific error numbers is one thing. Having a generic "I trapped an error" is little better than just leaving the application to fail. When I see the set of "case" statements dealing with each error number, I often (but admittedly not always) can see that the programmer could have tested for the potential error condition in advance of calling the routine; if you are going to cope with the condition, why not cope with it upstream, instead of waiting for the condition to trigger an error and then have all the (programming) work of tracing the problem back to its source?

    I used to rail against all On Error statements until I found my library of code was chock-a-block with them, and came to the conclusion that the design of early VBA left me no choice in some cases but to use On Error to detect events such as "if folder exists" and the like. Your excellent [/flattery] example "GetObject(, "Excel.Application")" indicates that VBA has provided no convenient programmable-test for an instance of Excel running (set running by some other process over which you have no control), and so we must resort to On Error. It's what we have to do, I agree, but I claim that the need is brought about by poor deisgn of the VBA system.

    Hope this finds you as it leaves me, if not, execute an On Error statement and email me in the morning (grin!)

  12. #12
    4 Star Lounger
    Join Date
    Dec 2003
    Location
    Zoetermeer, Zuid-Holland, Netherlands
    Posts
    559
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Error checking code (WinNT4/Word97)

    <hr>error-handler report both the module and the procedure<hr>
    I agree with you, but like to add that users (our users at least) are in the habit of clicking the msgbox away before they call the helpdesk. <img src=/S/sad.gif border=0 alt=sad width=15 height=15>
    So I enhanced it further by writing a log file with each error appended, which is very much appreciated by the helpdesk people.

    <pre>Public Sub ErrorHandler(strFile As String, _
    strModule As String, _
    strRoutine As String, _
    lngError As Long, _
    strError As String)
    'Central errorhandler, writes logfile My Documents and puts message on screen
    'Takes 5 input parameters: Codefile (dot), vba-module, vba-sub/function,
    'error number and error description

    Dim strTitle As String
    Dim strPrompt1 As String
    Dim strPrompt2 As String
    Dim strMyDocs As String
    Dim iChannel As Integer

    On Error GoTo Error_ErrorHandler

    strTitle = strFile & ", " & strModule & ", " & strRoutine
    strPrompt1 = "Error: " & lngError
    strPrompt2 = ", Description: " & strError
    'Read location of "My Documents" from the registry
    strMyDocs = System.PrivateProfileString("", "HKEY_CURRENT_USERSoftware" & _
    "MicrosoftWindowsCurrentVersionExplorerShell Folders", "Personal")
    'Add name of log file
    strMyDocs = strMyDocs & "VBA (Word) Error.log"

    'Write error to file, appending it to existing file
    iChannel = FreeFile
    Open strMyDocs For Append As #iChannel
    Print #iChannel, Format(Now, "dd-mm-yyyy, hh:mm:ss") & " - " & strTitle
    Print #iChannel, Space(12) & strPrompt1 & strPrompt2
    Close #iChannel

    'Put message on screen for user
    MsgBox "An Error occurred:" & vbCrLf & vbCrLf & strPrompt1 & vbCrLf & strPrompt2, _
    vbInformation + vbOKOnly, strTitle

    Exit_Error:
    Exit Sub

    Error_ErrorHandler:
    'If an error occurs in the error handler...
    MsgBox "An error occurred:" & vbCrLf & vbCrLf & _
    "Number : " & Err.Number & vbCrLf & _
    "Description: " & Err.Description, vbInformation + vbOKOnly, _
    "ErrorHandler"
    Resume Exit_Error
    End Sub
    </pre>


  13. #13
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Error checking code (WinNT4/Word97)

    Thanks for the sample code. You probably have reasons I'm not aware of for setting up the argument-passing the way you do, but just in case you didn't know you had the alternative, you can avoid passing lngError and strError to the procedure (assuming they're just Err.Number and Err.Description) and have the ErrorHandler procedure just read those properties directly (e.g., strPrompt1 = "Error: " & Err.Number). The only tricky part is that the ErrorHandler procedure will need to assign those properties to the strPrompt strings before the "On Error GoTo Error_ErrorHandler line (since an On Error line resets the Err object). Since it's hard to imagine the strPrompt assignment lines triggering an error, executing them in a "no-handler zone" shouldn't be a problem.

  14. #14
    4 Star Lounger
    Join Date
    Dec 2003
    Location
    Zoetermeer, Zuid-Holland, Netherlands
    Posts
    559
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Error checking code (WinNT4/Word97)

    Thanks, I do know that alternative now. But probably not when I programmed it a few years back. And you know what they say: if it ain't broken, don't fix it... <img src=/S/grin.gif border=0 alt=grin width=15 height=15> So if there's no real good reason to change this, I'll leave it that way, because it's a lot of work going thru all relevant Subs and Functions.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •