Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Following is an example to explain the concept of ActiveX Error trapping. Copy and paste the code into a RDMLX enabled form, compile and run it.

To gain an understanding of the concept, follow the comments within the supplied code.

How to set it up:1.  Set

  1. Set the ActiveX ComponentOnFailure Property.

...

  1. Trap error in code.

...

  1. Set the ActiveX ComponentOnFailure property to "SignalError".

...


  1. Image Added

*Trap error in code
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(376) Clientwidth(208) Height(414) Left(295) Top(178) Width(224)
 
Define_Com Class(#PRIM_PHBN) Name(#StartWord) Caption('Start Word') Displayposition(1) Left(8) Parent(#COM_OWNER) Tabposition(1) Top(8) Width(193)
 
Define_Com Class(#PRIM_PHBN) Name(#CreateDocument) Caption('Create Document') Displayposition(2) Left(8) Parent(#COM_OWNER) Tabposition(2) Top(40) Width(193)
 
Define_Com Class(#PRIM_PHBN) Name(#FindBookmark) Caption('Access Bookmark') Displayposition(3) Left(8) Parent(#COM_OWNER) Tabposition(3) Top(72) Width(193)
 
Define_Com Class(#va_word.Application) Name(#Word) Reference(*dynamic)
Define_Com Class(#va_word.Document) Name(#ActiveDocument) Reference(*dynamic)
Define_Com Class(#va_word.Bookmarks) Name(#Bookmarks) Reference(*dynamic)
 
Evtroutine Handling(#StartWord.Click)

...


* Start an instance of word
Set_Ref Com(#Word) To(*Create_as #va_word)
 
Endroutine
 
Evtroutine Handling(#CreateDocument.Click)
 
If (#Word *IsNot *null)
 
If (#ActiveDocument *Is *null)

...


* Open a new document
#ActiveDocument <= #Word.Documents.Add

...


* Get the reference to the Bookmarks of the Active Document
* This is necessary to be able to listen to the activeX errors

#Bookmarks <= #ActiveDocument.Bookmarks
 
Else
 
Use Builtin(ov_message_box) With_Args("Document Aleady Exists")
 
Endif
 
Else
 
Use Builtin(ov_message_box) With_Args("Word Has Not Yet been Started")
 
Endif
 
Endroutine
 
Evtroutine Handling(#FindBookmark.Click)
 
Define_Com Class(#va_word.Bookmark) Name(#Bookmark) Reference(*dynamic)

...


* Ensure there is an Active Document
If (#ActiveDocument *IsNot *null)

...


* Try to access a bookmark
* As this is a new document there will be no bookmarks

* This will generate an ActiveX error on Bookmarks ONLY
 
#Bookmark <= #Bookmarks<1>
 
Else
 
Use Builtin(Ov_message_box) With_Args("There Is No Active Document")
 
Endif
 
Endroutine
 
Evtroutine Handling(#Word.ComponentError)

...


* This routine will never fire.  The bookmark error is specific to the Bookmark instance
 
Use Builtin(Message_Box_Add) With_Args("Error on Word")
Use Builtin(Message_Box_Add) With_Args(#Com_err_info.ErrorWord)
 
Use Builtin(Message_Box_Show)
 
Endroutine
 
Evtroutine Handling(#Bookmarks.ComponentError)
 
Use Builtin(Message_Box_Add) With_Args("Error on Bookmarks")
Use Builtin(Message_Box_Add) With_Args(#Com_err_info.ErrorWord)
 
Use Builtin(Message_Box_Show)
 
Endroutine
 
Evtroutine Handling(#Com_Owner.Closing)

...


* Drop all references and ensure Word quits correctly
#Word.Documents.Close
 
If (#Word *IsNot *null)
 
#Word.Quit
 
Endif
 
Endroutine
 
End_Com

...

Background notes

To handle runtime errors in LANSA, you need to understand the difference between LANSA generated errors and errors generated by ActiveX controls.

Consider the following code sample:

Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(313) Clientwidth(492)
Define_Com Class(#PRIM_STBR) Name(#STBR_1) Displayposition(1) Height(24) Left(0) Messageposition(1) Parent(#COM_OWNER) Tabposition(1) Tabstop(False) Top(278) Width(484)
Define_Com Class(#VA_WORD.Application) Name(#VA_WORD)
Evtroutine Handling(#com_owner.Initialize)
Message Msgtxt("Throwing ActiveX error")
#VA_WORD.ComponentOnFailure := SignalError
If (#VA_WORD.ActiveDocument.Bookmarks.Exists( " ERROR" ))
Endif
Endroutine
Evtroutine Handling(#VA_WORD.ComponentError) Options(*NOCLEARMESSAGES *NOCLEARERRORS)
Message Msgtxt(("Catching ActiveX error").BlankConcat( #COM_ERR_INFO.ErrorCode.AsString ))
#COM_ERR_INFO.Clear
Endroutine
End_Com

In the above example, the initialize event references Word.ActiveDocument.Bookmarks. However, if there is no ActiveDocument, that is, you have neither explicitly created nor opened a document, the ActiveDocument reference in Word will be null. This means that the moment the Visual LANSA runtime attempts to access the ActiveDocument property of Word, there will be a LANSA generated runtime error reporting that Word.ActiveDocument is Null.

Had the initialize event been as follows, no such error would occur.

* Add a new (active) document.
#VA_Word.Add
If (#VA_word.ActiveDocument.Bookmarks.Exists("Etc")
etc.

It is therefore the responsibility of the developer to ensure that before trying to access a feature that references another instance, that suitably defensive code is included.

If (#Word.ActiveDocument *isnot *null)
If (#VA_word.ActiveDocument.Bookmarks.Exists("Error")
etc.
else
Use OV_message_box ("There is no Active Document")
Endif

Even though this code now avoids the LANSA generated runtime error, you still can't detect an ActiveX error by listening to VA_WORD because the ActiveX error for a missing bookmark belongs to the Bookmarks feature. Therefore, you need to set up specific references in the code.

Define_Com Class(#va_word.Application) Name(#Word) Reference(*dynamic)
Define_Com Class(#va_word.Document) Name(#ActiveDocument) Reference(*dynamic)
Define_Com Class(#va_word.Bookmarks) Name(#Bookmarks) Reference(*dynamic)
Evtroutine #Com_owner.CreateInstance
* Start Word
Set_Ref Com(#Word) To(*Create_as #va_word)
* Create a new document and store the reference
#ActiveDocument <= #Word.Documents.Add
#Bookmarks <= #ActiveDocument.Bookmarks
 
Endroutine

When you now attempt to access a bookmark that doesn't exist, the error generated by Word can be detected as follows:

Evtroutine Handling(#Bookmarks.ComponentError)
Use Builtin(Message_Box_Add) With_Args("Error on Bookmarks")
Use Builtin(Message_Box_Add) With_Args(#Com_err_info.ErrorWord)
Use Builtin(Message_Box_Show)
Endroutine