Flows for APEXを使って経費精算のアプリケーションを作っている際に、SELECT文を以下のように書いていました。
select
expe.expe_id
, expe.expe_justification
, expe.expe_amount
, expe.expe_status
, expe.expe_submitted_on
, expe.expe_invoice_dd
, expe.expe_purpose
, inst.prcs_id
, tibx.sbfl_id
from expe_expenses expe
join flow_instances_vw inst on expe.expe_id = inst.prcs_business_ref
left join flow_task_inbox_vw tibx on expe.expe_id = tibx.sbfl_business_ref
where inst.dgrm_name = '経費精算'
and (tibx.sbfl_dgrm_name = '経費精算' or tibx.sbfl_dgrm_name is null)
and expe.expe_submitted_by = :APP_USER
SELECT文にフロー・モデル名が直書きされています。フロー・モデル名をバインド変数に置き換える方法について考えてみます。フロー・モデル名をG_FLOW_NAMEというバインド変数に置き換え、結果として以下のSELECT文に置き換えます。
select
expe.expe_id
, expe.expe_justification
, expe.expe_amount
, expe.expe_status
, expe.expe_submitted_on
, expe.expe_invoice_dd
, expe.expe_purpose
, inst.prcs_id
, tibx.sbfl_id
from expe_expenses expe
join flow_instances_vw inst on expe.expe_id = inst.prcs_business_ref
left join flow_task_inbox_vw tibx on expe.expe_id = tibx.sbfl_business_ref
where inst.dgrm_name = :G_FLOW_NAME
and (tibx.sbfl_dgrm_name = :G_FLOW_NAME or tibx.sbfl_dgrm_name is null)
and expe.expe_submitted_by = :APP_USER
経費精算のアプリケーションが使用するフロー・モデルは、プラグインのコンポーネント設定のGlobal Flowとして定義されています。
バインド変数として使用するG_FLOW_NAMEは、アプリケーション・アイテムとして定義します。
共有コンポーネントのアプリケーション・アイテムを開きます。
名前として、G_FLOW_NAMEを入力します。セキュリティのセッション・ステート保護はデフォルトの制限付き - ブラウザから設定不可のままにします。一番、厳しい制限になります。以上の設定で、アプリケーション・アイテムの作成をクリックします。
アプリケーション・アイテムG_FLOW_NAMEが作成されます。
作成したアプリケーション・アイテムG_FLOW_NAMEに、フロー・モデル名を設定します。アプリケーション内でG_FLOW_NAMEを参照するときはいつでも、コンポーネント設定のGlobal Flowの値を返すようにします。
共有コンポーネントのアプリケーションの計算を開きます。
計算アイテムとしてG_FLOW_NAMEを選択します。頻度の計算ポイントとして新規インスタンス(新規セッション)開始時を選択します。
この頻度であれば、コンポーネント設定のGlobal Flowが変更されると、経費精算のアプリケーションは一旦サインアウトしてセッションを終了したのち、サインインをやり直して新規セッションを開始して初めて、変更されたGlobal FlowがG_FLOW_NAMEに反映されます。実際にはGlobal Flowの変更はほとんど行わないので、一番頻度が少なく(つまり実行回数が少ない)データベースに負荷がかからない設定を選択します。
計算の計算タイプにファンクション本体を選択します。言語はPL/SQLとして、以下のコードを計算に記述します。
declare
l_pos integer;
l_flow_name APEX_APPL_PLUGIN_SETTINGS.ATTRIBUTE_01%type;
begin
select attribute_01 into l_flow_name
from APEX_APPL_PLUGIN_SETTINGS
where application_id = :APP_ID
and plugin_code = 'PLUGIN_COM.FLOWS4APEX.MANAGE_INSTANCE.PROCESS';
l_pos := instr(l_flow_name,',');
if l_pos > 0 then
-- カンマがあれば、それに続くバージョンを取り除く。
l_flow_name := substr(l_flow_name,1,(l_pos-1));
end if;
return l_flow_name;
exception
when no_data_found then
/*
* Global Flowが設定されていないので、アプリケーション・アイテムは設定しない。
*/
return null;
end;
コンポーネント設定のGlobal Flowの値は、APEXの標準ビューAPEX_APPL_PLUGIN_SETTINGSの列ATTRIBUTE_01から取り出します。また、Global Flowはバージョンを含む場合があります。設定に, (カンマ)が含まれる場合は、バージョンの部分を取り除き、フロー・モデル名だけを取り出します。
以上の設定を行い、計算の作成を実行します。
アプリケーションの計算が作成されます。
以上でアプリケーション・アイテムG_FLOW_NAMEをバインド変数として扱うときはいつでも、コンポーネント設定のGlobal Flowが参照されるようになりました。
実際に設定されているかどうか確認するために、アプリケーションにサインインします。開発者ツール・バーより、セッションを実行します。
ビューとしてアプリケーション・アイテムを選択し設定をクリックすると、現在のセッションで設定されているG_FLOW_NAMEの値が表示されます。
バインド変数の設定は以上になります。
今回の作業中で気がついた点を追記しておきます。
プラグインを他のアプリケーションからコピーして作成する場合、コピーしますか?の指定で、はい(コピーのみ)とコピーおよびサブスクライブを選ぶことができます。
コピーしますか?にはいを選択した画面です。
コピーおよびサブスクライブを選択した画面です。
コピーおよびサブスクライブを選択した場合、単にプラグインがコピーされるだけではなく、コピー元のプラグインに紐づけられた状態になります。
プラグインの設定画面のサブスクリプションのマスター・プラグインの参照元として、コピーと元のプラグインが設定されます。コピー元のプラグインに変更があった場合、プラグインのリフレッシュを実行することにより、その変更をコピーとして作成されている、このプラグインに反映することができます。
コピーおよびサブスクライブを指定してプラグインを作成した場合、デフォルトではコンポーネント設定の画面で変更の適用のボタンが表示されません。
サブスクライブしているプラグインで個別にコンポーネント設定を行うには、コンポーネント設定のサブスクライブをOFFにします。
コンポーネント設定のサブスクライブをOFFにすると、サブスクライブしているプラグインごとにコンポーネント設定を行うことができます。
今回の記事は以上です。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完