独自のインスタンス・リスト・マネージャーへの共通タスクの委託
これまで、インスタンス・リスト・エントリーの追加、更新、削除処理を、どのようにして共通の共有インスタンス・リスト・マネージャーに代行させることができるかを見てきました。
通常、フィルターやコマンド・ハンドラー内に繰り返されるコードを含む可能性のあるその他の処理は、同じ方法で代行させることができます。
たとえば、前のセクションのRAMPスクリプトは、リッスンしているフィルター経由でイベントを通知することで、インスタンス・リスト・マネージャーにアクセスできます。ただし、リッスンしているフィルターを必ずしも認識しているとは限らないため、リッスンのためのコードをすべてのフィルターで繰り返す必要があるでしょう。
このリッスン・タスク(および実質的にすべてのリッスン・タスク)を共通の共有インスタンス・リスト・マネージャーに代行させる1つの方法を次に示します。
インスタンス・リスト・マネージャーで、次のような2つのコレクションを定義します。
* Keep track of all registered active filters and command handlers
DEFINE_COM CLASS(#Prim_Acol<#VF_ac007>) NAME(#ActiveFilters)
DEFINE_COM CLASS(#Prim_Acol<#VF_ac010>) NAME(#ActiveHandlers)
次に、以下のような2つのメソッドを追加します。
MthRoutine RegisterInitialize
Define_map *input #VF_AC007 #Filter Pass(*By_Reference) Mandatory(null)
Define_map *input #VF_AC010 #Handler Pass(*By_Reference) Mandatory(null)
* Keep track of registered and active filters
If_ref #Filter is_not(*null)
Invoke #ActiveFilters.Insert Item(#Filter)
Endif
* Keep track of all registered and active command handlers
If_ref #Handler is_not(*null)
Invoke #ActiveHandlers.Insert Item(#Handler)
Endif
Endroutine
MthRoutine RegisterTerminate
Define_map *input #VF_AC007 #Filter Pass(*By_Reference) Mandatory(null)
Define_map *input #VF_AC010 #Handler Pass(*By_Reference) Mandatory(null)
* Remove the specified filter from the active collection
If_ref #Filter is_not(*null)
Invoke #ActiveFilters.Remove Object(#Filter)
Endif
* Remove the specifeid command handler from the active collection
If_ref #Handler is_not(*null)
Invoke #ActiveHandlers.Remove Object(#Handler)
Endif
Endroutine
次に、各フィルターまたはコマンド・ハンドラーで次の3つの処理を行う必要があります。
· インスタンス・リスト・マネージャーを定義する。
DEFINE_COM CLASS(#EMPMNGR) NAME(#EmployeeManager) scope(*Application)
· 起動時にインスタンス・リスト・マネージャーに登録する。フィルターで次の処理を行う。
MthRoutine uInitialize Options(*Redefine)
Invoke #EmployeeManager.RegisterInitialize Filter(#Com_Owner)
Endroutine
コマンド・ハンドラーで次の処理を行います。
MthRoutine uInitialize Options(*Redefine)
Invoke #EmployeeManager.RegisterInitialize Handler(#Com_Owner)
Endroutine
· 終了時にインスタンス・リスト・マネージャーに登録(登録削除)する。フィルターで次の処理を行う。
MthRoutine uTerminate Options(*Redefine)
Invoke #EmployeeManager.RegisterTerminate Filter(#Com_Owner)
Endroutine
コマンド・ハンドラーで次の処理を行います。
MthRoutine uTerminate Options(*Redefine)
Invoke #EmployeeManager.RegisterTerminate Handler(#Com_Owner)
Endroutine
これでインスタンス・リスト・マネージャーは、ビジネス・オブジェクトに関する処理を実行しているすべてのアクティブなフィルターとコマンド・ハンドラーを認識します。
インスタンス・リスト・マネージャーは共通の共有操作の代行を開始できます。
たとえば、インスタンス・リスト・マネージャーに次のようなイベント・ルーチンが含まれている場合を考えます。
Evtroutine Handling(#ActiveFilters<>.avEvent) WithId(#EventId) WithAInfo1(#AInfo1) WithAInfo2(#AInfo2) WithAInfo3(#AInfo3) COM_Sender(#SendingFilter) Options(*NOCLEARMESSAGES *NOCLEARERRORS)
Case #EventId.Value
When (= UPDATE_EMPLOYEE_5250)
#Com_Owner.UpdateListDetails ListManager(#SendingFilter.avListManager) ForEmpno(#AInfo1)
When (= DELETE_EMPLOYEE_5250)
#Com_Owner.DeleteListDetails ListManager(#SendingFilter.avListManager) ForEmpno(#AInfo1) inDepartment(#AInfo2) InSection(#AInfo3)
EndCase
Endroutine
インスタンス・リスト・マネージャーは、すべてのフィルターの、RAMPスクリプトのイベントをリッスンするジョブを引き継ぎます。これで、特定のフィルターにこのリッスン・コードを追加する必要はなくなります。
#ActiveFilters<>.avEventの使用は特殊です。このインスタンス・リスト・マネージャーのイベント・ルーチンは、そのインスタンス・リスト・マネージャーに登録されているすべてのフィルターをリッスン(つまり傍受)しています。もちろん、#ActiveHandlers<>を使用しても同じ処理を行えます。
その一方で、インスタンス・リスト・マネージャーはイベントをすべてのアクティブなフィルターとコマンド・ハンドラーに通知することができます。通常以下のように処理します。
まず、インスタンス・リスト・マネージャーに通知するイベントとメソッドを次のように定義します。
Define_Evt EmployeeUpdate
Define_map *input #Empno #EmployeeNumber
Define_Evt EmployeeDelete
Define_map *input #Empno #EmployeeNumber
Mthroutine Sig_EmployeeUpdate
Define_map *input #Empno #EmployeeNumber
Signal EmployeeUpdate EmployeeNumber(#EmployeeNumber)
Endroutine
Mthroutine Sig_EmployeeDelete
Define_map *input #Empno #EmployeeNumber
Signal EmployeeDelete EmployeeNumber(#EmployeeNumber)
Endroutine
次に、これらのイベントが発生した時に通知を受けるすべてのフィルターまたはコマンド・ハンドラーに、次のようなイベント処理ルーチンを組み込みリッスンを行います。
Evtroutine Handling(#EmployeeManager.EmployeeUpdate) EmployeeNumber(#EmployeeNUmber) Options(*NOCLEARMESSAGES *NOCLEARERRORS)
Use Message_box_show (ok ok info *Component ("I have just been notified that employee number " + #EmployeeNumber + " has been updated"))
Endroutine
Evtroutine Handling(#EmployeeManager.EmployeeDelete) EmployeeNumber(#EmployeeNUmber) Options(*NOCLEARMESSAGES *NOCLEARERRORS)
Use Message_box_show (ok ok info *Component ("I have just been notified that employee number " + #EmployeeNumber + " has been deleted"))
Endroutine
最後に、他のものにイベントを伝える(または起動する、通知する)フィルターまたはコマンド・ハンドラーで、次のような処理を行う必要があります。
#EmployeeManager.Sig_EmployeeUpdate EmployeeNumber(#Empno)
また、
#EmployeeManager.Sig_EmployeeDelete EmployeeNumber(#Empno)