レポートとしてはひとつに見えるけど、編集するにあたっては異なるフォームを開きたい、という話があったので実装してみました。
以下、作業ログです。
クイックSQLにて、以下の表DFM_USER_CATEGORY_AとDFM_USER_CATEGORY_Iのふたつを定義します。
# prefix: dfm
# semantics: default
user_category_a
name vc80 /nn
hobby vc20
hours_in_day num
user_category_i
name vc80 /nn
school vc80
hours_in_day num
レポートとしては上記の表をUNIONして表示します。それぞれの行に編集リンクをつけて、表DFM_USER_CATEGORY_Aの内容であれば、その表を編集するフォーム(を含んだページ)を開き、表DFM_USER_CATEGORY_Iの内容であれば、別のフォーム(同じく、ページ)を開きます。
最初に上記のクイックSQLのモデルから表を作成します。SQLワークショップからユーティリティに含まれるクイックSQLを実行します。
最初にモデルを左ペインにペーストし、SQLの生成を実行します。続いてSQLスクリプトを保存し、レビューおよび実行をクリックします。
実行するSQLのレビュー画面が表示されます。実行をクリックします。生成されたSQLに少々問題がありました。双方の表を生成するDDLがともに、主キー制約名がdfm_user_category_id_pkとなるため、表DFM_USER_CATEGORY_Iの作成時にエラーが発生します。それぞれ、dfm_user_category_a_id_pk、dfm_user_category_i_id_pkに主キー制約名を変更したのち、実行します。
即時実行します。
表が2つ作成されたのを確認します。続いて、アプリケーションの作成をクリックし、アプリケーション作成ウィザードを呼び出します。
確認画面が開くので、アプリケーションの作成をクリックします。
アプリケーションの名前を異なるフォームを開くと設定し、アプリケーションの作成を実行します。表DFM_USER_CATEGORY_A、DFM_USER_CATEGORY_Iをそれぞれ編集するフォームのリージョンを含んだページは、アプリケーション作成ウィザードが作成してくれます。
アプリケーションが作成されます。表DFM_USER_CATEGORY_Aを編集するフォームはページ番号3、表DFM_USER_CATEGORY_Iを編集するフォームはページ番号5で作成されていることが確認できます。
両方の表を対象とした対話モード・レポートのページを作成します。ページの作成をクリックします。
コンポーネントの
レポートを選択します。
ページ名は合成レポートとし、ブレッドクラムとしてBreadcrumbを選択します。次に進みます。
ナビゲーションのプリファレンスとして新規ナビゲーション・メニュー・エントリの作成を選択し、次に進みます。
データ・ソースはローカル・データベース、ソース・タイプはSQL問合せとします。今回の肝であるSQL SELECT文を入力として、以下を設定します。作成をクリックします。APIのAPEX_PAGE.GET_URLを呼び出すことにより、それぞれの行を編集する(異なった)ページへのリンクを生成します。
select 'A' || id row_key,
apex_page.get_url(p_page => 3, p_items => 'P3_ID', p_values => id) link,
name,
hobby subject,
hours_in_day
from dfm_user_category_a
union
select 'I' || id row_key,
apex_page.get_url(p_page => 5, p_items => 'P5_ID', p_values => id) link,
name,
school subject,
hours_in_day
from dfm_user_category_i
ページが作成されたら、一旦、実行してみます。
データが無いので何も表示されません。サイド・メニューよりUser Category A、User Category Iを開いてテスト用のデータを投入します。データは何でもかまいません。
またはSQLコマンドより以下を実行します。
begin
insert into dfm_user_category_a(name, hobby, hours_in_day) values('太郎', 'ネット', 2);
insert into dfm_user_category_a(name, hobby, hours_in_day) values('花子', '野球', 3);
insert into dfm_user_category_a(name, hobby, hours_in_day) values('健一', 'サッカー', 1);
insert into dfm_user_category_i(name, school, hours_in_day) values('洋子', '小学校', 4);
insert into dfm_user_category_i(name, school, hours_in_day) values('大介', '中学校', 5);
insert into dfm_user_category_i(name, school, hours_in_day) values('二郎', '高校', 5);
commit;
end;
Linkが非常に長く表示されています。これはHTMLのAタグのHREF属性として与えられる文字列になります。遷移先のページがダイアログの場合は、URLではなくJavaScriptのコードを実行することにより、ページ遷移が行われます。ページ・デザイナにて対話モード・レポートのページを開き、修正を加えます。
最初に列ROW_KEYとLINKを選択し、タイプを非表示に変更します。これで、双方の列がレポートに表示されなくなります。
続いて対話モード・レポートのリージョンを選択し、プロパティ・エディタでAttributesタブを開きます。
リンク列としてカスタム・ターゲットへのリンクを選択し、リンク・アイコンに以下を指定します。デフォルトで選択される写実的な鉛筆アイコンでもよいのですが、FontAPEXの鉛筆アイコンに変更します。
<span class="fa fa-edit" aria-hidden="true"></span>
ターゲットをクリックして、ターゲットを設定します。ターゲットのタイプはURLを選択し、URLには#LINK#、つまりSQLのSELECT文の結果として、列LINKとして返される値を使用します。
変更を保存して、ページを実行します。基本的なレポートとしての表示はできています。
編集アイコンをクリックし、異なる表を対象としたフォームが開くことと、データの編集ができることを確認します。
適当なエントリを選択し、データを変更します。
データを変更しても、対話モード・レポートに変更が反映されません。
これはダイアログが閉じたときに、対話モード・レポートがリフレッシュされないためです。ブラウザでページをリロードすると、データが更新されていることを確認できます。
対話モード・レポートに動的アクションを追加し、リージョンのリフレッシュを行うようにします。
左ペインで動的アクション・ビューを開き、イベントとしてダイアログのクローズで起動する動的アクションを作成します。動的アクションの名前は任意ですが、ダイアログのクローズとしています。選択タイプはリージョン、リージョンとして合成レポートを選択します。
Trueアクションとして、アクションがリフレッシュ、選択タイプはリージョン、リージョンとして合成レポートを選択します。
以上の設定で、対話モード・レポートから開いたフォームを閉じた時に、対話モード・レポートがリフレッシュされます。
最後に新規行を作成するボタンを追加します。これはどちらの表に作成するのかをあらかじめ決まっている必要があるので、2つのボタンを作成します。
表DFM_USER_CATEGORY_Aへ新規行を作成するボタンとして、ボタン名をB_CREATE_A、ラベルを作成Aとします。ボタン位置は対話モード・レポートの検索バーの右を選択します。
動作のアクションとして、このアプリケーションのページにリダイレクトを選択し、ターゲットを設定します。ページは3、主キーのアイテムはP3_ID、キャッシュのクリアには3を設定します。
表DFM_USER_CATEGORY_Iに新規行を作成するボタンも同様に作成します。ボタン名をB_CREATE_I、ラベルを作成Iとします。ボタン位置は対話モード・レポートの検索バーの右を選択します。
動作のアクションとして、このアプリケーションのページにリダイレクトを選択し、ターゲットを設定します。ページは5、主キーのアイテムはP5_ID、キャッシュのクリアには5を設定します。
以上でアプリケーションは完成しました。
アプリケーションを実行すると、最初のGIF動画にあるような動きをします。
作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/multiforms.sql
Oracle APEXのアプリケーション作成の一助になれば幸いです。