2022年2月1日火曜日

経費精算アプリの見栄え改善で気のついたこと

 Flows for APEXを使って作った経費精算のAPEXアプリケーションをデモ・アプリケーションとして公開するにあたり、見栄えを少々改善しました。

https://apex.oracle.com/pls/apex/japancommunity/r/expenseclaim/

作業中に気がついたことをメモします。


プロセス変数を設定するプラグインで通貨を扱えない


経費精算を申請する画面を以下のように整えてみました。

支払額を入力するページ・アイテムの書式マスクとして、金額を表す

FM$999G999G999G999G990D00

を設定しています。

こうすると、ORA-6502が発生しました。

ORA-06502: PL/SQL: 数値または値のエラー: 文字から数値への変換エラー。が発生しました

Flows for APEXが提供しているプロセス・プラグインFlows for APEX - Manage Flow Instance Variables [プラグイン]で、通貨を適切に数値に変換できないことが原因のようです。

ワークアラウンドとして、直接APIを呼び出すプロセスに置き換えます。

begin
    flow_process_vars.set_var(
        pi_prcs_id => flow_globals.process_id
        , pi_var_name => 'EXPENSE_AMOUNT'
        , pi_num_value => to_number(:P3_EXPE_AMOUNT,'FML999G999G999G999G990D00')
    );
end;

プロセスのタイプコードの実行に変更し、上記のPL/SQLコードを記述します。

Flows for APEXはオープンソースのプロジェクトとしてGitHubでホストされているので、Issueとして登録したり、自力で修正してプルリクエストをあげることもできます。

https://github.com/flowsforapex/apex-flowsforapex/


ビルド・オプションのコメント・アウト


最近のAPEX Office Hourにて、開発者のNeil Fernandezさんが紹介しているビルド・オプションの使い方です。

前のセクションで説明したように、Flows for APEXのプロセス・プラグインで通貨をプロセス変数としと保存できませんでした。そのため、ワークアラウンドとしてPL/SQLコードを記述しています。不具合が修正されたら、PL/SQLコードからプラグインに簡単に戻せるように、プラグイン自体は削除したくありません。

サーバー側の条件タイプとしてなしを選ぶことにより、常に実行をしない設定にすることもできますが、すでにサーバー側の条件が設定済みの場合は条件を変更する必要があります。

このような場合、ビルド・オプションコメント・アウトを設定します。

この設定で、プロセスが処理の対象から外れます。

共有コンポーネントビルド・オプションを開くと、コメント・アウトの定義を確認することができます。

ビルド・オプションによる評価の方が、サーバー側の定義よりも負荷の軽い処理になります。そのため、単に処理対象から除外する場合は、ビルド・オプションの使用が推奨されます。


通貨記号の変更


通貨記号はNLSパラメータのNLS_CURRENCYで決まっています。Oracle APEXのアプリケーションでは、アプリケーションのプライマリ言語またはアプリケーション言語の導出元から決まる言語より、NLS_CURRENCYが決まります。

言語が日本語であれば、NLS_CURRENCY¥になります。各種の日付書式(アプリケーション日付書式、アプリケーションのタイムスタンプ書式、アプリケーションのタイムスタンプ・タイムゾーン書式)とは異なり、グローバリゼーションのページには、NLS_CURRENCYを独立して設定する項目はありません。

経費精算のアプリケーションのプライマリ言語は日本語ですが、通貨は米ドルを扱います。そのため、NLS_CURRENCY$に設定します。

アプリケーションセキュリティ属性データベース・セッションに、以下の初期化PL/SQLコードを記述します。

begin
   execute immediate 'alter session set nls_currency = ''$'' ';
end;

APEXのページ処理は常にデータベース内で行われます。その処理を行うデータベース・セッションの初期化時に、必ずNLS_CURRENCYに$を設定します。結果として言語環境は日本語ですが、通貨の表記は$になります。

例えば、申請された経費精算の一覧は以下のようになり、申請額は$200.00と表示されます。


EXPE_AMOUNTの書式マスクにはFML999G999G999G999G990D00が設定されています。


残念なことにページ・アイテムの書式については、データベース・セッションのNLS_CURRENCYの変更が効きません。


通貨記号は¥のままです。


Oracle APEX 21.1より、数値および日付のページ・アイテムの書式マスクの適用は、クライアント側のJavaScriptによって行われていることが理由だろうと想定されます。

アプリケーションの言語設定と通貨記号が異なるケースは、ほぼないでしょう。恒久的な対応は必要そうでないため、以下の書式マスク(ドル記号固定)を設定することにより問題を回避しています。

FM$999G999G999G999G990D00


LOVによる表示の置き換え - レポート列とページ・アイテムの違い



デモに使用するユーザーとして、内部名(英字)に日本語名を対応づけています。共有コンポーネントとしてLOV_EMP_NAMEを作成しています。


表には英字の内部名で保存しますが、レポートやフォームには日本語名を表示させます。

上司による承認待ちの申請を一覧する対話モード・レポートで、申請者の列を日本語の従業員名で表示させる設定は以下になります。

識別タイププレーン・テキスト(LOVに基づく)を選択し、LOVとして上記のLOV_EMP_NAMEを選択します。


以上で完了です。

ページ・アイテムで同等の設定を行います。ページ・アイテムのタイプにはプレーン・テキスト(LOVに基づく)はありません

ページ・アイテムの場合は、タイプ選択リストを指定し、LOVタイプ共有コンポーネントLOVとしてLOV_EMP_NAMEを指定します。

その上で読取り専用タイプ常時を選択します。


対話グリッドの列は、ページ・アイテムと同様の設定を行います。

以上にて、レポート列とページ・アイテムの両方で従業員名が日本語で表示されます。

以上が経費精算アプリケーションを作成していて、気のついた点の紹介になります。

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