OML for the complete beginner, #11

Error Trapping & Handling

There may come a time when you wish that a macro could itself respond to non-emergency errors and continue, rather than simply ending the macro and generating an error message. You may even wish you could create your own error messages in easily-upset sections of a macro, based on events that normally wouldn't trigger an error. This is where error handling comes in.

The first command to learn is On Error. It takes control of error handling away from the computer and gives it to the macro, and tells the macro what to do when an error occurs.

  On Error Goto ErrHandler
  On Error Resume Next

The first statement tells the macro to go to a section of the macro with the ErrHandler: label. The second tells the macro to skip the program line that generated the error and continue running the macro. On Error requires the use of Resume, either as part of the statement or as part of the error-handling routine. Here is an example of an error-handling routine in action:

  sub main
    Dim CS as Session
    Set CS = CurrentSession
    On Error Goto ErrorHandler
    CS.PutText "xpo", 1, 1
    RunMacro "PRSMUTIL!SendCommand"
    CS.Receive 5, "exported in USMARC"
    CS.PutText "s", 1, 1
    RunMacro "PRSMUTIL!SendCommand"
    Goto Done

  Errorhandler:
    MsgBox "There was an error.  Macro ending..."
    Resume Done

  Done:
  end sub

Right after setting up the "CS" short-cut, the macro is told that if an error occurs, it should go to "ErrHandler" instead of immediately stopping the macro. The macro then goes through its procedures; in this case exporting a record and waiting for the export to finish before saving the record. If everything runs smoothly, it then skips to the end of the macro. If there is a problem and the export fails, the CS.Receive command will generate an error--the indicated text won't be received. The macro then jumps down to the ErrHandler section, and executes the commands it finds there; in this case, a message box. Then the error handler tells the macro where to resume running the program, usually either through Resume Next, which returns to the line *after* the one that generated the error, or Resume [label], which jumps to the specified label and resumes executing commands there.

Some related statements you may find useful are Err, Error, and Erl. Erl gives you the program line that triggered the error, Err gives you the error code, and Error gives you the error description. For the following examples, assume that a "Command failed" error just occurred in the 54th line of the program:

  ELine = Erl
  ENum = Err
  e$ = Error
  MsgBox "Error (" & ENum & ") in line " & ELine & ": " & a$

The message box displays "Error (102) in line 54: Command failed". Using these commands, you can perform triage of sorts on the errors that come up, as in this program fragment:

  On Error Resume Next
  CS.Receive 5, "some text"
  Select Case Err
    Case 102
      MsgBox "Command Failed: Line " & Erl
      Goto Done
    Case 11
      MsgBox "Division by zero: Line " & Erl
      Goto Done
    Case Else
      Goto Done
  End Select

It is also possible to create and trap your own errors. If you want a program to trigger an error if a the data in a string is not numerical, you might try something along these lines:

  sub main
    On Error Goto Errhand
    StartStuff:
    Err = 0
    a$ = InputBox("Enter a number:")
    x = 1
    Do While x <= Len(a$)
      If Asc(Mid(a$, x, 1)) < 48 Or Asc(Mid(a$, x, 1)) >
      57 Then 
        Error 10000
      End If
      x=x+1
    Loop

    Errhand:
    If Err = 10000 Then
      MsgBox "Input must be numeric only"
      Resume StartStuff
    Else
      MsgBox "Error (" & Err & ") in line " & Erl & ": "
      & Error Resume Done
    End If

  Done:
  end sub

The "Err = 0" line at the beginning is important, because it clears the system of any error codes that have been triggered so far. When the program gets down to the Do...Loop, it checks each character in the string to see if it is 0-9 (0 is ASCII 48, 0 is ASCII 57); if it isn't, it triggers an Error of 10000, and jumps to the error handler. Once there, the handler checks to see if the error is the one you've created. if it is, it displays a message box, then goes back to the beginning of the program. Once back at the beginning, "Err = 0" resets the error status; if that line were missing, the program will reach the ErrHand section after a successful attempt and act as if there were an error anyway, as Err would still equal 10000 from the last error. If the error is not the one you've created, the program displays the error information in a message box and ends the macro.

Next time, dialog boxes...

Lesson #12 is quite long in comparison to previous lessons. You may wish to try it in smaller doses.


Return to Lesson #10.
Return to Main page.