ラベル 自動化 の投稿を表示しています。 すべての投稿を表示
ラベル 自動化 の投稿を表示しています。 すべての投稿を表示

2023年6月8日木曜日

PDF形式で出力したレポートをメールで送信する

 「対話モード・レポートに表示される一覧を定期的にメールで送信したいのだけど、対話モード・レポートのサブスクリプションの機能では、受信者がそれぞれ自分自身でサブスクリプションを設定しなければならない。管理者側から一括で送付先を決めて送信する方法はないものか?」との相談がありました。

Oracle APEXの自動化で実装できそうなので、試してみました。

対話モード・レポートのソースとして使用するデータを準備します。

ユーティリティサンプル・データセットより、タスク・プスレッドシートをインストールします。このサンプルをインストールすると、表EBA_TASKS_SSがデータも含めて作成されます。


送付先を保存する表TSK_RECIPIENTSを作成します。以下のDDLを実行します。
create table tsk_recipients (
    id                             number generated by default on null as identity 
                                   constraint tsk_recipients_id_pk primary key,
    name                           varchar2(80 char),
    email_address                  varchar2(80 char) not null
)
;
スキーマの準備ができたのでアプリケーション作成ウィザードを起動し、アプリケーションを作成します。

名前をタスク管理とします。ホーム・ページ削除します。

送付先を設定するページを追加します。ページの追加をクリックします。


送付先を編集するページは表TSK_RECIPIENTSをソースとした対話グリッドのページとして作成します。

対話グリッドを選択します。


ページ名送付先とします。表またはビュー編集を許可を選択します。表またはビューとしてTSK_RECIPIENTSを選択します。

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


EBA_TASKS_SSをソースとした対話モード・レポートのページを作成します。

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


対話モード・レポートを選択します。


ページ名タスクとします。表またはビュー対話モード・レポートを選択します。表またはビューとしてEBA_TASKS_SSを選択します。

今回の作業ではフォームを使用しませんが、フォームを含めるチェックを入れておきます。

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


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


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


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

送付先のページを開き、レポートの送付先となるNameEmail Addressを設定します。複数の送付先を設定できます。


タスクを開き、メールに添付されるレポートの形式を保存します。


アクション・メニューからフィルタを呼び出し、Start Dateとして今後の1か月内にある、という条件を設定します。

どのような条件を設定してもこれからの作業は進めていけるので、条件は好きなように設定 できます。


Start Date昇順で並べます。


以上の設定をレポートとして保存します。

アクション・メニューレポートより、レポートの保存を呼び出します。


デフォルトのレポート設定として保存を選択します。


デフォルトのレポート・タイプとして代替を選択し、名前ForEmailReportとします。この名前はPL/SQL APIなどに出てくるREPORT_NAMEやREPORT_ALIASには対応していません

適用をクリックし、レポートを保存します。


ページ・デザイナで、このページを開きます。

対話モード・レポート保存されたレポート以下に、レポートForEmailReportがあります。このレポートを選択し、識別別名ForEmailReportに変更します。これでREPORT_NAMEまたはREPORT_ALIASとしてForEmailReportを指定できるようになります。


対話モード・レポートTasks Ssを選択し、静的IDとしてtaskを割り当てます。


以上で、PL/SQLコードからレポートを呼び出すために必要な識別子の割り当てが完了しました。

送信する電子メールの書式を、電子メール・テンプレートとして定義します。

共有コンポーネント電子メール・テンプレートを開きます。


作成済みの電子メール・テンプレートが一覧されます。電子メール・テンプレートの作成をクリックします。


テンプレート名Task Report静的識別子TASK_REPORTとします。それ以外は自由に設定してかまいません。今回は、テンプレートとして以下を設定しています。

電子メールの件名です。

タスク・レポート #SEND_DATE#

HTMLフォーマットヘッダーです。

<b style="font-size: 24px;">タスク・レポート #SEND_DATE#</b>

本文です。

<strong>#NAME#さん</strong>
<br>
<br>
本日のタスク一覧を添付します。<br>
<br>

フッターです。

<a href="#MY_APPLICATION_LINK#">タスク一覧のアプリケーションにアクセスする。</a>


下にスクロールして、プレーン・テキスト・フォーマットコンテンツに以下を設定し、電子メール・テンプレートの作成をクリックします。

#NAME#さん

本日のタスク一覧を添付します。

タスク一覧のアプリケーションにアクセスする: #MY_APPLICATION_LINK#


以上で、電子メール・テンプレートが作成できました。


今回の本題である自動化を作成します。

最初に以下のプロシージャtsk_prepare_procedureを作成します。自動化の中から呼び出します。



共有コンポーネント自動化を開きます。


作成済みの自動化が一覧されます。作成をクリックします。


自動化の名前Send Task Reportとします。タイプとしてオンデマンドアクションの開始として問合せを選びます。


定期的に繰り返して送信する場合は、オンデマンドではなくスケジュール済を選択します。オンデマンドであれば、画面から自動化を実行できます。そのため、オンデマンドで自動化の実行を確認してから、スケジュール済に変更すると良いでしょう。


タイプオンデマンドを選択しに進むと、アクションの開始問合せを選択しているため、データ・ソースの設定を要求されます。

データ・ソースローカル・データベースソース・タイプとします。表/ビューの名前TSK_RECIPIENTS(表)を指定します。アクションの実行時間として行が返されるを選択します。

これは翻訳が今ひとつで、返される行ごとにアクションが実行される、という意味です。表TSK_RECIPIENTSの一行として送付先が保存されているので、送付先ごとに自動化アクションが呼び出されます。起動されるアクションは割り当てられた行のNAMEおよびEMAIL_ADDRESSの値を、置換文字列&NAME.および&EMAIL_ADDRESS.として利用できます。

作成をクリックし、自動化を作成します。


自動化Send Task Reportが作成されます。

電子メールに添付するレポートをPDF形式で生成します。追加のコード実行に移り、実行可能なPL/SQLコードに以下を記述します。

ページ番号にある対話モード・レポートtaskに保存されているレポートForEmailReportを使って出力したPDFドキュメントを、APEXコレクションATTACHMENTにBLOBとして保存しています。
procedure prepare_report
as
begin
    tsk_prepare_report(
        p_application_id => :APP_ID
        ,p_page_id       => 2
        ,p_static_id     => 'task'
        ,p_report_alias  => 'ForEmailReport'
        ,p_collection_name => 'ATTACHMENT'
    );
end;
初期化プロシージャ名として、上記のprepare_reportを指定します。


アクションを編集します。新規アクションが作成済みなので、それを編集します。


アクション名前レポートをメールで送信とします。タイプとして電子メールの送信を選択します。

電子メール設定の送信変換元ですが、Fromのことです。メールのFromに現れるメール・アドレスを記述します。変換先Toのことです。これは&EMAIL_ADDRESS.を指定します。表TSK_RECIPIENTSの列EMAIL_ADDRESSの値に置き換えられます。

電子メール・テンプレートとして、先ほど作成したTask Reportを選択します。

添付SQLとして以下を記述します。
select blob001, c001, c002, c003
from apex_collections where collection_name = 'ATTACHMENT'

プレースホルダ値の設定をクリックし、列または値を設定します。SEND_DATEには&SYSDATE_YYYYMMDD.NAMEには&NAME.MY_APPLICATION_LINKには作成中のアプリケーションを呼び出すためのURLを設定します。

保存をクリックします。


以上でアクションの設定は完了です。変更の適用をクリックします。


動作を確認するため、保存して実行をクリックします。


自動化実行が開始されました。とメッセージが表示されます。


自動化実行ログから、成功したか失敗したか、およびメッセージから出力されているログなどを確認できます。


メールの受信を待てない場合はAPEX_MAIL.PUSH_QUEUEを実行します。
begin
    apex_mail.push_queue;
end;

メールが受信できたら実装は完了です。添付されているレポートを開いて確認します。


レポートがPDFで出力されていることが確認できます。



この後、自動化タイプオンデマンドからスケジュール済に変更できます。

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

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

2022年12月14日水曜日

アプリケーション・インポート後の自動化を自動的にアクティブにする

 アプリケーションに作成されている自動化は、アプリケーションをインポートした時点では無効になっています。インポート後にいきなりアクティブになり、知らないうちに処理が実行されても困るので、これは妥当な仕様でしょう。

Oracle APEX 22.1のマニュアルでは以下のセクションに説明があります。

アプリケーション・ビルダー・ユーザーズ・ガイド
19.5.2 自動化のインポートとエクポートについて

とはいえ、インポート後に操作しなくてもアクティブになって欲しい自動化の処理もあるようです。少し実装方法について考えてみました。

これも自動化を使って実装します。

Oracle APEXの自動化はAPEXの標準ビューAPEX_APPL_AUTOMATIONSより、登録されている自動化やそのステータスを確認できます。

以下のSELECT文で無効になっている自動化を見つけることができます。静的ID(列static_id)がauto-enabled-で始まるという条件を付けることにより、インポート後に自動的にアクティブにしたい自動化を選択しています。

自動化をアクティブにするためにプロシージャAPEX_AUTOMATION.ENABLEが使えます。このプロシージャの引数は自動化が作成されているアプリケーションIDと自動化の静的IDです。そのため、上記のSELECT文で検索された値を引数としてAPEX_AUTOMATION.ENABLEを呼び出すことで、自動化をアクティブにできそうです。

APEXアプリケーションを作成し、上記の処理を実装してみます。

アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前自動化親アプリとします。

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


アプリケーションが作成されたら、自動化の作成を行います。

共有コンポーネント自動化を開きます。


作成済みの自動化が一覧されます。作成をクリックします。


名前自動有効化とします。タイプスケジュール済(翻訳がいまひとつです。定期実行または繰り返し実行のことです。)、アクションの開始問合せを選択します。実行スケジュールは、この中で一番短い15分ごとを選択します。

へ進みます。


データ・ソースローカル・データベースソース・タイプとしてSQL問合せを選択し、SQL SELECT文を入力に、アクティブに変更する自動化を検索するSELECT文を記述します。アクションの実行時間(これも翻訳が今ひとつです。アクションが実行されるタイミングです。)として行が返されるを選択します。


以上で作成をクリックします。

自動化が作成されます。

最初にアクションの実行のセクションを変更します。

アクションの実行時間行が返されるのままです。主キー列としてAUTOMATION_ID(Number)を選択します。設定ミスなどがあり自動化が大量に実行されることを防ぐため、処理する最大行数アクションのエラーの処理自動化の無効化を選択します。動作の確認ができたら、より緩やかな設定に変更します。


アクションにデフォルトで作成されている新規アクションを編集します。


アクション名前自動化をアクティブにするに変更し、コードからはAPEX_AUTOMATION.ENABLEを呼び出します。


以上で自動化の作成は完了です。

スケジュール・ステータスアクティブにし、保存して実行します。


実行ログは、自動化実行ログより確認できます。


動作確認のために別にAPEXアプリケーションを作成し、自動化を作成します。静的IDauto-enable-testとします。スケジュール・ステータス無効にします。

特にAlways Freeのインスタンスを使用している場合ですが、OCPUに限りがあるので無駄に自動化が動かないよう、一日に一度など少ない実行間隔にしておきます。


アプリケーション・ビルダーには複数のアプリケーションの自動化の状態を一度に確認する画面は無いみたいなので、以下のSELECT文により動作を確認します。


POLLING_STATUS_CODEがDISABLEDだった自動化がACTIVEに変わっていたら、期待通りに動作していると言えます。

自動化以外なにもないですが、アプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/enable-automation-by-automation.zip

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