2022年6月27日月曜日

ページ・アイテムのリフレッシュを代替する方法

タイプ表示のみで、ソースタイプSQL問合せ(単一の値を返す)としたページ・アイテムの表示をリフレッシュしたい、との相談がありました。

動的アクションリフレッシュがあり設定すればできそうなのですが、リフレッシュに対応しているコンポーネントは限定されています。

タイプが表示のみのページ・アイテムはリフレッシュに対応していないようです。

ページ・アイテムのタイプ表示のみソースタイプSQL問合せ(単一の値を返す)SQL問合せは以下としています。

select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') from dual

ボタンをクリックしたときに、ページ・アイテムにそのときの時刻を表示します。


ボタンのアクションとして、動的アクションで定義を選択します。


動的アクションが実行されるタイミングは、ボタンのデフォルトであるクリックです。


リフレッシュ表示のみのページ・アイテムには効きません。


今回の例であればTRUEアクションとして、サーバー側のコードを実行に置き換えることで実現できます。

設定PL/SQLコードに以下を記述します。

select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') into :P1_DATE from dual;

戻すアイテムとしてP1_DATEを設定します。


今回の例であればページ・アイテムにソースの設定があるため、初期化時に実行OFFでも問題ありません。ページが表示されるときにページ・アイテムに値が設定されない場合は、初期化時に実行はONにすることも検討が必要です。

以上になります。

簡単なアプリですが、今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/refresh-page-item.sql

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

2022年6月22日水曜日

ナビゲーション・メニューを動的に生成する

 標準的なOracle APEXアプリケーションでは、画面左にナビゲーション・メニューが表示されます。このナビゲーション・メニューは、SSELECT文の検索結果より動的に生成することができます。

以下は実装例です。サンプル・データセットEMP/DEPTに含まれる表EMPとDEPTから、ナビゲーション・メニューを生成しています。


ナビゲーション・メニューは、共有コンポーネントリストとして作成されます。タイプ動的であれば、SQLで実装されたリストになります。


ユーザー・インターフェースナビゲーション・メニューとして、共有コンポーネントリストを選択します。以下では、動的ナビゲーションナビゲーション・メニュー・リストとして設定しています。


リストである動的ナビゲーションのSELECT文は以下になります。動的リストに関するマニュアルの説明は、こちらになります。

以下より、実行例になっているアプリケーションの作成手順を紹介します。

サンプル・データセットEMP/DEPTがインストール済みで、表EMPDEPTおよびビューEMP_DEPT_Vが利用可能になっているのが前提条件です。

アプリケーション作成ウィザードを起動します。アプリケーションの名前動的ナビゲーション・メニューとします。

ホーム編集を開いて、ホーム・ページを削除します。


クラシック・レポートのページを追加します。

ページの追加をクリックします。


追加ページを開いて、クラシック・レポートを選択します。


ページ名従業員一覧表またはビューとしてEMP_DEPT_Vを選択します。レポートだけで編集はしないため、フォームを含めるチェックしません

ページの追加を実行します。


ページ従業員一覧だけを含むアプリケーションを作成します。

アプリケーションの作成を実行します。


アプリケーションが作成されます。


ナビゲーション・メニューは、アプリケーション全体で使用されます。そのため、検索条件には(ページ・アイテムではなく)アプリケーション・アイテムを使用します。

共有コンポーネントアプリケーション・アイテムを開きます。


作成済みのアプリケーション・アイテムが一覧されます。作成をクリックします。


作成するアプリケーション・アイテムの名前G_DNAMEとします。有効範囲アプリケーションセキュリティセッション・ステート保護として、チェックサムが必要 - セッション・レベルを選択します。

ナビゲーション・メニューのリンクにアプリケーション・アイテムG_DNAMEに設定する値を含めます。そのため、セッション・ステート保護制限付き - ブラウザから設定不可とすると、値が設定できません

以上で、アプリケーション・アイテムの作成を実行します。


同様の手順にて、アプリケーション・アイテムG_JOBを作成します。

2つのアプリケーション・アイテムG_DNAMEG_JOBが作成されます。


ホーム・ページを開き、クラシック・レポートの検索条件に使用するページ・アイテムP1_DNAMEおよびP1_JOBを作成します。双方とも、アプリケーション・アイテムをソースとします。

クラシック・レポートのリージョンに、ページ・アイテムを作成します。

識別名前P1_DNAMEタイプ非表示とします。ソースタイプアイテムを選択し、アイテムとしてG_DNAMEを指定します。セッション・ステートの保持リクエストごと(メモリーのみ)を選択します。


同様の手順でページ・アイテムP1_JOBを作成します。ソースとなるアプリケーション・アイテムはG_JOBです。


クラシック・レポートに、上記の2つのページ・アイテムを使用した検索条件を設定します。ソースWHERE句に以下を記述します。
(
    :P1_DNAME is null
    or
    :P1_DNAME = dname
)
and
(
    :P1_JOB is null
    or
    :P1_JOB = job
)

最後にナビゲーション・メニューとなるリストを作成します。

共有コンポーネントリストを開きます。


作成済みのリストが一覧されます。作成をクリックします。


リストの作成最初からのままにします。へ進みます。


名前動的ナビゲーションとし、タイプとして動的を選択します。

へ進みます。


問合せソース・タイプとしてSQL問合せを選択し、SQL問合せに前出のSQLを記述します。

へ進みます。


作成するリストはナビゲーションに使います。そのため、リスト・リージョンを作成しますか。として、リスト・リージョンを作成しないを選択します。

作成をクリックします。


リストとして動的ナビゲーションが作成されます。


ユーザー・インターフェースナビゲーション・メニューナビゲーション・メニュー・リストを、新たに作成したリスト動的ナビゲーションに置き換えます。

変更の適用をクリックします。


以上でアプリケーションは完成です。

アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/dynamic-navigation-menu.sql

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

2022年6月21日火曜日

DBAによるAPEXアプリの作成 - マスター・ディテール関係編

 以前に、ひとつの表をレポートと編集の対象とした、Oracle APEXのアプリケーションを作成する手順について記事を書いています。単にExcelやCSVをアップロードしてアプリケーションを作成するのではなく、あらかじめスキーマを定義することにより、その定義に対応したユーザー・インターフェースが、Oracle APEXのウィザードによって自動生成されます。結果として、より短い時間でアプリケーションが完成します。

対象をひとつの表としているのは少し単純です。本記事では、いわゆるマスター・ディテール関係の表から、Oracle APEXのアプリケーションを作成してみます。

これから行う作業では、Always FreeのAutonomous DatabaseのAPEX 21.2.6を使います。

データ・ソースとして、CSVのサンプルとして提供されているプロジェクトとタスクを使います。

アプリケーション・ビルダーを開いてアプリケーションの作成を実行し、ファイルからを選択します。

データのロードのダイアログが開きます。

コピー・アンド・ペーストを選択し、サンプル・データ・セットとしてプロジェクトとタスクを選択します。

ロードされるデータは、ProjectTask NameStart DateEnd DateStatusAssigned ToCostBudgetです。新規に表をひとつ作成し、このデータをロードします。しかし、本来はProjectを保持するマスター表があり、それに紐づくTaskがディテール表を構成するように、ふたつの表を作成する方がデータの持ち方としては適切に見えます。

本記事では、これからロードするデータをマスター・ディテール関係の表に入れ替えて、Oracle APEXのアプリケーションを作ります。

まずは、その準備作業としてCSVのサンプル・データ・セットをデータベースにロードします。

へ進みます。

データのロード先として新規表を選択し、表名PRJ_TEMPを入力します。ここで作成する表は、マスター・ディテール関係の表にデータを入れ替えるソースとして一時的に使用します。

データのロードを実行します。


73行のデータが新規に作成した表PRJ_TEMPにロードされます。この表を使って、アプリケーションの作成を実行します。マスター・ディテール関係にあるデータを、フラットな表に保存した状態で作成されるアプリケーションを確認します。


アプリケーション作成ウィザードが起動します。

アプリケーションの名前プロジェクト管理 - フラットと入力し、それ以外は変更せずアプリケーションの作成を実行します。


アプリケーションが作成されます。

スキーマ定義の違いの影響を受けるのは、主にデータを編集する作業です。レポートとフォームのページを実行し、操作を確認します。


レポートのページを表示し、データを編集するフォームを開きます。

フォーム上でProject、Task Name、Status、Assigned Toを任意の値で設定することができます。これは望しい状態ではありません。


クイックSQLのモデルを以下のように定義し、データを入れ替える表を作成します。
# prefix: prj
statuses
    status vc20 /nn

members
    member_name vc200 /nn

tasks
    task_name vc200 /nn

projects
    project_name vc200
    project_tasks
        task_id /fk tasks /nn
        start_date
        end_date
        status /fk statuses
        assigned_to /fk members
        cost num
        budget num


ステータスの定義をPRJ_STATUSESメンバーの定義(Assigned_Toに割り当てるメンバー)をPRJ_MEMBERSタスクの定義を保持する表をPRJ_TASKSとし、プロジェクトのマスターをPRJ_PROJECTSディテール表PRJ_PROJECT_TASKSとして、スキーマを定義します。


生成されたDDLが実行されると、5つの表が作成されます。

程度によりますがスキーマ定義に合わせて、元のOracle APEXアプリケーションを修正するのは、手間のかかる上、間違いが発生しやすいです。今回はアプリケーションを新規に作成しますが、すでにアプリケーションが作成されている場合は、新規に作成したページによって、既存のページを置き換えるといった手順が有効でしょう。

これからデータを移行します。アプリケーションの作成は、その後に実施します。


SQLワークショップSQLスクリプトを開き、以下のスクリプトを実行します。
insert into prj_members(member_name) select distinct assigned_to from prj_temp;
insert into prj_statuses(status) select distinct status from prj_temp;
insert into prj_projects(project_name) select distinct project from prj_temp;
insert into prj_tasks(task_name) select distinct task_name from prj_temp;
insert into prj_project_tasks(project_id, task_id, start_date, end_date, status, assigned_to, cost, budget)
select
    (select id from prj_projects pr where pr.project_name = p.project) project_id,
    (select id from prj_tasks tk where tk.task_name = p.task_name) task_id,
    start_date,
    end_date,
    (select id from prj_statuses st where st.status = p.status) status,
    (select id from prj_members mb where mb.member_name = p.assigned_to) assigned_to,
    cost,
    budget
from prj_temp p;
commit;

ひとつの表にアップロードされたCSVのデータが、正規化された表に移行されました。


これから本題である、マスター・ディテール関係の表を元にしたOracle APEXアプリケーションを作成します。

アプリケーション作成ウィザードを起動します。

アプリケーションの名前プロジェクト管理とします。

ページの追加をクリックし、マスター・ディテール関係を元にしたレポートおよび編集フォームのページを追加します。


マスター・ディテールを選択します。


ページの形式として積上げを選択します。積上げを選択すると、マスター表、ディテール表ともに対話グリッドを使った実装になります。ページ名積上げ、(マスター)PRJ_PROJECTSディテール表PRJ_PROJECT_TASKSを指定します。

ページの追加をクリックします。


同様の手順で、形式が左右のページも追加します。

左右では、マスター、ディテールの双方ともクラシック・レポートによって実装されます。編集フォームは別ページのフォームになります。

プライマリ表示列PROJECT_NAMEセカンダリ表示列IDを選択します。セカンダリ表示列にIDを選択するのは適切ではありませんが、表PRJ_PROJECTSはIDとPROJECT_NAMEしか列がないため、IDを選択しています。画面に表示することが適切な列が他にある場合は、それをセカンダリ表示列として設定します。


表のメンテナンスを行う画面を追加します。

ページの追加をクリックします。

追加ページを開き、複数のレポートを選択します。


今回のアプリケーションに関連する表をすべて選択します。表の接頭辞としてPRJ_が付加されている表をすべて選択し、ページの追加をクリックします。


追加されたフォーム付き対話モード・レポートのページは、編集を開いて管理ページに変更します。機能アクセス制御チェックを入れ、これらのページはエンド・ユーザーではなく、管理者向けのページからアクセスできるようにします。


これらの変更を行なった後、アプリケーションの作成を実行します。


アプリケーションが作成されます。

これから作成されたアプリケーションの、ユーザー・インターフェースを調整します。


積上げ形式のマスター・ディテールのレポート/編集ページを開きます。

ディテール表の対話グリッドにて、Task、Status、Assigned ToにIDが表示されています。これを選択リストに変更します。


ページ・デザイナを起動し、列TASK_ID識別タイプ選択リストに変更します。LOVタイプとして共有コンポーネントを選択し、LOVPRJ_TASKS.TASK_NAMEを選択します。追加値の表示OFFにします。


同様に列STATUSタイプ選択リストに変更し、LOVとしてPRJ_STATUSES.STATUSを選択します。列ASSIGNED_TO選択リストに変更し、LOVPRJ_MEMBERS.MEMBER_NAMEを選択します。


列のタイプを選択リストに変更しても、データ・ソースである表から取り出される/保存される列のデータはIDのまま変更されません。あくまでユーザー・インターフェースでの変更になります。

今回の作業では、アプリケーションを作成した際に、共有コンポーネントのLOVがいくつか自動的に作成されています。


これは、生成するページに表PRJ_PROJECT_TASKSの対話モード・レポートを含んでいるためです。アプリケーション作成ウィザードページに、外部キー制約を含む表の対話モード・レポートのページが追加されていると、外部キー制約を元に共有コンポーネントのLOVが作成されます。

形式が左右のマスター・ディテールのページを確認します。

Task、Status、Assigned ToがIDで表示されているので、これらをLOVに基づく表示に変更します。


ページ・デザイナを開き、列TASK_IDタイププレーン・テキスト(LOVに基づく)に変更します。LOVタイプ共有コンポーネントLOVとしてPRJ_TASKS.TASK_NAMEを選択します。


同様に、列STATUSLOVとしてPRJ_STATUSES.STATUS、列ASSIGNED_TOPRJ_MEMBERS.MEMBER_NAMEに基づいた表示になるように変更します。

以上で、IDによる表示が名前に置き換えられます。


編集フォームは、共有コンポーネントのLOVを使用するようになっているため、変更は不要です。


マスター・ディテール関係の表を扱うOracle APEXアプリを、ウィザードを使って作成する手順の解説は以上になります。

マスター・ディテールのサンプルは、Oracle APEXのギャラリーサンプルに含まれています。



公式のサンプルは、もっと凝った実装になっています。

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