Stefan Dobreさんによるこちらの記事 How to dynamically compute Interactive Grid Columns in #orclAPEX 20.2 の紹介です。
記事に記載されている実装を行うことで、理解してみました。色々と応用ができますし、同様の処理を大量の動的アクションで実装していた方は、ずっと分かりやすく書き換えることができるでしょう。
この機能は、Oracle APEXを20.2以降よりサポートされています。
以下が確認作業の順番です。
- 表とアプリケーションの作成
- CSVファイルのロード
- 計算によって導出される列を、対話グリッドのSQLに追加
- 対話グリッド上で、列の計算を行うコードを追加
1から2までは準備作業になります。Oracle APEXによるアプリケーション作成について経験のある方にとっては、冗長かもしれません。
表とアプリケーションの作成
サンプルの受注一覧のデータより、商品(PRODUCT_NAME)の価格(PRICE)と数量(QUANTITY)より、売り上げ(REVENUE)を計算します。売り上げは
REVENUE = PRICE * QUANTITY
として計算するため、表の列には含みません。
クイックSQLに与える設定は、以下とします。
# prefix: dmt
orders
product_name vc255 /nn
price num
quantity num
SQLワークショップよりクイックSQLを開き、左側に上記のモデルを入力します。
SQLの生成、SQLスクリプトを保存、レビューおよび実行を順次実行します。
SQLスクリプトが開きます。DDLの変更は不要なので、そのまま実行します。確認画面が開くので、即時実行をクリックします。
表DMT_ORDERSが作成されます。続けてアプリケーション作成を実行します。
アプリケーション作成ウィザードが起動します。
作成するアプリケーションの名前は対話グリッドの計算とします。デフォルトで追加されているページをすべて削除し(編集をクリックして削除を実行)、代わりにページの追加をクリックして対話グリッドを追加します。
対話グリッドのページ名も対話グリッドの計算とします。表またはビュー、編集を許可を選択し、表またはビューとして表DMT_ORDERSを選択します。
ページの追加をクリックします。
以上の設定を行い、アプリケーションの作成を実行します。
アプリケーションが作成されます。今回の作業はページ番号1の対話グリッドの計算のページに対して実施します。
CSVファイルのロード
ロードするCSVファイルを、以下よりダウンロードします。
https://apex.oracle.com/pls/apex/japancommunity/r/simcontents/download?id=SampleOrders.csv
次にSQLワークショップのユーティリティより、データ・ワークショップを開きます。データのロードをクリックして開きます。
ファイルのアップロード(デフォルトで選択されています)より、ファイルの選択をクリックして、先ほどダウンロードしたSampleOrders.csvを選択します。
データのロードを行う前に、構成をクリックします。
受注番号のマップ先としてID(Number)、製品はPRODUCT_NAME(Varchar2)、単価はPRICE(Number)、数量はQUANTITY(Number)を指定します。単価と数量にはグループ・セパレータとして,(カンマ)、小数点文字として.(ピリオド)を指定します。私がテストしたときは、小数点文字のデフォルトが,(カンマ)になっていたので、設定変更は必須です。
表DMT_ORDERSに含まれる4つの列をマップして、変更の保存を行います。
103行のデータがロードされていれば、ロードは成功です。続けてアプリケーションの作成を実行します。
列REVENUEをSQLに追加
対話グリッドのページをページ・デザイナで開き、対話グリッドのリージョンを左ペインより選択します。ソースのタイプをSQL問合せに切り替え、SQL問合せを以下の列REVENUEを追加したものに更新します。
select ID,
PRODUCT_NAME,
PRICE,
QUANTITY,
NVL(PRICE,0) * NVL(QUANTITY,0) as REVENUE
from DMT_ORDERS
列REVENUEが追加されます。元記事によると、今回のソリューションは編集可能な列にのみ適用可能なので、タイプを表示のみに設定することは不可です。しかし、列REVENUEは計算された結果でありユーザーからの入力は禁止したいので、外観のCSSクラスにis-readonlyを指定します。また、データベースのアップデート操作に含まれないよう問合せのみをONにします。
変更を保存して、ページを実行します。
この状態で列Price、Quantityを変更して、保存をクリックすると列Revenueに計算結果が反映されることが確認できます。
次に、保存をクリックせず、PriceやQuantityを変更するとすぐにRevenueが更新される実装を行います。
対話グリッド上の列の計算
Oracle APEX 20.2から利用可能になったcalcValueとdependsOnの機能を使用します。
列REVENUEのプロパティである詳細の列初期化JavaScriptファンクションに以下を記述します。
dependsOnとして、この列REVENUEが依存している列を指定します。REVENUEはPRICEとQUANTITYの積なので、dependsOnはPRICEとQUANTITYになります。
dependsOnで指定された列、PRICEまたはQUANTITYが変更されたときに呼び出されるファンクションをcalcValueとして記述します。戻り値が列REVENUEの値になります。
以上のコードを設定して、期待した動作になるか確認してみましょう。列REVENUEを計算しているJavaScriptのコードの部分については、理解が難しいところはないかと思います。
おまけ:書式マスクについて
数値列である列PRICEとQUANTITYに以下のような書式マスクの設定がされていると、3桁ごとに区切り文字として,(カンマ)が含まれます。
999G999G999G999G999G999G999G999G999G990
このままではparseInt()で適切な整数として変換されないので、replaceAll(",","")でカンマを取り除いています。
対話グリッドの計算結果としても,(カンマ)を含めるには、Intl.NumberFormatを使って以下のように記述することで対応できます。
以上で、対話グリッドの列の計算方法の紹介は終了です。
今回作成したアプリケーションのエクスポートを以下に置きました。https://github.com/ujnak/apexapps/blob/master/exports/calcvalue-interactive-grids.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完