2022年1月31日月曜日

プラグインのコンポーネント設定を参照する

 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に、フロー・モデル名を設定します。アプリケーション内でG_FLOW_NAMEを参照するときはいつでも、コンポーネント設定Global Flowの値を返すようにします。

共有コンポーネントアプリケーションの計算を開きます。


作成をクリックします。


計算アイテムとしてG_FLOW_NAMEを選択します。頻度の計算ポイントとして新規インスタンス(新規セッション)開始時を選択します。

この頻度であれば、コンポーネント設定Global Flowが変更されると、経費精算のアプリケーションは一旦サインアウトしてセッションを終了したのち、サインインをやり直して新規セッションを開始して初めて、変更されたGlobal FlowG_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のアプリケーション作成の参考になれば幸いです。