0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SDIでレポートを定期自動配信:月次売上サマリー

Last updated at Posted at 2025-10-29

1. はじめに

Simple Data Integrator(SDI) は、データソース間でのデータ連携を実現するツールですが、メール通知機能とスケジューラ機能を組み合わせることで、各種レポートを定期的に自動配信することも可能です。

本記事では、以下のような仕組みの実装手順を紹介します。
先月分の売上データを自動で集計し、読みやすいレイアウトのレポートを月初に自動配信する仕組み。

メール例:
image.png


2. 全体像(仕組みとデータ前提)

2.1 仕組み

  • (A) SQL:DB上の売上データを集計し、HTMLの行として出力
  • (B) HTMLテンプレ{outputFile} 変数に (A) の出力をそのまま差し込み
  • (C) スケジューラ:毎月決まった日時に SQL → メール送信 を順番実行

2.2 データ前提

売上テーブル

CREATE TABLE "FACT_SALES_DAILY" 
   (	"DATE_KEY" DATE NOT NULL ENABLE, 
	"STORE_ID" VARCHAR2(32 BYTE) COLLATE "USING_NLS_COMP" NOT NULL ENABLE, 
	"PRODUCT_ID" VARCHAR2(64 BYTE) COLLATE "USING_NLS_COMP" NOT NULL ENABLE, 
	"QTY" NUMBER(18,4) DEFAULT 0 NOT NULL ENABLE, 
	"NET_SALES" NUMBER(18,2) DEFAULT 0 NOT NULL ENABLE, 
	"TRANSACTIONS" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE, 
	"CUSTOMERS" NUMBER(10,0) DEFAULT 0 NOT NULL ENABLE, 
	 CONSTRAINT "PK_FACT_SALES_DAILY" PRIMARY KEY ("DATE_KEY", "STORE_ID", "PRODUCT_ID")
  }

商品テーブル

  CREATE TABLE "DIM_PRODUCT" 
   (	"PRODUCT_ID" VARCHAR2(64 BYTE) COLLATE "USING_NLS_COMP", 
	"PRODUCT_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP" NOT NULL ENABLE, 
	"CATEGORY" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", 
	"SUBCATEGORY" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", 
	"BRAND" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", 
	"UOM" VARCHAR2(20 BYTE) COLLATE "USING_NLS_COMP", 
	 PRIMARY KEY ("PRODUCT_ID")
   )

2.3 マッピング処理フロー

image.png

3. 実装手順

3.1 コネクション設定

まず、Source および Target への接続を設定します。
本例では、Source は Oracle Database、Target は CSV ファイル です。

設定手順の詳細については、以下の記事を参照してください:
コネクション設定 (ダイレクト接続)

ソースコネクション名 ターゲットコネクション名
oracle_sales
CSV_EXPORT

3.2 マッピング設定

3.2.1 .「新規マッピング」ボタンをクリックして、マッピング設定画面を開きます

image.png

3.2.2 . ソースコネクション、クエリ、ターゲットコネクション、および CSV ファイル名を設定します

image.png

No 項目 説明
1 マッピング名 マッピング名を入力します。管理上ユニークな名前の設定を推奨します。
2 ソースコネクション oracle_salesを選択
3 タイプ クエリを選択
4 クエリのSQL詳細 レポート作成用の SQL を入力します。 ※1
5 コネクションコネクション CSV_EXPORTを選択
6 CSVファイル名 出力する CSV ファイル名を入力します。
7 カラム一覧取得 カラム一覧取得ボタンをクリックし、テーブル定義明細を取得します。
8 マッピング対象 出力対象とするカラムを選択します。

※1 レポート作成用のSQL

WITH t AS (
  SELECT
    fsd.PRODUCT_ID,
    MAX(dp.PRODUCT_NAME) AS PRODUCT_NAME,
    ROUND(SUM(fsd.NET_SALES)) AS SALES,
    SUM(fsd.QTY) AS QTY
  FROM FACT_SALES_DAILY fsd
  JOIN DIM_PRODUCT dp ON dp.PRODUCT_ID = fsd.PRODUCT_ID
  WHERE fsd.DATE_KEY >= TRUNC(ADD_MONTHS(SYSDATE, -1), 'MM')
    AND fsd.DATE_KEY <  TRUNC(SYSDATE, 'MM')
  GROUP BY fsd.PRODUCT_ID
),
kpi AS (  -- KPIカード用の合計
  SELECT
    SUM(SALES) AS SUM_SALES,
    SUM(QTY)   AS SUM_QTY
  FROM t
),
topn AS ( -- TOP5をここで確定させる(サブクエリ内でORDER/FETCH)
  SELECT
    -- HTMLエスケープ(& < > " ')
    PRODUCT_NAME AS NAME_HTML,
    SALES,
    QTY
  FROM t
  ORDER BY SALES DESC
  FETCH FIRST 5 ROWS ONLY
)
-- 1行目:カード(売上合計)
SELECT
  '<div class="section">
     <div class="kpis">
       <div class="card">
         <h4>売上合計</h4>
         <p class="v">' || TO_CHAR(SUM_SALES, 'FM999G999G999') || '</p>
         <div class="delta muted">数量:' || TO_CHAR(SUM_QTY, 'FM999G999G999') || '</div>
       </div>
     </div>
   </div>' AS ROW_HTML
FROM kpi
UNION ALL
-- 2行目 商品テーブル Head
SELECT 
  '     
        <div class="section">
        <div class="hr"></div>
        <h3 style="margin:0 0 10px 0;color:#0f172a">TOP 5 商品</h3>
        <p class="muted text-right" style="margin:0 0 10px 0;" >並び順:売上金額(降順)</p>
        <table role="presentation" aria-hidden="true">
          <thead>
            <tr>
              <th style="width:56%">商品名</th>
              <th style="width:22%" class="num">売上(税抜)</th>
              <th style="width:22%" class="num">数量</th>
            </tr>
          </thead>
          <tbody>
  ' AS ROW_HTML
FROM DUAL  
UNION ALL 
-- 3行目以降:TOP5の商品行(<tr>…</tr>)
SELECT
  '<tr><td>' || NAME_HTML ||
  '</td><td class="num">' || TO_CHAR(SALES, 'FM999G999G999') ||
  '</td><td class="num">' || TO_CHAR(QTY,   'FM999G999G999') ||
  '</td></tr>' AS ROW_HTML
FROM topn
-- 最後Footer
UNION ALL
SELECT 
  ' 
        </tbody>
        </table>
      </div>
      <div class="foot">
        <div class="hr"></div>
        <p class="tiny">
          このメールはシステムから自動送信されています。
        </p>
      </div>
    </div>
  ' AS ROW_HTML
FROM DUAL

3.3 . メール送信設定

3.3.1 「詳細設定」ボタンをクリックして、詳細設定画面を開きます

image.png

3.3.2 処理フロー画面上の「処理成功時処理」で Yes を選択します。その下の「詳細設定」ボタンをクリックし、メール送信内容を設定します。

image.png

3.3.3 メール内容の設定

image.png
image.png

注意

メール送信を行うためには、送信メールサーバー(SMTP) の設定が必要です。
詳細な設定手順については、以下のページを参照してください。
https://ja.sdi.ricct.com/userguide/mailsetting/

No 項目 説明
12 メール送信 メール送信をチェックします
13 メール詳細 送信先、件名、本文などを設定します。

件名:

月間売上サマリー({DateTime.Now.AddMonths(-1).ToString("yyyy年M月")})

本文:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>{DateTime.Now.AddMonths(-1).ToString("yyyy年M月")}月間売上サマリー</title>
    <style>
      /* ---- 基本 ---- */
      body{margin:0;padding:0;background:#f6f7fb;}
      .wrap{max-width:720px;margin:0 auto;background:#ffffff;border-radius:14px;
            box-shadow:0 4px 18px rgba(15,23,42,.06);overflow:hidden}
      .head{padding:22px 26px 8px 26px;background:#0f172a;color:#fff}
      .title{margin:0;font-size:20px;line-height:1.35;font-weight:700}
      .sub{margin:6px 0 0 0;font-size:12px;opacity:.85}
      .muted{color:#64748b;font-size:12px}
      .text-right{text-align:right;} 
      .section{padding:18px 22px}
      .hr{height:1px;background:#eef2f7;margin:14px 0}

      /* ---- 合計カード ---- */
      .kpis{display:flex;gap:10px}
      .card{flex:1;border:1px solid #eef2f7;border-radius:12px;padding:12px 12px 10px}
      .card h4{margin:0 0 6px 0;color:#64748b;font-size:12px;font-weight:600;letter-spacing:.2px}
      .card .v{margin:0;font-size:22px;font-weight:800;color:#0f172a;letter-spacing:.2px}
      .delta{font-size:12px;margin-top:4px}
      .up{color:#16a34a;font-weight:700}
      .down{color:#dc2626;font-weight:700}

      /* ---- テーブル ---- */
      .table-wrap{overflow:auto;-webkit-overflow-scrolling:touch}
      table{border-collapse:collapse;width:100%;min-width:520px}
      th,td{border:1px solid #eef2f7;padding:10px 10px;text-align:left;font-size:13px}
      th{background:#f8fafc;color:#0f172a}
      tr:nth-child(even){background:#fcfdff}
      th.num, td.num{ text-align:right; font-variant-numeric: tabular-nums; }

      /* ---- バッジ ---- */
      .badge{display:inline-block;padding:2px 8px;border-radius:999px;font-size:11px}
      .b-primary{background:#e3f2fd;color:#0b6aa3}

      /* ---- CSVリンク(ボタン風) ---- */
      .btn{display:inline-block;padding:8px 12px;border-radius:8px;background:#0b6aa3;color:#fff;
           text-decoration:none;font-size:13px}

      /* ---- フッタ ---- */
      .foot{padding:14px 22px 24px 22px}
      .tiny{font-size:11px;color:#94a3b8}

      @media (max-width:560px){
        .kpis{display:block}
        .card{margin-bottom:8px}
      }
    </style>

  </head>
  <body>
    <div class="wrap">
      <!-- ヘッダ -->
      <div class="head">
        <div class="badge b-primary">{DateTime.Now.AddMonths(-1).ToString("yyyy年M月")}</div>
        <h1 class="title">{DateTime.Now.AddMonths(-1).ToString("yyyy年M月")}月間売上サマリー</h1>
        <p class="sub">対象期間:{DateTime(today.Year, today.Month, 1).AddMonths(-1).ToString("yyyy年M月d日")}
                 –{DateTime(today.Year, today.Month, 1).AddDays(-1).ToString("yyyy年M月d日")}</p>
      </div>
{outputFile}
  </body>
</html>

メール設定画面および処理フロー画面で 「OK」 ボタンをクリックし、マッピング設定画面に戻ります。

4 . テスト実行

「マッピング実行」 ボタンをクリックして、動作を確認します。

設定した内容のメールが正しく送信されることを確認します。

5 . 保存

「保存」 ボタンをクリックして、マッピング設定を保存します。

6 . スケジューラーへの登録

毎月の月初にメールを自動送信する場合は、スケジューラーを作成してマッピングを登録します。
スケジューラーの設定方法については、以下のページを参照してください。
スケジューラ設定

7. 横展開

本記事では月次売上サマリーを例にしましたが、同じ構成(①SQLでHTML断片生成 → ②テンプレ差し込み → ③スケジューラ配信)で、以下のレポートにそのまま横展開できます。

7.1 期間違いのサマリー

  • 週次売上サマリー:期間を「先週の月〜日」に変更
    • 件名例:週間売上サマリー({DateTime.Today.AddDays(-7).ToString("yyyy年M月d日")}週)
    • スケジュール:毎週月曜 9:00
  • 売上日報DATE_KEY = TRUNC(SYSDATE-1) などで前日分
    • 件名例:売上日報({DateTime.Today.AddDays(-1).ToString("yyyy年M月d日")})
    • スケジュール:毎朝 8:00

7.2 切り口違いのランキング/集計

  • 部門別 / 店舗別GROUP BY 部門ID(または店舗ID) を追加し、表見出しを差し替え
    • 件名例:店舗別・月次売上サマリー({DateTime.Now.AddMonths(-1).ToString("yyyy年M月")})
  • 担当者別 / ブランド別GROUP BY のキーを入れ替え、TOP N を ORDER BY で制御

7.3 アラート系(しきい値通知)

  • 在庫アラート:在庫率や安全在庫を下回る商品のみ 生成
    • 件名例:在庫アラート({DateTime.Today.ToString("yyyy/MM/dd")})
    • 並び順:在庫率の昇順、ステータス(危険/注意/良好)に応じてバッジ色を変更
  • 欠品リスク:売上推移×在庫日数(= 在庫 / 平均販売数量)で閾値判定
    • 表示:リードタイム、想定欠品日、代替品リンクなど

7.4 配信の工夫

  • セグメント配信:部門長には部門別、店舗責任者には店舗別だけを配信(宛先リストを分割)
  • CSV添付 / DLリンク:SQL結果をCSV出力して添付、あるいはオブジェクトストレージのURLを本文ボタンに設定
  • 多言語対応{DateTime(..., "ja-JP")} / "en-US" で件名・本文の日付ローカライズ

以上です。

SDIのインストール、設定、活用方法に関するその他の情報については、下記のページをご参照ください。
Simple Data Integrator (SDI) 実践入門

参考資料

SDI日本語公式サイト
SDI English Official Website
SDIマップイング設定

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?