ActiveXのエラー・トラップの考え方を説明する例を以下に示します。コードをコピーして、RDMLXを使用可能にしたフォームに貼り付け、コンパイルして実行してください。
考え方を理解するには、コードのコメントを確認してください。
設定方法
- ActiveXのComponentOnFailureプロパティを設定します。
- コードでエラーをトラップします。
- ActiveXのComponentOnFailureプロパティを「SignalError」に設定します。
*Trap error in codeFunction 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 wordSet_Ref Com(#Word) To(*Create_as #va_word)EndroutineEvtroutine 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.BookmarksElseUse Builtin(ov_message_box) With_Args("Document Aleady Exists")EndifElseUse Builtin(ov_message_box) With_Args("Word Has Not Yet been Started")EndifEndroutineEvtroutine Handling(#FindBookmark.Click)Define_Com Class(#va_word.Bookmark) Name(#Bookmark) Reference(*dynamic)* Ensure there is an Active DocumentIf (#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>ElseUse Builtin(Ov_message_box) With_Args("There Is No Active Document")EndifEndroutineEvtroutine Handling(#Word.ComponentError)* This routine will never fire. The bookmark error is specific to the Bookmark instanceUse 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)EndroutineEvtroutine 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)EndroutineEvtroutine Handling(#Com_Owner.Closing)* Drop all references and ensure Word quits correctly#Word.Documents.CloseIf (#Word *IsNot *null)#Word.QuitEndifEndroutineEnd_Com
背景に関する注意事項
LANSAの実行時エラーを処理するには、LANSAによって生成されたエラーと、ActiveXコントロールによって生成されたエラーの違いを理解する必要があります。
次のコード・サンプルを見てみましょう。
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 := SignalErrorIf (#VA_WORD.ActiveDocument.Bookmarks.Exists( " ERROR" ))EndifEndroutineEvtroutine Handling(#VA_WORD.ComponentError) Options(*NOCLEARMESSAGES *NOCLEARERRORS)Message Msgtxt(("Catching ActiveX error").BlankConcat( #COM_ERR_INFO.ErrorCode.AsString ))#COM_ERR_INFO.ClearEndroutineEnd_Com
上の例では、initializeイベントがWord.ActiveDocument.Bookmarksを参照しています。しかし、ActiveDocumentがない場合(ドキュメントを明示的に作成しても開いてもいない場合)、WordのActiveDocument参照はnullになります。つまり、Visual LANSAランタイムがWordのActiveDocumentプロパティにアクセスを試みた瞬間に、Word.ActiveDocumentがnullであるというエラーがLANSAによって生成されます。
initializeイベントが以下のようになっていれば、エラーは発生していませんでした。
* Add a new (active) document.#VA_Word.AddIf (#VA_word.ActiveDocument.Bookmarks.Exists("Etc")etc.
したがって、別のインスタンスを参照する機能にアクセスを試みる前に、適切な防御用コードを含めるようにするのは、開発者の責任です。
If (#Word.ActiveDocument *isnot *null)
If (#VA_word.ActiveDocument.Bookmarks.Exists("Error")
etc.
else
Use OV_message_box ("There is no Active Document")
Endif
このコードで、LANSAによって生成される実行時エラーは回避されるようになりましたが、VA_WORDをリスニングすることで発生するActiveXエラーは依然として検出できません。ブックマークが存在しない場合のActiveXエラーは、Bookmarks機能に属するからです。したがって、コードに特殊な参照を設定する必要があります。
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
ここで、存在しないブックマークへのアクセスを試みると、Wordによって生成されたエラーを以下のように検出できます。
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
