「対話モード・レポートに表示される一覧を定期的にメールで送信したいのだけど、対話モード・レポートのサブスクリプションの機能では、受信者がそれぞれ自分自身でサブスクリプションを設定しなければならない。管理者側から一括で送付先を決めて送信する方法はないものか?」との相談がありました。
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をソースとした対話グリッドのページとして作成します。
対話グリッドを選択します。
ページの追加をクリックします。
表EBA_TASKS_SSをソースとした対話モード・レポートのページを作成します。
ページの追加をクリックします。
対話モード・レポートを選択します。
ページ名はタスクとします。表またはビュー、対話モード・レポートを選択します。表またはビューとしてEBA_TASKS_SSを選択します。
今回の作業ではフォームを使用しませんが、フォームを含めるにチェックを入れておきます。
ページの追加をクリックします。
以上で、アプリケーションの作成を実行します。
作成されたアプリケーションを実行します。
送付先のページを開き、レポートの送付先となるNameとEmail Addressを設定します。複数の送付先を設定できます。
タスクを開き、メールに添付されるレポートの形式を保存します。
アクション・メニューからフィルタを呼び出し、Start Dateとして今後の1か月内にある、という条件を設定します。
どのような条件を設定してもこれからの作業は進めていけるので、条件は好きなように設定 できます。
以上の設定をレポートとして保存します。
アクション・メニューのレポートより、レポートの保存を呼び出します。
デフォルトのレポート・タイプとして代替を選択し、名前は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を作成します。自動化の中から呼び出します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create or replace procedure tsk_prepare_report( | |
p_application_id in number | |
,p_page_id in number | |
,p_static_id in varchar2 | |
,p_report_alias in varchar2 | |
,p_collection_name in varchar2 | |
) | |
as | |
l_export apex_data_export.t_export; | |
l_region_id number; | |
l_report_id number; | |
l_file_name varchar2(80); | |
begin | |
/* get region_id of the report to be attached. */ | |
select region_id into l_region_id | |
from apex_application_page_regions | |
where application_id = p_application_id | |
and page_id = p_page_id | |
and static_id = p_static_id; | |
/* get component_id / report_id if report alias is provided */ | |
if p_report_alias is not null then | |
select report_id into l_report_id | |
from apex_application_page_ir_rpt | |
where application_id = p_application_id | |
and page_id = p_page_id | |
and region_id = l_region_id | |
and report_alias = p_report_alias; | |
end if; | |
l_file_name := 'task-report-' || to_char(sysdate,'RR-MM-DD') || '.pdf'; | |
/* export report as pdf / blob */ | |
l_export := apex_region.export_data ( | |
p_format => apex_data_export.c_format_pdf | |
,p_page_id => p_page_id | |
,p_region_id => l_region_id | |
,p_component_id => l_report_id | |
,p_file_name => l_file_name | |
); | |
/* store exported data / blob in apex_collection */ | |
apex_collection.create_or_truncate_collection( | |
p_collection_name => p_collection_name | |
); | |
apex_collection.add_member( | |
p_collection_name => p_collection_name | |
,p_blob001 => l_export.content_blob | |
,p_c001 => l_file_name | |
,p_c002 => 'application/pdf' | |
,p_c003 => sys_guid() | |
); | |
end; | |
/ |
共有コンポーネントの自動化を開きます。
作成済みの自動化が一覧されます。作成をクリックします。
自動化の名前はSend Task Reportとします。タイプとしてオンデマンド、アクションの開始として問合せを選びます。
定期的に繰り返して送信する場合は、オンデマンドではなくスケジュール済を選択します。オンデマンドであれば、画面から自動化を実行できます。そのため、オンデマンドで自動化の実行を確認してから、スケジュール済に変更すると良いでしょう。
タイプにオンデマンドを選択し次に進むと、アクションの開始に問合せを選択しているため、データ・ソースの設定を要求されます。
データ・ソースはローカル・データベース、ソース・タイプは表とします。表/ビューの名前にTSK_RECIPIENTS(表)を指定します。アクションの実行時間として行が返されるを選択します。
これは翻訳が今ひとつで、返される行ごとにアクションが実行される、という意味です。表TSK_RECIPIENTSの一行として送付先が保存されているので、送付先ごとに自動化のアクションが呼び出されます。起動されるアクションは割り当てられた行のNAMEおよびEMAIL_ADDRESSの値を、置換文字列&NAME.および&EMAIL_ADDRESS.として利用できます。
作成をクリックし、自動化を作成します。
自動化Send Task Reportが作成されます。
電子メールに添付するレポートをPDF形式で生成します。追加のコード実行に移り、実行可能なPL/SQLコードに以下を記述します。
ページ番号2にある対話モード・レポート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のアプリケーション作成の参考になれば幸いです。
完