2022年3月16日水曜日

複数の値を扱うポップアップLOVを使ったカスケードLOVの実装

 以前に書いたカスケードLOVの実装を元にして、複数の値が扱えるポップアップLOVを使ったカスケードLOVを実装してみました。

以下に実装手順を記載します。

最初にテスト用の表CLOV_PROJECTSCLOV_DEPTCLOV_EMPを作成し、テストに使うデータも生成します。

SQLワークショップユーティリティクイックSQLに以下のモデルを与え、実装に使用する表とデータを準備します。

# prefix: clov
# language: ja
# genpk: false
projects /insert 3
id num /nn
name

dept /insert 9
id num /nn
name

emp /insert 27
id num /nn
project_id num /nn /values 1,2,3
dept_id num /nn /values 1,2,3,4,5,6,7,8,9
name

SQLの生成SQLスクリプトを保存レビューおよび実行を順番に実行します。表の作成までを実施し、アプリケーションの作成は行いません。

表が作成されたらアプリケーション作成ウィザードを実行し、空のアプリケーションを作成します。名前はMultivalue Cascade LOVとします。アプリケーションの作成を実行します。


アプリケーションが作成されたら、共有コンポーネントを開いてLOVの作成を行います。


LOVを開きます。


作成済みのLOVの一覧が表示されます。作成をクリックします。


最初に表CLOV_PROJECTSから個々のプロジェクトを選択するLOV、LOV_PROJECTSを作成します。

LOVの作成最初からを選択します。

へ進みます。


名前LOV_PROJECTSとし、タイプDynamicを選択します。

へ進みます。


LOVソースデータ・ソースとしてローカル・データベースソース・タイプとしてTableを選択します。表/ビューの名前としてCLOV_PROJECTS (表)を選択します。

へ進みます。


戻り列をID、表示列NAMEとして、作成をクリックします。


LOV_PROJECTSが作成されます。追加表示列を設定しポップアップLOVに列IDとNAMEの両方を表示させるため、LOV_PROJECTSを開いて編集します。


追加表示列列の選択をクリックします。


ID (Number)NAME (Varchar2) 追加表示列として選択し、更新をクリックします。


追加表示列としてIDとNAMEが追加されます。ID表示可能をNoからYes検索可能をオフからオンに変更します。


以上の変更を行なったのち、変更の適用をクリックします。


以上でLOV_PROJECTSが作成できました。

同様の手順で表CLOV_DEPTから個々の部門を選択するLOV、LOV_DEPTSを作成します。

LOVソース表/ビューの名前としてCLOV_DEPT (表)を選択します。


追加表示列としてIDNAMEを選択し、すべて表示可能検索可能とします。


最後に従業員を選択するLOV、LOV_EMPを作成します。

LOVソースソース・タイプSQL Queryを選択し、SQL SELECT文を入力に以下を記述します。

select
e.id
, e.name employee_name
, p.name project_name
, d.name department_name
from clov_emp e
join clov_projects p on e.project_id = p.id
join clov_dept d on e.dept_id = d.id
where
project_id in (select column_value from apex_string.split(:P1_PROJECT,':'))
and
dept_id in (select column_value from apex_string.split(:P1_DEPT,':'))

選択済みのプロジェクト(ページ・アイテムP1_PROJECT)や部門(ページ・アイテムP1_DEPT)に従って、対象を限定します。また、これらは':'で区切られた複数の値を持つ予定なので、apex_string.splitを使って値を分割しています。

へ進みます。


戻り列IDであることを確認して、作成をクリックします。追加表示列は後ほど設定します。


検索されたすべての列を、追加表示列にします。


以上で共有コンポーネントのLOVの準備は完了です。

これより、これらのLOVを使ったページ・アイテムを作成します。

ページ・デザイナでホーム・ページを開き、リージョンを作成します。

識別名前Cascade LOVとし、タイプ静的コンテンツを選びます。


プロジェクトを選択するページ・アイテムP1_PROJECTを作成します。

識別名前P1_PROJECTタイプポップアップLOVを選択し、ラベルプロジェクトとします。設定複数の値ONにします。

LOVタイプ共有コンポーネントを選択し、LOVとしてLOV_PROJECTSを指定します。追加値の表示NULL値の表示は共にOFFを設定します。


同様に、部門を選択するページ・アイテムP1_DEPTを作成します。ラベル部門とし、LOVにはLOV_DEPTを選択します。


同様に、従業員を選択するページ・アイテムP1_EMPを作成します。ラベル従業員とし、LOVにはLOV_EMPを選択します。

従業員の一覧は選択済みのプロジェクトと部門によって絞り込みを行うため、カスケードLOV親アイテムとして、P1_PROJECTP1_DEPTを指定します。


以上で複数の値を扱うポップアップLOVを使ったカスケードLOVが実装できました。

ページ・アイテムP1_EMPに選択した従業員のIDが':'で区切られて設定されます。レポートの検索条件として使う際には、以下のようにapex_string.splitを使って分割し、条件として指定すると良いでしょう。

emp_id in (select column_value from apex_string.split(:P1_EMP,':'))

今回作成したアプリケーションのエクスポートを以下に置きました。表のDDLはエクスポートに含まれていますが、テスト用のデータは含まれていません。
https://github.com/ujnak/apexapps/blob/master/exports/multivalue-cascade-lov.sql

Oracle APEXのアプリケーション作成の参考になれば幸いです。

追記


このLOVを使った検索のサンプルを実装してみました。検索対象として表CLOV_SAMPLESを作成します。クイックSQLの以下のモデルを使います。

# prefix: clov
# language: ja
samples /insert 100
emp_id /values 1,2,3,4,5,6,7,8,9,10
label /values A,B,C,D,E
size1 /values 大,中,小
region /values 北海道,東北,関東,北陸,中部,近畿,中国,四国,九州,沖縄


表CLOV_SAMPLESの列EMP_IDに、表CLOV_EMPの列IDへの参照制約CLOV_SAMPLES_FKを作成します。

alter table clov_samples add constraint clov_samples_fk foreign key (emp_id) references clov_emp(id);


参照制約を設定した列EMP_IDに、索引CLOV_SAMPLES_EMP_IDXを作成します。

create index clov_samples_emp_idx on clov_samples(emp_id);


LOVのページ・アイテムを検索条件にして、表CLOV_SAMPLESを一覧するレポートを作成します。

Content Bodyに新たにリージョンを作成します。

識別名前検索サンプルとします。タイプには対話モード・レポートを選択します。ソースタイプSQL問合せとし、SQL問合せとして以下を記述します。

検索条件として従業員が選択されていない場合、部門とプロジェクトの選択を元に検索をしています。

select
s.label
, s.size1
, s.region
, e.name employee_name
, d.name department_name
, p.name project_name
from clov_emp e
join clov_samples s on e.id = s.emp_id
join clov_dept d on e.dept_id = d.id
join clov_projects p on e.project_id = p.id
where 1=1
and
(
(
:P1_EMP is null
and
(
:P1_DEPT is null
or
e.dept_id in (select column_value from apex_string.split(:P1_DEPT,':'))
)
and
(
:P1_PROJECT is null
or
e.project_id in (select column_value from apex_string.split(:P1_PROJECT,':'))
)
)
or
s.emp_id in (select column_value from apex_string.split(:P1_EMP,':'))
)


検索を実行するボタンを作成します。

識別ボタン名B_SUBMITラベル検索とします。動作アクションはデフォルトのページの送信のまま変更しません。ボタンの見栄えを良くするため、外観ホットONにし、テンプレート・オプションを開いて詳細WidthStretchに変更します。


以上で検索のサンプルとなるレポートの追加は完了です。

アプリケーションを実行すると、以下のような動作を確認できます。


リージョンを追加したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/multivalue-cascade-lov-samples.sql

Oracle APEXのアプリケーション作成の参考になれば幸いです。