調達から支払いまで:発注書のデータテンプレート
調達から支払いまで:発注書のデータテンプレート
- 収集を推奨する属性
- 追跡する主要なアクティビティ
- SAP ECCからのデータ抽出ガイド
調達から支払いまで:発注書の属性
| 名前 | 説明 | ||
|---|---|---|---|
| アクティビティ Activity | 購買発注のライフサイクルで発生した、特定の業務イベントまたはステップの名称です。 | ||
| 説明 この属性は、「購買発注を作成」「購買発注を承認」「入庫を転記」など、プロセス内の個々のステップを表します。これらのアクティビティの順序によって、購買発注ごとのプロセスフローが構成されます。 アクティビティの順序、頻度、所要時間の分析は、プロセスマイニングの中核です。ボトルネックや手戻りのループ、標準プロセスからの逸脱を特定し、的を絞った改善や標準化につなげられます。 重要な理由 アクティビティによってプロセスの各ステップが分かります。その順序やタイミングを分析すると、実際のプロセスフローやボトルネック、標準からの逸脱を把握できます。 入手先 CDHDR/CDPOS(変更)、EKBE(入庫/請求書照合)、EBAN(購買依頼)など、複数のSAPテーブルやトランザクションログから取得します。生成には、多くの場合、個別のロジックや抽出プログラムが必要です。 例 購買発注を作成購買発注を承認入庫を転記 | |||
| イベント時刻 EventTime | アクティビティが発生した正確な日時です。 | ||
| 説明 このタイムスタンプは、購買発注の承認や入庫の転記など、イベントが発生した正確な時点を示します。ケース内のすべてのアクティビティを時系列に並べるために使われます。 タイムスタンプは、時間に基づく分析に欠かせません。アクティビティ間のサイクルタイムの算出、遅延の特定、プロセスの処理量の分析、サービスレベル合意(SLA)に対する実績の測定に使われます。 重要な理由 サイクルタイムやボトルネックなど、所要時間に基づく指標の算出と、イベントの時系列順の整理に欠かせません。 入手先 EKKO-AEDAT(変更日)、CDHDR-UDATE/UTIME(変更ログのタイムスタンプ)、EKBE-BUDAT(転記日)など、SAPテーブルの複数の日付・時刻フィールドから取得します。 例 2023-04-15T10:05:31Z2023-04-16T14:22:00Z2023-05-01T09:00:15Z | |||
| 購買発注 PurchaseOrder | 購買発注(PO)文書を一意に識別する番号です。調達プロセスを追跡する際の主要なケースとして使われます。 | ||
| 説明 購買発注番号は、作成から最終的な入庫と完了まで、すべてのアクティビティを結び付ける中心的な識別子です。購買発注番号ごとに、調達プロセスの1つの実行を表します。 プロセスマイニングでは、この属性を使って個々の購買の流れを最初から最後まで再構成します。各発注のサイクルタイム、プロセスのバリアント、コンプライアンスを詳細に分析でき、プロセスモデルの基盤となります。 重要な理由 関連するすべてのイベントを結び付ける基本の識別子です。個々の購買発注のライフサイクル全体を分析できます。 入手先 テーブル:EKKO、フィールド:EBELN 例 450001762345000176244500017625 | |||
| ユーザー名 UserName | アクティビティを実行した人のユーザーIDです。 | ||
| 説明 この属性には、文書を作成、変更、承認した従業員のSAPユーザー名が記録されます。自動処理の場合は、システムまたはバッチユーザーのIDが表示されることがあります。 ユーザー別に分析すると、トレーニングの必要性や高い成果を上げている担当者、コンプライアンス上の懸念を特定できます。業務量の分布や承認マトリクスへの準拠を確認するダッシュボードの作成や、チーム・個人ごとの実績把握にも役立ちます。 重要な理由 ユーザーの操作を個人にひも付け、実績や業務量、コンプライアンス手順の遵守状況を分析できます。 入手先 テーブル:EKKO、フィールド:ERNAM(作成者);テーブル:CDHDR、フィールド:USERNAME(変更者)。 例 JSMITHMBROWNBATCH_USER | |||
| 仕入先番号 VendorNumber | 仕入先を一意に識別する番号です。 | ||
| 説明 調達する商品やサービスの仕入先を一意に識別するコードです。調達プロセスにおける重要なマスターデータです。 この属性は、仕入先別の分析に欠かせません。仕入先の納品実績の評価、仕入先間のリードタイムの比較、支出傾向の分析に使えます。「仕入先の納品実績」ダッシュボードの主要な分析軸です。 重要な理由 仕入先の実績を分析し、信頼できる仕入先や、遅延・品質上の問題を引き起こしている仕入先を特定できます。 入手先 テーブル:EKKO、フィールド:LIFNR 例 100345V-20598700112 | |||
| 会社コード CompanyCode | 購買を開始する法人または会社を識別するコードです。 | ||
| 説明 会社コードは、SAPにおける独立した法人を表します。すべての取引は会社コード単位で転記されるため、基本的な組織単位の1つです。 会社コード別にプロセスを分析すると、事業部門や国ごとの調達効率とコンプライアンスを比較できます。ある法人の優れた取り組みを他の法人に展開したり、プロセスに課題を抱える部門を特定したりするのに役立ちます。 重要な理由 法人を識別し、組織内の各部門におけるプロセス実績の比較やコンプライアンスの確認に役立ちます。 入手先 テーブル:EKKO、フィールド:BUKRS 例 10002100US01 | |||
| 品目グループ MaterialGroup | 特性が似た品目やサービスを分類するための区分です。 | ||
| 説明 品目グループ(購買カテゴリ)は、調達する商品やサービスの種類を分類するために使います。例として、「ITハードウェア」「事務用品」「専門サービス」などがあります。 この属性は、支出分析や調達傾向の把握に欠かせません。カテゴリ別にプロセスを絞り込み、処理方法や承認者、仕入先を分析できます。「購買発注金額分析」ダッシュボードの主要な分析軸です。 重要な理由 商品やサービスのカテゴリ別にプロセスを分けて分析できます。支出の種類ごとの処理方法、サイクルタイム、仕入先の違いを把握できます。 入手先 テーブル:EKPO、フィールド:MATKL 例 00101IT_HWCONSULT | |||
| 文書タイプ DocumentType | 購買発注の種類を分類するコードです。 | ||
| 説明 文書タイプはSAPの設定項目で、購買発注の番号範囲、フィールド選択、全体のプロセスフローを制御します。標準購買発注、サービス購買発注、在庫転送発注など、種類ごとに異なる設定が可能です。 文書タイプによって異なるプロセスをたどることが多いため、分析の重要な軸になります。文書タイプで絞り込むと、サイクルタイムやプロセスフローを同じ条件で比較できます。 重要な理由 標準、サービス、返品など、購買プロセスの種類を区別します。それぞれ異なる経路や実績の基準が設定されていることがあります。 入手先 テーブル:EKKO、フィールド:BSART 例 NBFOUB | |||
| 発注金額 OrderAmount | 購買発注明細の合計金額です。 | ||
| 説明 この属性は、購買発注明細ごとの合計金額を表します。数量に正味価格を掛けて算出します。購買発注全体の金額を求めるには、各明細の金額を合計します。 発注金額別にプロセスを分析すると、より厳格な管理や異なる承認経路が必要な高額取引を特定できます。「購買発注金額分析」ダッシュボードに使われ、金額の大きい発注を優先したプロセス改善にも役立ちます。 重要な理由 購買ごとの財務上の影響を数値化し、高額発注の優先やコスト削減の機会の特定に役立てられます。 入手先 テーブル:EKPO、フィールド:NETWR(正味発注金額)。 例 1500.00250.7512345.50 | |||
| ソースシステム SourceSystem | データの抽出元となるシステムです。 | ||
| 説明 この属性はデータの取得元を示します。通常はSAP ECCのインスタンス識別子(例:「ECC_PROD_100」)です。複数のシステムがある環境では、データソースの区別に役立ちます。 ガバナンスとデータリネージを確認するうえで、ソースシステムの把握は重要です。データの完全性を確保し、特に複数のERPシステムやモジュールのデータを統合する場合に、データ抽出や品質に関する問題の調査に役立ちます。 重要な理由 データの取得元を示します。複数のシステムにまたがる分析のデータガバナンス、検証、管理に欠かせません。 入手先 通常は、データ抽出時に追加する固定値です。データセットに取得元のシステムを示すラベルを付けます。 例 SAP_ECC_PRODECC_EU_100S4H_FIN | |||
| プラント Plant | 商品を納品する物理的な場所またはプラントです。 | ||
| 説明 プラントは、製造施設、倉庫、その他商品やサービスを受け入れる場所を表す組織単位です。 プラント別に分析すると、調達プロセスにおける地域ごとの差を把握できます。特定の場所への仕入先の納品にかかる時間の違いや、入庫処理に非効率があるプラントを特定し、商品の入庫が適時に行われているかを分析できます。 重要な理由 納品先を示す項目です。地域ごとのプロセスの違いや物流パフォーマンスの分析に役立ちます。 入手先 テーブル:EKPO、項目:WERKS 例 100011002000 | |||
| 仕入先名 VendorName | 仕入先の正式名称です。 | ||
| 説明 仕入先番号よりも利用者にとって分かりやすい、仕入先の名称です。通常は仕入先マスターデータから取得します。 仕入先番号はデータの結合や一意の識別に使います。一方、仕入先名は、利用者向けのダッシュボードやレポートに欠かせません。仕入先コードに詳しくない業務担当者にも、分析内容が伝わりやすくなります。 重要な理由 仕入先の名称を分かりやすく表示し、業務担当者がダッシュボードやレポートを理解しやすくします。 入手先 テーブル:LFA1、フィールド:NAME1。EKKO-LIFNRとLFA1-LIFNRを結合します。 例 Staples Inc.Global Tech SolutionsOffice Supply Co. | |||
| 最終データ更新 LastDataUpdate | ソースシステムからデータが最後に更新された日時を示すタイムスタンプです。 | ||
| 説明 この属性には、データを最後に抽出または更新した日時が記録されます。分析対象のデータがどの程度新しいかを把握できます。 ダッシュボードにこの情報を表示すると、インサイトがほぼリアルタイムのデータに基づくのか、過去の時点のデータに基づくのかを利用者が判断できます。データの鮮度を明示することで、利用者の期待を適切に調整し、データの経過時間を踏まえた意思決定を支援します。 重要な理由 データの更新状況を利用者に伝え、分析が業務の最新状況を反映しているかどうかを判断できるようにします。 入手先 このタイムスタンプは、データ抽出またはETLプロセスの実行時に生成され、追加されます。 例 2023-10-27T02:00:00Z2023-10-28T02:00:00Z | |||
| 却下理由 RejectionReason | 購買依頼または発注書が却下された理由を示すコードまたはテキストです。 | ||
| 説明 承認ワークフローで発注書が却下された際に、その具体的な理由を記録する属性です。手戻りや遅延の根本原因を把握するうえで重要な情報です。 却下理由を分析すると、価格の誤り、予算超過、コンプライアンスに適合しない仕入先の選定など、よくある問題を特定できます。根本原因への対処、発注書の初期作成の品質向上、承認プロセスの効率化に役立ちます。 重要な理由 承認が通らない理由を直接把握できるため、手戻りの削減や承認サイクルタイムの短縮に向けた改善につなげられます。 入手先 この情報は見つけにくい場合があります。長文テキスト項目に保存されていたり、独自のワークフロー設定に依存していたりすることがあります。確認には、個別の実装に関する知識が必要になる場合もあります。 例 価格の誤り予算超過重複した依頼 | |||
| 希望納期 RequestedDeliveryDate | 商品やサービスの納品を仕入先に求める日付です。 | ||
| 説明 購買発注に指定された目標納期です。実際の納品実績を測定する際のベースラインになります。 この日付は、「納期どおりの入庫率」の重要業績評価指標(KPI)の算出に欠かせません。実際の入庫日と希望納期を比較すると、仕入先の信頼性と社内の受入業務の効率を定量的に測定でき、「仕入先の納品実績」ダッシュボードにも役立ちます。 重要な理由 納品の目標日です。納期遵守に関する重要業績評価指標(KPI)の算出や、仕入先の信頼性の評価に欠かせません。 入手先 テーブル:EKPO、フィールド:EINDT 例 2023-06-102023-07-222023-08-01 | |||
| 承認後の変更かどうか IsPostApprovalChange | 最初の承認後に発注書が変更されたかどうかを示すフラグです。 | ||
| 説明 同じ発注書で「発注書変更」アクティビティが「発注書承認」アクティビティの後に検出された場合、この真偽値属性はtrueになります。プロセスの後半で発生する問題のある変更を特定できます。 この計算項目は、「承認後の発注書変更率」KPIと「発注書の手戻りと変更」ダッシュボードに直接利用されます。遅延や再承認の原因となる業務への影響が大きい変更を定量化して明らかにし、初期の要件定義や範囲設定に関する問題の特定に役立ちます。 重要な理由 承認後の手戻りを直接測定できるため、プロセスの安定性と効率を示す重要業績評価指標(KPI)になります。数値が高い場合は、上流工程での要件定義に問題がある可能性があります。 入手先 イベントログ内のアクティビティの順序から算出される属性です。 例 truefalse | |||
| 納期どおりに納品されたか IsOnTimeDelivery | 依頼された納品日までに商品を受領したかどうかを示すフラグです。 | ||
| 説明 「入庫転記」アクティビティのタイムスタンプが「依頼納品日」と同日またはそれ以前の場合、この真偽値属性はtrueになります。発注明細ごとの納品パフォーマンスを明確に判定できます。 この属性は「納期どおりの入庫率」KPIの基礎となります。納期どおりの納品と遅延した納品を簡単に集計・絞り込みできるため、仕入先のパフォーマンスと社内の入庫処理の効率を分析しやすくなります。 重要な理由 納品が期日どおりかどうかを明確に示し、仕入先のパフォーマンスに関するKPIやダッシュボードを支えます。 入手先 入庫転記日(EKBE-BUDAT)と依頼納品日(EKPO-EINDT)を比較して算出される属性です。 例 truefalse | |||
| 購買グループ PurchasingGroup | 調達業務を担当する購買担当者または担当者グループです。 | ||
| 説明 購買グループは、特定の購買業務を担当する購買担当者またはチームを表します。仕入先との主な連絡窓口です。 この属性を使うと、購買組織より細かい単位で分析できます。購買担当者間の業務量の分布や実績の違いを把握し、人員配置やトレーニングの計画に役立てられます。 重要な理由 購買担当者やチーム単位で、購買の担当者を詳しく把握できます。これにより、業務量やパフォーマンスを詳細に分析できます。 入手先 テーブル:EKKO、項目:EKGRP 例 001002N01 | |||
| 購買依頼 PurchaseRequisition | 購買発注の前段階にある購買依頼の識別子です。 | ||
| 説明 この属性は、購買発注と元になった購買依頼を結び付けます。すべての購買発注に先行する購買依頼があるとは限りません。 この関連付けは、「購買依頼から発注への変換」ダッシュボードと「購買依頼から購買発注への変換率」の重要業績評価指標(KPI)の分析に欠かせません。最初の依頼から正式な発注の作成まで、前段階のプロセスの効率を測定できます。また、購買依頼を経ずに作成された、コンプライアンスに準拠しない購買発注の特定にも役立ちます。 重要な理由 購買発注と元の依頼を結び付け、購買依頼から購買発注への変換プロセスを分析できます。先行する購買依頼なしで作成された購買発注も特定できます。 入手先 テーブル:EKPO、フィールド:BANFN 例 1001589010015891 | |||
| 購買組織 PurchasingOrganization | 価格交渉や品目・サービスの調達を担当する組織単位です。 | ||
| 説明 購買組織は、SAPで調達業務を担う主要な組織単位です。全社で一元化することも、プラントや地域ごとに分散させることもできます。 購買組織別にプロセス実績を分析すると、調達チームごとの効率を把握できます。サイクルタイム、手戻り率、コストなどの指標を組織単位で比較し、優れた取り組みや支援が必要な領域を特定できます。 重要な理由 調達を担当するチームを特定し、組織単位ごとの実績比較や分析に役立てられます。 入手先 テーブル:EKKO、フィールド:EKORG 例 1000US01DE01 | |||
| 通貨 Currency | 購買発注金額の通貨コードです。 | ||
| 説明 この属性は、購買発注金額の通貨(USD、EUR、GBPなど)を示します。金額を解釈するために欠かせない情報です。 グローバルに事業を展開する組織では、正確な財務分析に通貨の情報が欠かせません。発注金額を適切に集計・比較できるほか、金額に関する重要業績評価指標(KPI)を通貨単位と併せて解釈できます。 重要な理由 金額の通貨を明示し、特に多国籍の組織における正確な財務分析を支援します。 入手先 テーブル:EKKO、フィールド:WAERS 例 USDEURJPY | |||
調達から支払いまで:発注書のアクティビティ
| アクティビティ | 説明 | ||
|---|---|---|---|
| 入庫を転記 | このアクティビティは、特定の購買発注に対する商品の物理的な受領を示します。入庫の転記は明示的な操作であり(例:トランザクションMIGO)、品目伝票を作成して在庫を更新します。 | ||
| 重要な理由 仕入先の納品実績を追跡し、請求書照合プロセスの開始を把握するうえで重要な節目です。納期遵守率や入庫の適時性の算出にも使われます。 入手先 品目伝票の作成時に記録されます。イベントのタイムスタンプには、品目伝票ヘッダーテーブル(MKPF)の転記日(MKPF-BUDAT)または作成日(MKPF-CPUDT)を使用します。明細テーブル(MSEG)を介して購買発注と関連付けます。 記録 購買発注を参照する品目伝票について、MKPFテーブルの転記または作成のタイムスタンプを使用します。 イベントタイプ explicit | |||
| 購買依頼を作成 | このアクティビティは、商品やサービスの正式な依頼が作成されたことを示します。ユーザーが新しい購買依頼文書を保存すると(ME51Nなどのトランザクションを使用)、明示的なイベントとして記録され、EBANテーブルに一意のレコードが作成されます。 | ||
| 重要な理由 これは調達プロセスの主な開始点です。このイベントから購買発注の作成までにかかる時間を分析すると、社内の需要を実際の発注に変える効率を測定できます。 入手先 購買依頼ヘッダーテーブル(EBAN)にレコードが作成された時点で記録されます。このイベントのタイムスタンプには、作成日(EBAN-BADAT)と時刻が使われます。 記録 作成日を基に、EBANテーブルの新しいレコードを特定します。 イベントタイプ explicit | |||
| 購買発注を仕入先に送付 | このアクティビティは、承認済みの購買発注がEDI、メール、印刷などの方法で仕入先に正式に送信された時点を示します。出力メッセージが正常に処理されると、メッセージ制御テーブルに明示的なイベントとして記録されます。 | ||
| 重要な理由 この重要な節目から、仕入先のリードタイムの計測が始まります。このイベントから入庫までの時間を分析すると、仕入先の実績や納期遵守状況を評価できます。 入手先 メッセージ状況テーブル(NAST)に記録されます。該当する購買発注の出力タイプについて、処理状況(NAST-VSTAT)が「1」(正常に処理済み)の場合、NAST-DATVRとNAST-UHRVRからタイムスタンプを取得できます。 記録 購買発注の出力メッセージについて、NASTテーブルの処理タイムスタンプを使用します。 イベントタイプ explicit | |||
| 購買発注を作成 | このアクティビティは、仕入先との拘束力のある契約となる正式な購買発注文書が作成されたことを示します。ユーザーが購買発注(PO)を作成して保存すると(例:トランザクションME21N)、EKKOテーブルとEKPOテーブルにレコードが作成され、明示的なイベントとして記録されます。 | ||
| 重要な理由 購買発注のライフサイクルが正式に始まったことを示します。購買依頼から購買発注への変換時間と、発注から納品までの所要時間を測定するうえで重要な節目です。 入手先 該当する購買発注番号(EKKO-EBELN)について、購買発注ヘッダーテーブル(EKKO)の作成日(EKKO-AEDAT)から取得します。 記録 新しい購買発注ごとに、EKKOテーブルの作成タイムスタンプを使用します。 イベントタイプ explicit | |||
| 購買発注を完了 | 購買発注明細の納品がすべて完了したと見なされることを示します。通常、購買発注明細の「納品完了」インジケーターが自動または手動で設定されたことから推定されます。 | ||
| 重要な理由 このアクティビティは、発注履行プロセスの論理的な終点となります。作成から完了までの購買発注のサイクルタイム全体を算出するうえで欠かせません。 入手先 購買発注明細の「納品完了」インジケーター(EKPO-ELIKZ)が「X」に設定された時点を記録する変更文書(CDHDR/CDPOS)から推定します。最後の明細が完了としてマークされた時点を、購買発注全体の完了と見なすことができます。 記録 EKPO-ELIKZフラグが設定された時点のタイムスタンプを、変更文書から特定します。 イベントタイプ inferred | |||
| 購買発注を承認 | 購買発注が最終承認され、仕入先への送付が許可されたことを示します。この重要な節目は通常、購買発注のリリース状況が「完全リリース済み」または「承認済み」に変わった時点から推定されます。 | ||
| 重要な理由 このアクティビティは、購買発注の承認サイクルタイムの重要業績評価指標(KPI)を算出し、承認ワークフローのボトルネックを特定するうえで重要です。発注を仕入先に送るなど、その後の多くのアクティビティを進めるための前提条件でもあります。 入手先 購買発注ヘッダーテーブル(EKKO)の変更ログ(CDHDR/CDPOS)を追跡し、最終リリースコードが適用された時点、または全体のリリース状況インジケーター(EKKO-FRGKE)が「リリース済み」に設定された時点を特定します。 記録 購買発注の全体のリリース状況(EKKO-FRGKE)が最終承認状態に変わったタイムスタンプを特定します。 イベントタイプ inferred | |||
| サービス確認を入力 | サービスの購買発注では、サービスが提供されたことの確認を示します。サービス入力シートの作成時に明示的なイベントとして記録されます(例:トランザクションML81N)。 | ||
| 重要な理由 サービスにおける入庫に相当し、サービス発注の履行状況を追跡するうえで欠かせません。サービスの支払いに関する財務プロセスの開始にもつながります。 入手先 サービス入力シートのヘッダーテーブル(ESSR)の作成日(ESSR-ERDAT)から取得します。購買発注との関連付けにはESLLテーブルを使用します。 記録 購買発注に関連付けられたサービス入力シートについて、ESSRテーブルの作成タイムスタンプを使用します。 イベントタイプ explicit | |||
| 品質検査を実施 | 受領した商品が品質検査を受けたことを示します。通常、入庫時に作成された検査ロットに対して品質管理モジュールで使用決定が行われた時点から推定されます。 | ||
| 重要な理由 品質が重視される業界では、検査にかかる時間や結果の分析に役立ちます。この段階で遅延が発生すると、入庫から使用可能になるまでの間にボトルネックが生じることがあります。 入手先 品質管理モジュールのデータから推定します。入庫時に検査ロットが作成され(QALSテーブル)、タイムスタンプを含む使用決定が作成されると(QAVEテーブル)、このアクティビティが記録されます。 記録 品目伝票に関連付けられた検査ロットについて、QAVEテーブルの使用決定のタイムスタンプを特定します。 イベントタイプ inferred | |||
| 商品を返品 | 品質上の問題や誤出荷などを理由に、受領済みの商品を仕入先に返品したことを示します。返品専用の移動タイプを指定して品目伝票を転記すると、明示的なイベントとして記録されます。 | ||
| 重要な理由 このアクティビティから、仕入先の品質や発注内容の正確性に関する問題が分かり、プロセスの手戻りを示す重要な指標になります。入庫差異率の重要業績評価指標(KPI)の算出にも欠かせません。 入手先 返品移動タイプ(例:「仕入先への返品納品」を示す「122」)を使用すると、品目伝票テーブル(MKPF/MSEG)に記録されます。タイムスタンプには転記日(MKPF-BUDAT)を使用します。 記録 元の購買発注を参照する返品移動タイプ(例:122)の品目伝票を特定します。 イベントタイプ explicit | |||
| 購買依頼を承認 | 購買依頼が正式に承認され、購買発注への変換が許可されたことを示します。このイベントは、SAPのリリース戦略ワークフローで追跡される購買依頼データのリリース状況フィールドの変更から推定されます。 | ||
| 重要な理由 承認状況を追跡することで、発注前の段階にあるボトルネックを特定し、承認ポリシーへの準拠を確認できます。この段階での遅延は、調達サイクルタイム全体に直接影響します。 入手先 購買依頼テーブル(EBAN)の変更ログを基に推定します。具体的には、リリース状況フィールド(例:EBAN-FRGZU)の変更を監視するか、EBANオブジェクトの変更文書(CDHDR/CDPOS)を分析します。 記録 EBANのリリース状況フィールドに関する変更文書を監視し、最終承認のタイムスタンプを特定します。 イベントタイプ inferred | |||
| 購買発注の承認を申請 | 作成または変更された購買発注が、設定済みのリリース戦略に従って承認に回されたことを示します。リリース戦略が開始され、購買発注が承認待ちの状態になると、このイベントが推定されます。 | ||
| 重要な理由 購買発注の作成と承認プロセスの開始を区別すると、承認サイクルタイムの重要業績評価指標(KPI)を正確に測定できます。また、承認ワークフローが始まるまでの遅れも把握できます。 入手先 購買発注(オブジェクトEINKBELEG)の変更文書(CDHDR/CDPOS)から、リリース状況が初めて設定されたことを確認して推定します。または、全体のリリース状況(EKKO-FRGKE)が、承認プロセスの開始を示す値に初めて設定された時点を確認します。 記録 購買発注のリリース戦略を開始した最初の変更文書レコードを特定します。 イベントタイプ inferred | |||
| 購買発注を削除 | 購買発注明細の取り消し、または論理削除を示します。これにより、入庫や請求などの後続処理ができなくなります。購買発注明細に削除インジケーターが設定された時点から推定されるイベントです。 | ||
| 重要な理由 このアクティビティは、発注が取り消されたことを示す終端イベントです。発注が削除された理由や時期を分析すると、需要計画や仕入先選定の問題を明らかにできます。 入手先 購買発注明細の削除インジケーター(EKPO-LOEKZ)が「L」に設定されたことを示す変更文書(CDHDR/CDPOS)から推定します。 記録 EKPO-LOEKZフラグが設定された時点のタイムスタンプを、変更文書から特定します。 イベントタイプ inferred | |||
| 購買発注を却下 | 承認ワークフロー中に承認者が購買発注を却下した場合に発生します。購買発注のリリース戦略データに記録された状況変更から、却下があったことを推定するイベントです。 | ||
| 重要な理由 却下を追跡すると、購買発注のデータ品質やポリシーへの準拠、承認マトリクスに関する問題を特定できます。却下によって手戻りが発生し、サイクルタイムが長くなることも少なくありません。 入手先 購買発注のリリース状況に関する変更文書(CDHDR/CDPOS)から推定します。通常、リリースコードが取り消された場合や、特定の却下状況が設定された場合に、却下が記録されます。 記録 リリースコードの取り消し、または却下を示す状況変更について、変更ログを監視します。 イベントタイプ inferred | |||
| 購買発注を変更 | 購買発注の作成後に行われた数量、価格、納期などの変更を示します。これらの変更は、SAPの変更文書システムに明示的に記録されます。 | ||
| 重要な理由 特に承認後の頻繁な変更は、プロセスの非効率、初期計画の不備、または対象範囲の拡大を示します。このアクティビティは、購買発注の手戻りと変更に関するダッシュボードや関連する重要業績評価指標(KPI)に欠かせません。 入手先 購買発注オブジェクト(EINKBELEG)の変更文書ヘッダー(CDHDR)テーブルと明細(CDPOS)テーブルに明示的に記録されます。変更ごとにタイムスタンプ付きの新しいレコードが作成されます。 記録 購買発注番号に関連付けられたCDHDRテーブルとCDPOSテーブルから、変更イベントとタイムスタンプを抽出します。 イベントタイプ explicit | |||
データ抽出ガイド
ステップ
- ABAPプログラムの作成:トランザクションコードSE38でABAPエディターを開きます。新しいプログラム名(例:Z_PM_PO_EXTRACT)を入力し、「作成」をクリックします。タイトルに「Process Mining PO Data Extraction」などを入力し、タイプを「実行可能プログラム」に設定します。
- 選択画面の定義:プログラム内で選択画面のパラメーターを定義します。これにより、抽出するデータを絞り込めます。主なパラメーターは、発注書の作成日範囲、会社コード(BUKRS)、購買伝票タイプ(BSART)です。
- データ構造の定義:最終的なイベントログの形式に合わせて、内部テーブルの構造を宣言します。PurchaseOrder、Activity、EventTime、UserName、VendorNumber、OrderAmount、MaterialGroup、CompanyCode、DocumentTypeなど、必要な属性と推奨属性を含めます。
- データ選択ロジックの実装:必要な14種類のアクティビティごとにデータを選択するABAPの主要ロジックを記述します。EKKO、EKPO、EKBE、EBAN、CDHDR、CDPOS、NASTなど、複数のSAPテーブルを照会します。コードを整理しやすくするため、アクティビティごとに個別のサブルーチン(PERFORM)を使用します。
- 購買依頼データの選択:EBANテーブルを照会し、「購買依頼作成」イベントを取得します。EKPOテーブルを介して発注書と関連付けます。変更ログテーブル(CDHDR、CDPOS)を使い、リリースステータス項目の変更を追跡して「購買依頼承認」イベントを特定します。
- 発注書の主要イベントの選択:EKKOテーブルとEKPOテーブルを照会し、「発注書作成」イベントを取得します。オブジェクトEINKBELEGの変更ログテーブル(CDHDR、CDPOS)を使い、リリースインジケーターや削除フラグなどの特定項目の変更に基づいて、「発注書変更」「発注書承認」「発注書却下」「発注書完了」「発注書削除」イベントを抽出します。
- 発注書の送信イベントの選択:NASTテーブルを照会し、発注書が正常に送信されたレコードを見つけて、「発注書を仕入先に送信」アクティビティを記録します。
- 商品・サービスのイベントの選択:EKBEテーブルで入出庫伝票の転記を照会し、移動タイプのカテゴリに基づいて「入庫転記」と「商品返品」アクティビティを特定します。サービス入力シートの「サービス確認入力」イベントを取得するには、ESSRとESLLを照会します。
- 品質管理イベントの選択:品質管理モジュールを使用している場合は、QALSとQAVEを照会し、発注書に関連付けられた検査ロットの使用決定が行われた時点を特定します。これを「品質検査実施」アクティビティとして記録します。
- データの統合と形式の調整:個別の選択処理で取得したデータを、最終的な単一の内部テーブルにまとめます。EventTime項目の形式を統一します(例:YYYY-MM-DDTHH:MI:SS)。
- ファイルのダウンロード機能の実装:最終的な内部テーブルをファイルとしてダウンロードする機能を追加します。タブ区切りまたはCSV形式を推奨します。GUI_DOWNLOAD関数モジュールを使用できます。
- 実行と保存:トランザクションSE38またはSA38でプログラムを実行します。選択条件を入力してレポートを実行し、出力ファイルの保存を求められたら、アップロードに備えてローカルマシンに.csv拡張子で保存します。
設定
- 日付範囲:抽出対象の日付範囲を指定します。通常は発注書の作成日(EKKO-AEDAT)を基準にします。データ量とプロセス分析のバランスを取るため、まずは3~6か月を対象にする方法が一般的です。
- 会社コード(BUKRS):1つ以上の会社コードで絞り込み、対象となる法人のみを抽出します。パフォーマンスと分析の関連性を保つための重要なパラメーターです。
- 購買伝票タイプ(BSART):特定の伝票タイプ(例:「NB」は標準発注書)で絞り込みます。必要に応じて特殊な調達タイプを除外し、標準的なプロセスに焦点を当てます。
- データの粒度:発注明細単位でデータを抽出します。ケースIDには発注書番号(EBELN)を使用します。入庫など明細単位のイベントも、すべてこのケースIDに関連付けます。
- パフォーマンスに関する考慮事項:大規模なデータセットでは、タイムアウトを避けるため、プログラムをバックグラウンドジョブ(SM36)として実行するように設定します。特にCDHDRやCDPOSなど、WHERE句で使用する主要項目にデータベースインデックスが設定されていることを確認してください。
- 前提条件:レポートを実行するユーザーには、ABAPワークベンチ(SE38)へのアクセス権限と、プログラムの開発・実行権限が必要です。また、EKKO、EKPO、EKBE、CDHDR、CDPOS、EBAN、NAST、ESSR、QM関連テーブルを含む、すべての基盤テーブルへの読み取り権限も必要です。
クエリの例 abap
REPORT Z_PM_PO_EXTRACT.
TABLES: ekko, ekpo, eban.
*&---------------------------------------------------------------------*
*& Data Structures for Event Log
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
purchaseorder TYPE ebeln,
activity TYPE string,
eventtime TYPE timestamp,
username TYPE ernam,
vendornumber TYPE lifnr,
orderamount TYPE netwr_ak,
materialgroup TYPE matkl,
companycode TYPE bukrs,
documenttype TYPE bsart,
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_aedat FOR ekko-aedat OBLIGATORY, " PO Creation Date
s_bukrs FOR ekko-bukrs, " Company Code
s_bsart FOR ekko-bsart, " PO Document Type
s_ebeln FOR ekko-ebeln. " PO Number
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM get_po_headers.
IF gt_event_log IS NOT INITIAL.
PERFORM get_pr_created.
PERFORM get_pr_approved.
PERFORM get_po_created.
PERFORM get_po_release_events. " Approved, Rejected, Approval Requested
PERFORM get_po_sent_to_vendor.
PERFORM get_po_changed.
PERFORM get_goods_receipt_posted.
PERFORM get_services_confirmed.
PERFORM get_quality_inspection.
PERFORM get_goods_returned.
PERFORM get_po_completed.
PERFORM get_po_deleted.
PERFORM download_to_csv.
ELSE.
MESSAGE 'No Purchase Orders found for the given criteria.' TYPE 'I'.
ENDIF.
*&---------------------------------------------------------------------*
*& Form GET_PO_HEADERS (Base data)
*&---------------------------------------------------------------------*
FORM get_po_headers.
SELECT h~ebeln, h~lifnr, h~bukrs, h~bsart, p~netwr, p~matkl
FROM ekko AS h
INNER JOIN ekpo AS p ON h~ebeln = p~ebeln
INTO TABLE @DATA(lt_po_base)
WHERE h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND h~bsart IN @s_bsart
AND h~ebeln IN @s_ebeln.
SORT lt_po_base BY ebeln.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PR_CREATED
*&---------------------------------------------------------------------*
FORM get_pr_created.
DATA: lt_pr_events TYPE TABLE OF ty_event_log.
SELECT p~ebeln AS purchaseorder,
'Purchase Requisition Created' AS activity,
b~erdat AS event_date,
'000000' AS event_time,
b~ernam AS username,
h~lifnr AS vendornumber,
p~netwr AS orderamount,
p~matkl AS materialgroup,
h~bukrs AS companycode,
h~bsart AS documenttype
FROM ekpo AS p
JOIN eban AS b ON p~banfn = b~banfn AND p~bnfpo = b~bnfpo
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE p~ebeln IN @s_ebeln
AND p~banfn IS NOT NULL AND p~banfn <> ''
AND h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND h~bsart IN @s_bsart
INTO TABLE @DATA(lt_pr_created).
LOOP AT lt_pr_created ASSIGNING FIELD-SYMBOL(<fs_pr>).
DATA(ls_event) = CORRESPONDING ty_event_log(<fs_pr>).
CONCATENATE <fs_pr>-event_date <fs_pr>-event_time INTO DATA(lv_ts).
CONVERT DATE <fs_pr>-event_date TIME '000000' INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PR_APPROVED
*&---------------------------------------------------------------------*
FORM get_pr_approved.
DATA: lt_pr_list TYPE TABLE OF eban-banfn.
SELECT DISTINCT p~banfn FROM ekpo AS p
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND p~banfn IS NOT NULL AND p~banfn <> ''
INTO TABLE @lt_pr_list.
IF lt_pr_list IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime, p~fname, p~value_new
FROM cdhdr AS h
JOIN cdpos AS p ON h~objectid = p~objectid AND h~changenr = p~changenr
FOR ALL ENTRIES IN @lt_pr_list
WHERE h~objectclas = 'BANF'
AND h~objectid = @lt_pr_list-table_line
AND p~tabname = 'EBAN'
AND p~fname = 'FRGZU'
INTO TABLE @DATA(lt_cd_pr).
LOOP AT lt_cd_pr ASSIGNING FIELD-SYMBOL(<fs_cd>) WHERE <fs_cd>-value_new = 'X'.
SELECT SINGLE p~ebeln, p~netwr, p~matkl, h~lifnr, h~bukrs, h~bsart
FROM ekpo AS p
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE p~banfn = @<fs_cd>-objectid(10)
INTO @DATA(ls_po_info).
IF sy-subrc = 0.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = ls_po_info-ebeln
activity = 'Purchase Requisition Approved'
username = <fs_cd>-username
vendornumber = ls_po_info-lifnr
orderamount = ls_po_info-netwr
materialgroup = ls_po_info-matkl
companycode = ls_po_info-bukrs
documenttype = ls_po_info-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_CREATED
*&---------------------------------------------------------------------*
FORM get_po_created.
LOOP AT lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>).
SELECT SINGLE aedat, ernam FROM ekko INTO @DATA(ls_ekko)
WHERE ebeln = @<fs_po>-ebeln.
IF sy-subrc = 0.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Created'
username = ls_ekko-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE ls_ekko-aedat TIME '000000' INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_RELEASE_EVENTS
*&---------------------------------------------------------------------*
FORM get_po_release_events.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime, p~value_new
FROM cdhdr AS h
JOIN cdpos AS p ON h~objectid = p~objectid AND h~changenr = p~changenr
WHERE h~objectclas = 'EINKBELEG'
AND h~objectid IN lt_ebeln
AND p~tabname = 'EKKO'
AND p~fname = 'FRGKE'
INTO TABLE @DATA(lt_cd_po).
LOOP AT lt_cd_po ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
CASE <fs_cd>-value_new.
WHEN '2' OR 'R'. " Final Release
ls_event-activity = 'Purchase Order Approved'.
WHEN '1'. " Blocked
ls_event-activity = 'Purchase Order Rejected'.
WHEN OTHERS. " Any other change implies a pending state
ls_event-activity = 'Purchase Order Approval Requested'.
ENDCASE.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_SENT_TO_VENDOR
*&---------------------------------------------------------------------*
FORM get_po_sent_to_vendor.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT objky, erdat, eruhr, ernam
FROM nast
WHERE kapol = 'EF' AND objky IN lt_ebeln AND vstat = '1'
INTO TABLE @DATA(lt_nast).
LOOP AT lt_nast ASSIGNING FIELD-SYMBOL(<fs_nast>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_nast>-objky.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Sent to Vendor'
username = <fs_nast>-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_nast>-erdat TIME <fs_nast>-eruhr INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_CHANGED
*&---------------------------------------------------------------------*
FORM get_po_changed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT DISTINCT objectid, username, udate, utime
FROM cdhdr
WHERE objectclas = 'EINKBELEG' AND objectid IN lt_ebeln AND tcode <> 'ME21N' AND tcode <> 'ME22'
INTO TABLE @DATA(lt_cdhdr_chg).
LOOP AT lt_cdhdr_chg ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Changed'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_GOODS_RECEIPT_POSTED
*&---------------------------------------------------------------------*
FORM get_goods_receipt_posted.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT k~ebeln, m~cpudt, m~cputm, m~usnam, k~bewtp
FROM ekbe AS k JOIN mkpf AS m ON k~belnr = m~mblnr AND k~gjahr = m~mjahr
WHERE k~ebeln IN lt_ebeln AND k~bewtp = 'E' AND k~shkzg = 'S'
INTO TABLE @DATA(lt_gr).
LOOP AT lt_gr ASSIGNING FIELD-SYMBOL(<fs_gr>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_gr>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Goods Receipt Posted'
username = <fs_gr>-usnam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_gr>-cpudt TIME <fs_gr>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_SERVICES_CONFIRMED
*&---------------------------------------------------------------------*
FORM get_services_confirmed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT l~ebeln, h~erdat, h~eruhr, h~ernam
FROM essr AS h JOIN esll AS l ON h~lblni = l~lblni
WHERE l~ebeln IN lt_ebeln
INTO TABLE @DATA(lt_ses).
LOOP AT lt_ses ASSIGNING FIELD-SYMBOL(<fs_ses>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_ses>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Services Confirmation Entered'
username = <fs_ses>-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_ses>-erdat TIME <fs_ses>-eruhr INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_QUALITY_INSPECTION
*&---------------------------------------------------------------------*
FORM get_quality_inspection.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT q~ebeln, v~vdatum, v~vzeit, v~vname
FROM qals AS q JOIN qave AS v ON q~prueflos = v~prueflos
WHERE q~ebeln IN lt_ebeln
INTO TABLE @DATA(lt_qm).
LOOP AT lt_qm ASSIGNING FIELD-SYMBOL(<fs_qm>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_qm>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Quality Inspection Performed'
username = <fs_qm>-vname
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_qm>-vdatum TIME <fs_qm>-vzeit INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_GOODS_RETURNED
*&---------------------------------------------------------------------*
FORM get_goods_returned.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT k~ebeln, m~cpudt, m~cputm, m~usnam
FROM ekbe AS k JOIN mkpf AS m ON k~belnr = m~mblnr AND k~gjahr = m~mjahr
WHERE k~ebeln IN lt_ebeln AND k~bwart = '122'
INTO TABLE @DATA(lt_ret).
LOOP AT lt_ret ASSIGNING FIELD-SYMBOL(<fs_ret>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_ret>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Goods Returned'
username = <fs_ret>-usnam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_ret>-cpudt TIME <fs_ret>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_COMPLETED
*&---------------------------------------------------------------------*
FORM get_po_completed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime
FROM cdhdr AS h JOIN cdpos AS p ON h~changenr = p~changenr AND h~objectid = p~objectid
WHERE h~objectclas = 'EINKBELEG' AND h~objectid IN lt_ebeln AND p~tabname = 'EKPO' AND p~fname = 'ELIKZ' AND p~value_new = 'X'
INTO TABLE @DATA(lt_cd_comp).
LOOP AT lt_cd_comp ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Completed'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_DELETED
*&---------------------------------------------------------------------*
FORM get_po_deleted.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime
FROM cdhdr AS h JOIN cdpos AS p ON h~changenr = p~changenr AND h~objectid = p~objectid
WHERE h~objectclas = 'EINKBELEG' AND h~objectid IN lt_ebeln AND p~tabname = 'EKPO' AND p~fname = 'LOEKZ' AND p~value_new = 'L'
INTO TABLE @DATA(lt_cd_del).
LOOP AT lt_cd_del ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Deleted'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form DOWNLOAD_TO_CSV
*&---------------------------------------------------------------------*
FORM download_to_csv.
DATA: lv_filename TYPE string.
DATA: lt_fieldnames TYPE TABLE OF string.
APPEND 'PurchaseOrder' TO lt_fieldnames.
APPEND 'Activity' TO lt_fieldnames.
APPEND 'EventTime' TO lt_fieldnames.
APPEND 'UserName' TO lt_fieldnames.
APPEND 'VendorNumber' TO lt_fieldnames.
APPEND 'OrderAmount' TO lt_fieldnames.
APPEND 'MaterialGroup' TO lt_fieldnames.
APPEND 'CompanyCode' TO lt_fieldnames.
APPEND 'DocumentType' TO lt_fieldnames.
DATA(lv_header) = REDUCE string( INIT h = '' FOR f IN lt_fieldnames NEXT h = h && f && cl_abap_char_utilities=>horizontal_tab ).
REPLACE LAST OCCURRENCE OF cl_abap_char_utilities=>horizontal_tab IN lv_header WITH cl_abap_char_utilities=>cr_lf.
DATA(lv_file_content) = lv_header.
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_log>).
DATA lv_line TYPE string.
DATA lv_eventtime_str TYPE string.
lv_eventtime_str = |{ <fs_log>-eventtime TIMESTAMP = ISO }|.
lv_line = <fs_log>-purchaseorder && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-activity && cl_abap_char_utilities=>horizontal_tab &&
lv_eventtime_str && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-username && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-vendornumber && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-orderamount && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-materialgroup && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-companycode && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-documenttype && cl_abap_char_utilities=>cr_lf.
CONCATENATE lv_file_content lv_line INTO lv_file_content.
ENDLOOP.
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
filename = 'C:\temp\po_event_log.csv'
filetype = 'ASC'
CHANGING
data_tab = lv_file_content. ステップ
- データベース接続の確立:SAP ECCの基盤データベースに接続するための読み取り専用認証情報と接続情報(ホスト名、ポート、データベース名)を取得します。DBeaver、SQL Developer、SSMSなどのクライアントツールをインストールしてください。
- SAPスキーマの特定:データベースに接続し、テーブルが格納されているSAPの主要スキーマを特定します。通常はSAPSR3、SAPHANADBなど、システム固有の名前が使われます。ユーザーのデフォルトスキーマでない場合は、クエリ内のすべてのテーブル名にスキーマ名を付ける必要があります。
- SQLクエリの確認:提供されたSQLスクリプトをクライアントツールで開きます。このクエリは、複数のSAPテーブルを結合し、調達から支払いまでのプロセスから14種類のアクティビティを抽出するように設計されています。
- クエリパラメーターの設定:スクリプトの先頭にあるPO_BASE共通テーブル式(CTE)を探し、抽出範囲を指定するプレースホルダーの値を変更します。
- [START_DATE]と[END_DATE]:分析対象の日付範囲を設定します(例:「20230101」と「20230630」)。AEDAT(変更日)項目で絞り込む方法を推奨します。
- [COMPANY_CODE_1]、[COMPANY_CODE_2]:対象に含めるSAP会社コードを指定します。
- [DOC_TYPE_1]、[DOC_TYPE_2]:対象に含める発注書の伝票タイプを指定します。
- [Your SAP Schema]:スクリプト内のプレースホルダーを、実際のSAPスキーマ名に置き換えます。
- クエリの実行:設定したSQLスクリプトをSAPデータベースに対して実行します。実行時間は、日付範囲、データ量、データベースのパフォーマンスによって異なります。
- 結果の確認:クエリの完了後、出力内容を簡単に確認します。行数が妥当であること、PurchaseOrder、Activity、EventTimeなどの主要列に想定どおり値が入っていることを確認してください。
- データのCSV出力:SQLクライアントから結果セット全体をCSVファイルに出力します。文字化けを防ぐため、UTF-8エンコーディングを使用してください。
- アップロードの準備:CSVファイルの列見出しが、必要な属性名と完全に一致していることを確認します:PurchaseOrder、Activity、EventTime、UserName、VendorNumber、OrderAmount、MaterialGroup、CompanyCode、DocumentType。
- プロセスマイニングツールへのアップロード:最終的なCSVファイルをプロセスマイニングアプリケーションにアップロードし、分析と可視化を行います。
設定
- 前提条件:SAP ECCの基盤データベースに対する直接の読み取り専用アクセスが必要です。EKKO、EKPO、EKBE、EBAN、CDHDR、CDPOS、NASTなどのテーブルを照会するための十分な権限が必要です。
- 日付範囲による絞り込み:データ量を抑えるため、日付範囲で必ず絞り込んでください。EKKO.AEDAT(発注書変更日)を使い、3~6か月を対象にする方法が一般的です。日付範囲を広げすぎると、クエリの実行に非常に長い時間がかかることがあります。
- 主要データの絞り込み:分析対象を適切に絞るため、EKKO.BUKRS(会社コード)とEKKO.BSART(伝票タイプ)で必ず絞り込んでください。対象となる法人と業務プロセスを限定できます。
- パフォーマンスに関する考慮事項:このクエリでは、変更履歴テーブル(CDHDR、CDPOS)を含む複数の大規模テーブルを結合するため、システムリソースを多く消費する場合があります。システムへの影響を避けるため、利用の少ない時間帯、または複製した非本番データベースでの実行を強く推奨します。
- 変更文書の記録:「承認済み」「却下」「完了」「変更」などのアクティビティを正確に取得できるかどうかは、SAPで該当項目の変更文書記録が有効になっているかに左右されます。SAP管理者に、トランザクションSCDOで記録が有効になっていることを確認してください。
クエリの例 sql
WITH PO_BASE AS (
SELECT
H.EBELN, -- Purchase Order Number
I.EBELP, -- Purchase Order Item
H.LIFNR, -- Vendor Number
H.BUKRS, -- Company Code
H.BSART, -- Document Type
I.NETWR, -- Order Amount (Item Level)
I.MATKL, -- Material Group
I.BANFN, -- Purchase Requisition Number
I.BNFPO -- Purchase Requisition Item
FROM [Your SAP Schema].EKKO AS H
JOIN [Your SAP Schema].EKPO AS I ON H.EBELN = I.EBELN
WHERE H.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' -- Filter on PO Change Date, e.g., '20230101' and '20231231'
AND H.BUKRS IN ('[COMPANY_CODE_1]', '[COMPANY_CODE_2]') -- Specify Company Codes
AND H.BSART IN ('[DOC_TYPE_1]', '[DOC_TYPE_2]') -- Specify PO Document Types
)
-- 1. Purchase Requisition Created
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Requisition Created' AS "Activity",
TO_TIMESTAMP(CONCAT(pr.ERDAT, '000000'), 'YYYYMMDDHH24MISS') AS "EventTime", -- Time is not available in EBAN
pr.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EBAN pr ON po.BANFN = pr.BANFN AND po.BNFPO = pr.BNFPO
WHERE po.BANFN IS NOT NULL AND po.BANFN <> ''
UNION ALL
-- 2. Purchase Requisition Approved
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Requisition Approved' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'BANF' AND ch.OBJECTID = po.BANFN
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EBAN' AND cp.FNAME = 'FRGZU' AND cp.VALUE_NEW = 'X' -- Release indicator set to 'released'
UNION ALL
-- 3. Purchase Order Created
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Created' AS "Activity",
TO_TIMESTAMP(CONCAT(ekko.ERDAT, ' ', ekko.ERZET), 'YYYYMMDD HH24MISS') AS "EventTime",
ekko.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKKO ekko ON po.EBELN = ekko.EBELN
UNION ALL
-- 4. Purchase Order Approval Requested / 5. Approved / 6. Rejected (from Change Docs)
SELECT
po.EBELN AS "PurchaseOrder",
CASE
WHEN cp.VALUE_NEW > cp.VALUE_OLD THEN 'Purchase Order Approval Requested'
WHEN cp.VALUE_NEW = ekko.FRGKE AND ekko.FRGKE = 'R' THEN 'Purchase Order Approved'
ELSE 'Purchase Order Rejected' -- Simplified logic, may need adjustment
END AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKKO ekko ON po.EBELN = ekko.EBELN
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID = po.EBELN
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKKO' AND cp.FNAME = 'FRGZU' -- Release status
UNION ALL
-- 7. Purchase Order Sent to Vendor
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Sent to Vendor' AS "Activity",
TO_TIMESTAMP(CONCAT(na.ERDAT, ' ', na.ERUHR), 'YYYYMMDD HH24MISS') AS "EventTime",
na.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].NAST na ON na.OBJKY = po.EBELN AND na.KSCHL = '[Your PO Output Type]' -- e.g., 'NEU'
WHERE na.VSTAT = '1' -- Successfully processed
UNION ALL
-- 8. Purchase Order Changed
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Changed' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID = po.EBELN
WHERE ch.TCODE IN ('ME22', 'ME22N') -- Filter for change transactions
UNION ALL
-- 9. Goods Receipt Posted
SELECT
ekbe.EBELN AS "PurchaseOrder",
'Goods Receipt Posted' AS "Activity",
TO_TIMESTAMP(CONCAT(mkpf.CPUDT, ' ', mkpf.CPUTM), 'YYYYMMDD HH24MISS') AS "EventTime",
mkpf.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM [Your SAP Schema].EKBE AS ekbe
JOIN [Your SAP Schema].MKPF AS mkpf ON ekbe.BELNR = mkpf.MBLNR AND ekbe.GJAHR = mkpf.MJAHR
JOIN PO_BASE AS po ON ekbe.EBELN = po.EBELN AND ekbe.EBELP = po.EBELP
WHERE ekbe.BEWTP = 'E' -- Goods Receipt
AND ekbe.SHKZG = 'S' -- Debit/Credit Indicator: Goods Receipt
UNION ALL
-- 10. Services Confirmation Entered
SELECT
po.EBELN AS "PurchaseOrder",
'Services Confirmation Entered' AS "Activity",
TO_TIMESTAMP(CONCAT(essr.ERDAT, ' ', essr.ERZET), 'YYYYMMDD HH24MISS') AS "EventTime",
essr.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKBE ekbe ON po.EBELN = ekbe.EBELN AND po.EBELP = ekbe.EBELP
JOIN [Your SAP Schema].ESSR essr ON ekbe.LBLNI = essr.LBLNI
WHERE ekbe.BEWTP = 'L' -- Service Entry Sheet
UNION ALL
-- 11. Quality Inspection Performed
SELECT
po.EBELN AS "PurchaseOrder",
'Quality Inspection Performed' AS "Activity",
TO_TIMESTAMP(CONCAT(qave.VDATUM, ' ', qave.VZEIT), 'YYYYMMDD HH24MISS') AS "EventTime",
qave.VNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKBE ekbe ON po.EBELN = ekbe.EBELN AND po.EBELP = ekbe.EBELP
JOIN [Your SAP Schema].QALS qals ON qals.MBLNR = ekbe.BELNR AND qals.MJAHR = ekbe.GJAHR
JOIN [Your SAP Schema].QAVE qave ON qals.PRUEFLOS = qave.PRUEFLOS
WHERE ekbe.BEWTP = 'E' -- Linked to a Goods Receipt
UNION ALL
-- 12. Goods Returned
SELECT
ekbe.EBELN AS "PurchaseOrder",
'Goods Returned' AS "Activity",
TO_TIMESTAMP(CONCAT(mkpf.CPUDT, ' ', mkpf.CPUTM), 'YYYYMMDD HH24MISS') AS "EventTime",
mkpf.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM [Your SAP Schema].EKBE AS ekbe
JOIN [Your SAP Schema].MKPF AS mkpf ON ekbe.BELNR = mkpf.MBLNR AND ekbe.GJAHR = mkpf.MJAHR
JOIN PO_BASE AS po ON ekbe.EBELN = po.EBELN AND ekbe.EBELP = po.EBELP
WHERE ekbe.BEWTP = 'E' -- Goods Movement
AND ekbe.SHKZG = 'H' -- Debit/Credit Indicator: Return
AND ekbe.BWART = '122' -- Movement type for return to vendor
UNION ALL
-- 13. Purchase Order Completed
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Completed' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID LIKE CONCAT(po.EBELN, po.EBELP, '%')
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKPO' AND cp.FNAME = 'ELIKZ' AND cp.VALUE_NEW = 'X' -- Delivery completed indicator
UNION ALL
-- 14. Purchase Order Deleted
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Deleted' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID LIKE CONCAT(po.EBELN, po.EBELP, '%')
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKPO' AND cp.FNAME = 'LOEKZ' AND cp.VALUE_NEW = 'L'; -- Deletion indicator ステップ
- 前提条件と接続:サードパーティETLツールにSAP認証コネクターがインストールされ、ライセンスが有効であることを確認します。ETLツールの管理コンソールで、SAP ECCシステムへの新しい接続を設定します。アプリケーションサーバーホスト、システム番号、クライアントIDに加え、適切なRFC権限とテーブル読み取り権限を持つ専用のSAPユーザーが必要です。
- ソーステーブルの特定:ETLジョブまたはデータフローで、必要なSAPテーブルをデータソースとして定義します。主なテーブルは、EKKO(発注書ヘッダー)、EKPO(発注明細)、EBAN(購買依頼)、CDHDR(変更文書ヘッダー)、CDPOS(変更文書明細)、MSEG(伝票セグメント:品目)、MKPF(入出庫伝票ヘッダー)、NAST(メッセージステータス)、ESSR(サービス入力シートヘッダー)、QALS(検査ロット)です。
- 「発注書作成」の抽出:EKKOテーブルをソースとするデータフローを作成します。対象の日付範囲(例:AEDAT)と組織の範囲(例:会社コードのBUKRS、伝票タイプのBSART)でレコードを絞り込みます。EKKO.EBELNをPurchaseOrderに、「発注書作成」をActivityに割り当て、AEDATとERZETを組み合わせてEventTimeを設定します。その他の必要な属性も割り当てます。
- 「入庫転記」の抽出:MSEGをソースとする別のデータフローを作成し、MBLNRとMJAHRを使ってMKPFと結合します。「101」など、対象となる移動タイプで絞り込みます。MSEG.EBELNをPurchaseOrderに、「入庫転記」をActivityに割り当て、MKPF.CPUDTとMKPF.CPUTMをEventTimeに使用します。
- 変更に基づくイベントの抽出(承認、変更、削除):CDHDRとCDPOSをCHANGENRで結合したデータフローを作成します。このデータソースから複数のアクティビティを導出できます。
- OBJECTCLAS = 'EINKBELEG'かつTABNAME = 'EKPO'で絞り込みます。
- **「発注書承認」**では、リリースステータス項目(例:FNAME = 'FRGZU')の変更を絞り込み、VALUE_NEWの新しい値が最終承認を示すレコードを取得します。
- **「発注書削除」**では、削除インジケーター(FNAME = 'LOEKZ')の変更を絞り込み、新しい値が「L」のレコードを取得します。
- **「発注書変更」**では、他の関連項目の変更を絞り込み、他のアクティビティに使用するステータス項目の変更は除外します。
- これらのイベントでは、CDHDR.UDATEとCDHDR.UTIMEをEventTimeに使用します。
- 「購買依頼」イベントの抽出:EBANから「購買依頼作成」のデータフローを作成します。購買依頼番号(BANFN)と明細(BNFPO)を使ってEBANとEKPOを結合し、購買依頼を発注書のケースに関連付けます。「購買依頼承認」には、OBJECTCLAS = 'BANF'のCDHDRとCDPOSを使用します。イベントを最終的な発注書に正しく関連付けるため、慎重なマッピングが必要です。
- 「発注書を仕入先に送信」の抽出:NASTテーブルをソースとするデータフローを作成します。発注書番号を含むOBJECTKEY、該当する出力タイプ(KSCHL)、処理が成功したステータス(VSTAT = '1')で絞り込みます。EventTimeにはERDATとUHRを使用します。
- アクティビティのデータフローの統合:前の手順で作成した各データフローの出力を、ETLツールの「Union」または「Merge」変換で統合します。すべてのデータフローで列名とデータ型(PurchaseOrder、Activity、EventTimeなど)を統一してください。
- データ型と形式の変換:EventTime列のタイムスタンプ形式を統一します(例:YYYY-MM-DD HH:MM:SS)。OrderAmountは標準的な小数形式に変換します。
- 出力先の設定:統合したデータストリームの出力先(「sink」)を設定します。通常はCSVやParquetなどのフラットファイルを指定し、区切り文字、テキスト修飾子、ヘッダーのオプションを設定します。
- 実行と検証:ETLジョブ全体を実行します。出力ファイルを検証し、14種類すべてのアクティビティが含まれていること、行数が妥当であること、主要な属性に正しく値が設定されていることを確認します。
- スケジュール設定とエクスポート:検証後、データを最新の状態に保つため、ETLジョブを定期的(例:毎晩)に実行するよう設定します。生成されたファイルをプロセスマイニングツールにアップロードできます。
設定
- 前提条件:ECC用のSAP認定コネクターを備えた商用ETLツール(Informatica PowerCenter、Talend、SAP Data Servicesなど)。必要なテーブルに対するS_RFCおよびS_TABU_DISの権限を持つSAPダイアログユーザーまたはシステムユーザー。
- SAP接続:コネクターにSAPアプリケーションサーバー、システム番号、クライアント、ユーザー、パスワードを設定する必要があります。セキュアネットワーク通信(SNC)の使用を推奨します。
- 日付範囲フィルター:データ量を抑えるため、日付範囲フィルターを必ず適用してください。一般的には、EKKO.AEDAT(発注書作成日)を対象に、直近3~12か月のデータに絞り込みます。SAPから過剰なデータを抽出しないよう、このフィルターはデータソース側で適用してください。
- 組織範囲フィルター:必ずEKKO.BUKRS(会社コード)で絞り込みます。分析対象を特定の事業部門に限定する場合は、EKPO.WERKS(プラント)またはEKKO.EKORG(購買組織)による絞り込みも検討してください。
- 伝票タイプフィルター:EKKO.BSARTを使って対象となる発注書タイプのみを含め、標準的な調達から支払いまでのプロセスに含まれない在庫転送やその他の社内伝票を除外します。
- パフォーマンスの調整:変更伝票テーブル(CDHDR、CDPOS)からの抽出には時間がかかる場合があります。OBJECTCLAS、OBJECTID、UDATEに対するフィルターが適用されていることを確認してください。データ転送速度を最適化するには、SAPコネクターの「パケットサイズ」設定を調整します。大規模なシステムでは、初回に過去データを読み込んだ後、差分データを定期的に読み込む方法を検討してください。
クエリの例 sql
/*
This is a logical representation of the transformations performed within the ETL tool.
The tool's graphical interface will be used to configure these separate data flows, which are then combined with a UNION transformation.
Placeholders like [Your ETL Tool Functions] and [Filter Values] must be configured in the tool.
*/
-- 1. Purchase Requisition Created
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Requisition Created' AS Activity,
[Your ETL Tool Functions].DateTime(eban.ERDAT, eban.ERZET) AS EventTime,
eban.ERNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM EBAN AS eban
INNER JOIN EKPO AS ekpo ON eban.BANFN = ekpo.BANFN AND eban.BNFPO = ekpo.BNFPO
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 2. Purchase Requisition Approved (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Requisition Approved' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EBAN AS eban ON cdhdr.OBJECTID = eban.BANFN
INNER JOIN EKPO AS ekpo ON eban.BANFN = ekpo.BANFN AND eban.BNFPO = ekpo.BNFPO
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'BANF' AND cdpos.TABNAME = 'EBAN' AND cdpos.FNAME = 'FRGZU' AND cdpos.VALUE_NEW = '[Final Release Indicator for PR]'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 3. Purchase Order Created
SELECT
EBELN AS PurchaseOrder,
'Purchase Order Created' AS Activity,
[Your ETL Tool Functions].DateTime(AEDAT, ERZET) AS EventTime,
ERNAM AS UserName,
LIFNR AS VendorNumber,
NULL AS OrderAmount, -- Amount is at item level
NULL AS MaterialGroup, -- Attribute is at item level
BUKRS AS CompanyCode,
BSART AS DocumentType
FROM EKKO
WHERE AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 4. Purchase Order Approval Requested / 5. Approved / 6. Rejected (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
CASE
WHEN cdpos.VALUE_NEW = '[Final Release Code]' THEN 'Purchase Order Approved'
WHEN cdpos.VALUE_NEW = '[Rejection Release Code]' THEN 'Purchase Order Rejected'
ELSE 'Purchase Order Approval Requested'
END AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKKO AS ekko ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKKO' AND cdpos.FNAME = 'FRGKE'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 7. Purchase Order Sent to Vendor
SELECT
ekko.EBELN AS PurchaseOrder,
'Purchase Order Sent to Vendor' AS Activity,
[Your ETL Tool Functions].DateTime(nast.ERDAT, nast.UHR) AS EventTime,
nast.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM NAST AS nast
INNER JOIN EKKO AS ekko ON nast.OBJKY = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE nast.KAPPL = 'EF' AND nast.VSTAT = '1' AND nast.KSCHL IN ([Your PO Output Types])
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 8. Purchase Order Changed (inferred from change documents, simplified example)
SELECT DISTINCT
ekko.EBELN AS PurchaseOrder,
'Purchase Order Changed' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKKO AS ekko ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.FNAME NOT IN ('FRGKE', 'FRGZU', 'LOEKZ', 'ELIKZ')
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 9. Goods Receipt Posted
SELECT
mseg.EBELN AS PurchaseOrder,
'Goods Receipt Posted' AS Activity,
[Your ETL Tool Functions].DateTime(mkpf.CPUDT, mkpf.CPUTM) AS EventTime,
mkpf.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM MSEG AS mseg
INNER JOIN MKPF AS mkpf ON mseg.MBLNR = mkpf.MBLNR AND mseg.MJAHR = mkpf.MJAHR
INNER JOIN EKPO AS ekpo ON mseg.EBELN = ekpo.EBELN AND mseg.EBELP = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE mseg.BWART = '101' AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 10. Services Confirmation Entered
SELECT
essr.EBELN AS PurchaseOrder,
'Services Confirmation Entered' AS Activity,
[Your ETL Tool Functions].DateTime(essr.ERDAT, essr.ERZET) AS EventTime,
essr.ERNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM ESSR AS essr
INNER JOIN EKKO AS ekko ON essr.EBELN = ekko.EBELN
INNER JOIN EKPO AS ekpo ON essr.EBELN = ekpo.EBELN AND essr.EBELP = ekpo.EBELP
WHERE ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 11. Quality Inspection Performed
SELECT
qals.EBELN AS PurchaseOrder,
'Quality Inspection Performed' AS Activity,
[Your ETL Tool Functions].DateTime(qals.PASTRTERM, '000000') AS EventTime, -- Time is often not available
qals.PRUEFER AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM QALS AS qals
INNER JOIN EKKO AS ekko ON qals.EBELN = ekko.EBELN
INNER JOIN EKPO AS ekpo ON qals.EBELN = ekpo.EBELN AND qals.EBELP = ekpo.EBELP
WHERE qals.VCODE <> '' -- A usage decision code exists
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 12. Goods Returned
SELECT
mseg.EBELN AS PurchaseOrder,
'Goods Returned' AS Activity,
[Your ETL Tool Functions].DateTime(mkpf.CPUDT, mkpf.CPUTM) AS EventTime,
mkpf.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM MSEG AS mseg
INNER JOIN MKPF AS mkpf ON mseg.MBLNR = mkpf.MBLNR AND mseg.MJAHR = mkpf.MJAHR
INNER JOIN EKPO AS ekpo ON mseg.EBELN = ekpo.EBELN AND mseg.EBELP = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE mseg.BWART = '122' AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 13. Purchase Order Completed (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Order Completed' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKPO AS ekpo ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekpo.EBELN AND SUBSTRING(cdhdr.OBJECTID, 11, 5) = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKPO' AND cdpos.FNAME = 'ELIKZ' AND cdpos.VALUE_NEW = 'X'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 14. Purchase Order Deleted (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Order Deleted' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKPO AS ekpo ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekpo.EBELN AND SUBSTRING(cdhdr.OBJECTID, 11, 5) = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKPO' AND cdpos.FNAME = 'LOEKZ' AND cdpos.VALUE_NEW = 'L'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]); 始める準備はできましたか?
このテンプレートを使って、SAP ECCの調達から支払いまでの発注書プロセスを改善するための手順を確認できます。データからインサイトを見つけ、今すぐ業務の効率化につなげましょう。
調達から支払いまでの発注書プロセスを改善:今すぐ無料トライアルを開始
ボトルネックを解消し、サイクルタイムを30%以上短縮しましょう。
クレジットカード不要。数分で利用を開始できます。