調達から支払いまで:発注書のデータテンプレート
調達から支払いまで:発注書のデータテンプレート
- 詳細な分析に推奨される属性
- プロセス内で追跡する主なアクティビティ
- データ抽出の手順
調達から支払いまで:発注書の属性
| 名前 | 説明 | ||
|---|---|---|---|
| アクティビティ ActivityName | 発注書プロセスで発生した業務イベントまたは工程の名前です。 | ||
| 説明 この属性は、発注書のライフサイクルにおける具体的な操作やステータス変更を示します。例として、「発注書を作成」「発注書を承認」「入庫を計上」などがあります。これらのアクティビティの順序がプロセスフローを構成します。 アクティビティの順序や発生頻度の分析は、プロセスマイニングの中核です。実際のプロセスを把握し、設計されたモデルと比較することで、ボトルネック(例:「請求書を受領」後の長い待ち時間)を特定し、手戻り(例:「発注書を変更」の繰り返し)を定量化できます。 重要な理由 プロセスの各工程を定義し、エンドツーエンドの流れの可視化と分析、バリアント分析、ボトルネックの特定を可能にします。 入手先 通常、主要な業務上の節目を表すために、EKKO/EKPOのステータス項目やCDHDR/CDPOSの変更文書ログなど、複数のテーブルや項目を組み合わせて取得します。 例 発注書を作成発注書を承認入庫を計上請求書を受領 | |||
| イベント時刻 EventTime | アクティビティが発生した日時を示すタイムスタンプです。 | ||
| 説明 この属性には、プロセス内の各アクティビティが発生した正確な日時が記録されます。プロセスマイニングにおける時間ベースの分析に欠かせません。 イベント時刻を使ってアクティビティを時系列に並べ、プロセスフローを作成します。また、アクティビティ間のサイクルタイム、待ち時間、処理時間など、期間に基づく指標を算出する際にも使います。これらの指標は、パフォーマンス分析やボトルネックの特定に重要です。 重要な理由 イベントを正しい順序に並べ、サイクルタイム、リードタイム、待ち時間などのパフォーマンス指標を算出するうえで重要なタイムスタンプです。 入手先 作成日(変更の場合はEKKO-AEDAT)や転記日(入庫の場合はMKPF-BUDAT)など、特定のアクティビティに関連するタイムスタンプ項目です。複数のテーブルのデータを組み合わせる必要がある場合もあります。 例 2023-04-15T10:00:00Z2023-04-15T14:30:00Z2023-05-01T09:15:00Z | |||
| 発注書 PurchaseOrderNumber | 調達のライフサイクルを追跡する際に、主なケースIDとして使われる発注書(PO)の一意の識別子です。 | ||
| 説明 発注書番号は、最初の作成から最終的な入庫と完了まで、関連するすべてのアクティビティを結び付ける中心的な識別子です。プロセスマイニング分析では、ケース識別子として使われます。 分析時にこの番号でイベントをグループ化すると、個々の発注書の進行状況を再構成できます。サイクルタイムの算出、プロセスバリアントの分析、個々の注文に固有のボトルネックや逸脱の特定に欠かせません。 重要な理由 調達に関するすべてのイベントをエンドツーエンドのプロセスとして結び付け、発注書ごとのライフサイクルを詳細に分析するための重要なキーです。 入手先 SAP S/4HANAのテーブルEKKOにある項目EBELNです。 例 450001712345000171244500017125 | |||
| ソースシステム SourceSystem | データの抽出元となるソースシステムを識別します。 | ||
| 説明 この属性は、イベントデータの発生元となるシステムを示します。例:「SAP S/4HANA Production」「SAP ECC」。 複数のシステムを使う環境では、データの来歴の追跡、問題の調査、異なるソースのデータの正確な解釈に欠かせない項目です。データのコンテキストを把握し、特定のシステム環境に絞って分析する際にも使えます。 重要な理由 データの発生元に関する重要なコンテキストを示します。複数のシステムを使う環境でのデータガバナンス、検証、分析に欠かせません。 入手先 通常、データの抽出、変換、ロード(ETL)の過程でデータセットの発生元を示すために追加される固定値です。 例 S4H_PROD_100ECC_EU_200S4H_US_300 | |||
| 最終データ更新 LastDataUpdate | ソースシステムからデータを最後に更新または抽出した日時を示すタイムスタンプです。 | ||
| 説明 この属性は、分析対象データの鮮度を示します。SAP S/4HANAからデータを最後に取得した日時を確認できます。 最終データ更新の日時を把握すると、分析結果がどの程度新しい情報に基づいているかを判断できます。リアルタイムの情報なのか、特定の時点のスナップショットなのかを確認できるため、分析結果に基づく対応の妥当性を評価しやすくなります。 重要な理由 データの更新時期を示し、分析結果のコンテキストと関連性を正しく理解できるようにします。 入手先 データの抽出、変換、ロード(ETL)の過程で追加されるメタデータのタイムスタンプです。 例 2024-05-21T02:00:00Z2024-05-20T02:00:00Z2024-05-19T02:00:00Z | |||
| ユーザー UserName | 特定のアクティビティを実行したユーザーの識別情報です。 | ||
| 説明 この属性には、文書の作成、変更、承認を行ったSAPユーザーIDが記録されます。システム内で行われた操作を追跡できます。 ユーザー別に分析すると、研修の必要性、業務負荷の分布、個人のパフォーマンスを把握できます。たとえば、特定のユーザーが承認に時間を要するケースや、承認後の変更が頻繁なケースに継続して関わっているかを確認できます。こうした情報は、リソース管理やプロセス改善の取り組みに役立ちます。 重要な理由 個人またはチーム単位で責任の所在を明確にし、パフォーマンスを分析できます。研修の機会やリソース不足の特定にも役立ちます。 入手先 EKKOの項目ERNAM(作成者)や、変更文書テーブルのユーザー項目(CDHDR-USERNAME)などに記録されています。 例 CB9980000012JSMITHRROE | |||
| 仕入先ID VendorId | 商品やサービスを提供する仕入先を識別する一意のIDです。 | ||
| 説明 仕入先IDは、発注書と特定の仕入先を結び付ける重要なマスターデータです。調達プロセス全体で、連絡、納品、支払いに使われます。 プロセスマイニングでは、この属性を使って仕入先ごとのパフォーマンスを分析できます。「仕入先リードタイムのパフォーマンス」や「仕入先別返品率」などのダッシュボードに欠かせません。信頼性の高い仕入先や、遅延や品質上の問題につながる可能性のある仕入先を特定できます。 重要な理由 仕入先ごとの分析を可能にし、パフォーマンスの評価や実績の高低の把握、サプライチェーンの最適化に役立ちます。 入手先 SAP S/4HANAのテーブルEKKOにある項目LIFNRです。 例 100023100045100088 | |||
| 希望納品日 RequestedDeliveryDate | 商品やサービスを納品するよう、組織が仕入先に指定した日付です。 | ||
| 説明 この属性は、発注書で合意した納品予定日を示します。仕入先の納品パフォーマンスを測定する際のベースラインとなります。 プロセスマイニングでは、この日付と実際の入庫日(「入庫を計上」のタイムスタンプ)を比較し、「仕入先の納期遵守率」を算出します。この日付からのずれを分析すると、仕入先の信頼性を評価し、サプライチェーンのリスクを管理できます。 重要な理由 仕入先の納期遵守パフォーマンスを測定するベースラインとなります。サプライチェーン管理や業務計画に欠かせない重要業績評価指標(KPI)です。 入手先 納期日程行テーブルEKETにある項目EINDTです。 例 2023-06-012023-06-152023-07-01 | |||
| 正味合計金額 TotalNetAmount | 税金と運賃を除いた発注書の合計金額です。 | ||
| 説明 この属性は、発注書の正味金額を示します。調達取引の規模を把握するための重要な財務指標です。 発注書を金額別(高額・低額)に分類し、プロセスの進み方に違いがあるかを確認するなど、財務分析に役立ちます。また、金額が大きく財務リスクや事業への影響が大きい発注書を優先して分析する際にも使えます。 重要な理由 金額に基づく分析を可能にし、発注書を金額別に分類できます。支出額の大きい領域を優先してプロセス改善に取り組む際にも役立ちます。 入手先 SAP S/4HANAのテーブルEKKOにある項目NETWRです。 例 1500.0025000.50125.75 | |||
| 発注書の文書タイプ DocumentType | 標準発注書、サービス発注書、在庫転送注文など、発注書の種類を区別する分類です。 | ||
| 説明 文書タイプは、発注書のプロセスフロー、番号範囲、項目を制御するSAPの重要な設定要素です。さまざまな状況に合わせて調達プロセスを調整できます。 文書タイプ別の分析は、プロセスの違いを理解するうえで重要です。たとえば、通常の商品発注書とサービス発注書、在庫転送注文では、プロセスが大きく異なる場合があります。この属性を使って異なるプロセスフローを絞り込み、比較することで、具体的な改善点を見つけられます。 重要な理由 発注書を分類し、異なる調達プロセスを比較できます。プロセスフローやサイクルタイムの違いを把握する際にも役立ちます。 入手先 SAP S/4HANAのテーブルEKKOにある項目BSARTです。 例 NBFOUB | |||
| 購買依頼 PurchaseRequisitionNumber | 発注書の起点となった購買依頼(PR)の識別子です。 | ||
| 説明 この属性は、発注書を元となる購買依頼に関連付けます。発注書を直接作成した場合、購買依頼がないこともあります。 この関連付けは、最初の依頼から始まる調達プロセス全体を分析するうえで欠かせません。「購買依頼の承認時間」などの重要業績評価指標(KPI)を算出できるほか、先行する承認済み購買依頼なしに発注書が作成される「承認経路を通さない購入」の特定にも役立ちます。 重要な理由 発注書と最初の依頼を結び付け、エンドツーエンドのプロセス分析や、コンプライアンスに反する承認経路を通さない購入の特定を可能にします。 入手先 SAP S/4HANAのテーブルEKPO(発注書明細レベル)にある項目BANFNです。 例 1001005110010052 | |||
| プラント Plant | 商品が納品される、またはサービスが提供される事業所や拠点です。 | ||
| 説明 SAPにおけるプラントは、商品を生産・保管する場所、またはサービスを提供する場所です。物流と計画における重要な要素です。 プラント別にプロセス分析を行うと、地域や拠点による調達プロセスの違いを把握できます。たとえば、特定のプラントで納品までの時間が長い、または商品の返品率が高い場合、地域固有の物流や品質管理の問題が考えられます。 重要な理由 拠点別に分析し、事業所、プラント、倉庫間のプロセスパフォーマンスの違いを把握できます。 入手先 この属性は、SAP S/4HANAのテーブルEKPOのフィールドWERKSにあります。 例 10101710DE01 | |||
| 仕入先の納期遵守 SupplierOnTimeDelivery | 入庫が希望納期当日またはそれ以前に計上されたかどうかを示す計算フラグです。 | ||
| 説明 この真偽値属性は、「Goods Receipt Posted」アクティビティのタイムスタンプと「Requested Delivery Date」を比較して算出されます。入庫が希望納期当日またはそれ以前であれば「true」になります。 この属性は、「仕入先納期遵守率」の重要業績評価指標(KPI)に直接利用されます。納期どおりの納品と遅延を簡単に絞り込めるため、仕入先のパフォーマンスを示すダッシュボードや評価表の作成に役立ちます。 重要な理由 仕入先の信頼性を直接測定し、納期遵守率のKPIの基礎となるほか、仕入先のパフォーマンス管理にも役立ちます。 入手先 「Goods Receipt Posted」アクティビティのタイムスタンプと「RequestedDeliveryDate」属性を比較して算出します。 例 truefalse | |||
| 会社コード CompanyCode | 発注書の作成対象となる法人または会社を識別するコードです。 | ||
| 説明 会社コードは、組織内の独立した会計単位を表します。発注書に関連するすべての財務取引は、特定の会社コードに計上されます。 会社コードは、法人ごとに調達プロセスを絞り込んで比較するための基本的な組織属性です。会社コード別に分析すると、組織内のプロセス実行のばらつき、効率の違い、コンプライアンス遵守率の差を把握できます。 重要な理由 法人ごとにプロセス分析を分け、事業部門間のパフォーマンスやコンプライアンスを比較できます。 入手先 この属性は、SAP S/4HANAのテーブルEKKOのフィールドBUKRSにあります。 例 101017102000 | |||
| 品目番号 MaterialNumber | 調達対象となる特定の品目または商品を識別する番号です。 | ||
| 説明 品目番号は、SAPの品目マスタレコードごとに割り当てられる一意のコードです。調達、在庫管理、販売など、その品目に関するすべての取引で使用されます。 品目番号または品目グループ別に分析すると、品目の種類ごとに調達状況を把握できます。特定の品目の調達プロセスで効率が低下していないか、リードタイムが長くなっていないか、返品が多くないかを確認し、カテゴリ管理に役立てられます。 重要な理由 品目ごとの分析により、特定の商品や資材に関するプロセス上の問題や仕入先のパフォーマンスの問題を特定できます。 入手先 この属性は、SAP S/4HANAのテーブルEKPOのフィールドMATNRにあります。 例 RM100-100FG210SERV-CONSULT | |||
| 手戻りがあるかどうか IsRework | 承認後の変更や商品の返品など、発注書に手戻りが発生したかどうかを示す計算フラグです。 | ||
| 説明 この真偽値属性は、発注書ごとのアクティビティの順序を分析して算出されます。「Purchase Order Approved」の後に「Purchase Order Changed」イベントが発生した場合、または「Goods Returned」イベントがある場合に「true」になります。 このフラグを使うと、「一括処理率」の重要業績評価指標(KPI)を簡単に算出できます。手作業での対応や修正が必要だった発注書を絞り込んで可視化し、手戻りのコストと発生頻度を把握できます。 重要な理由 手戻りが発生したケースを特定してプロセスの非効率性を数値化できます。一括処理率の算出や、逸脱の根本原因の特定にも役立ちます。 入手先 アクティビティの順序をもとに算出するフィールドです。承認後に「Purchase Order Changed」イベントが発生しているか、または「Goods Returned」イベントがあるかを判定します。 例 truefalse | |||
| 明細カテゴリ ItemCategory | 標準、委託、外注、サービスなど、発注書の明細を分類します。 | ||
| 説明 明細カテゴリは、特定の品目やサービスの調達方法と処理方法を決定します。入庫や請求書照合など、後続の工程にも影響します。 この属性は、購入対象に応じたプロセスバリアントの分析に役立ちます。たとえば、サービス入力シートが必要なサービス明細と、通常の在庫品目では、プロセスが大きく異なります。明細カテゴリ別に分析すると、こうした違いを把握し、対象を絞ったプロセス改善を行えます。 重要な理由 商品、サービス、外注など、調達の種類ごとにプロセスの違いを説明します。 入手先 この属性は、SAP S/4HANAのテーブルEKPOのフィールドPSTYPにあります。 例 093 | |||
| 規定外購買かどうか IsMaverickSpend | 事前に承認された購買依頼を経ずに発注書が作成されたかどうかを示す計算フラグです。 | ||
| 説明 この真偽値フラグは、データ処理時に算出されます。発注書に対応する購買依頼がない場合、または標準の承認ワークフローを経ずに発注書が作成された場合に「true」になります。 この属性は、「規定外購買の特定」ダッシュボードと関連する重要業績評価指標(KPI)に直接利用されます。規定に沿わない購買の規模を数値化し、調達方針や管理体制の徹底が必要な部門やユーザーグループを特定できます。 重要な理由 規定に沿わない購買を直接特定し、プロセス逸脱の規模を把握するとともに、財務管理と調達方針の徹底に役立ちます。 入手先 特定の文書タイプで「PurchaseRequisitionNumber」に値がないこと、またはイベントの順序をもとに算出するフィールドです。 例 truefalse | |||
| 購買グループ PurchasingGroup | 特定の調達活動を担当する購買担当者のグループです。 | ||
| 説明 購買グループは、特定の購買活動、資材、仕入先を担当する購買担当者またはそのグループです。仕入先との主な窓口となります。 この属性を使うと、購買組織単位の分析よりも細かく、業務量やパフォーマンスを分析できます。負荷が集中しているチームの特定や、購買グループごとの効率測定に加え、規定外購買などのプロセス逸脱が起きやすいグループの把握にも役立ちます。 重要な理由 購買グループごとのパフォーマンスを詳細に把握し、チーム単位で業務量、効率、プロセスの遵守状況を分析できます。 入手先 この属性は、SAP S/4HANAのテーブルEKKOのフィールドEKGRPにあります。 例 001002N00 | |||
| 購買組織 PurchasingOrganization | 資材やサービスの調達と、仕入先との交渉を担当する組織単位です。 | ||
| 説明 購買組織は、調達における主要な組織単位です。全社、会社、プラントの各レベルで編成でき、購買活動全般を担当します。 購買組織別にプロセスを分析すると、調達チームや地域ごとの効率とパフォーマンスを評価できます。組織単位間で、仕入先との交渉、プロセスの遵守状況、承認の遅れにどのような違いがあるかを把握できます。 重要な理由 調達部門や地域ごとのパフォーマンスを比較し、優れた取り組みや改善が必要な領域を特定できます。 入手先 この属性は、SAP S/4HANAのテーブルEKKOのフィールドEKORGにあります。 例 10101710US01 | |||
調達から支払いまで:発注書のアクティビティ
| アクティビティ | 説明 | ||
|---|---|---|---|
| 入庫を計上 | 仕入先から商品を実際に受領し、その内容をシステムに記録したことを示します。発注書の履歴を更新する明示的なトランザクションです。 | ||
| 重要な理由 仕入先のリードタイムが終了し、社内での請求書照合が始まる重要な節目です。納期遵守率を追跡するうえで欠かせません。 入手先 テーブルMKPF(ヘッダー)およびMSEG(明細)の入出庫伝票として記録され、特定の移動タイプ(例:101)を使って発注書履歴テーブルEKBEに関連付けられます。 記録 EKBEを介して関連付けられた入出庫伝票ヘッダー(MKPF)の転記日付(BUDAT)です。 イベントタイプ explicit | |||
| 発注書を作成 | 正式な発注書文書の作成を示します。購買依頼を参照して作成する場合と、参照せずに作成する場合があります。発注書文書をシステムに初めて保存した時点で、イベントが明示的に記録されます。 | ||
| 重要な理由 特に承認経路を通さない購入の分析では、このアクティビティをプロセスの開始点として扱えます。発注書の処理時間全体を追跡するうえで基本となるイベントです。 入手先 発注書ヘッダーテーブルEKKOに記録されます。作成日(AEDAT)と時刻は、文書の情報としてこのテーブルに保存されます。 記録 発注書文書の作成タイムスタンプ(AEDAT)は、EKKOテーブルに記録されます。 イベントタイプ explicit | |||
| 発注書を完了 | このアクティビティは、物流上、発注書の明細が完了したと見なされることを示します。「納品完了」と「最終請求書」のインジケーターが両方とも設定された時点で推定されます。 | ||
| 重要な理由 発注書のライフサイクル分析における終了点です。このイベントまでの時間を測定すると、調達業務のエンドツーエンドのサイクルタイムを把握できます。 入手先 発注書明細テーブルEKPOのステータスフラグから推定します。「納品完了」インジケーター(ELIKZ)と「最終請求書」インジケーター(EREKZ)が両方とも有効になると、イベントが発生します。 記録 EKPOの項目ELIKZとEREKZが両方とも完了に設定された時点を、変更ログから推定します。 イベントタイプ inferred | |||
| 発注書を承認 | 発注書に必要な社内承認がすべて完了し、仕入先への送付が承認されたことを示します。発注書のリリース戦略におけるステータス変更から推定します。 | ||
| 重要な理由 承認の効率や承認後の手戻りを測定するうえで重要な節目です。発注書の作成から承認までの時間を分析すると、社内プロセスの遅れが明らかになります。 入手先 EKKOテーブルのリリースインジケーター(FRGKE)から推定します。この項目が「リリース済み」ステータスに更新された日時を、変更履歴(CDHDR/CDPOS)から取得します。 記録 EKKOテーブルのリリースインジケーター(FRGKE)に関する変更ログから推定します。 イベントタイプ inferred | |||
| 請求書を受領 | 仕入先の請求書をSAPシステムに登録し、該当する発注書に関連付けたことを示します。会計伝票を作成する明示的な財務転記です。 | ||
| 重要な理由 調達プロセスと買掛金処理をつなぐ重要な節目です。入庫から請求書処理までにかかる時間を分析できます。 入手先 会計伝票はテーブルBKPF(ヘッダー)に作成され、明細はBSEGまたはユニバーサルジャーナルACDOCAに記録されます。テーブルRSEGで発注書に関連付けられます。 記録 会計伝票ヘッダーテーブルBKPFの文書入力日(CPUDT)です。 イベントタイプ explicit | |||
| 購買依頼を作成 | このアクティビティは、商品やサービスの正式な依頼を示し、調達プロセスの開始点となります。ユーザーが新しい購買依頼文書を保存した時点で、イベントが明示的に記録されます(例:トランザクションME51Nを使用)。 | ||
| 重要な理由 多くの発注書のライフサイクルでは、ここが主な開始点となります。このイベントから発注書の作成までにかかる時間を分析すると、調達先の選定や社内処理の遅れを特定できます。 入手先 テーブルEBAN(購買依頼)に記録されます。作成イベントのタイムスタンプは、EBANオブジェクトの変更履歴テーブルCDHDRおよびCDPOSで確認できます。 記録 EBANテーブルに文書が作成された時点でイベントが記録されます。 イベントタイプ explicit | |||
| 購買依頼を承認 | 管理者または指定された承認者が購買依頼を正式に承認したことを示します。通常は、購買依頼文書のステータス変更から推定され、発注書に変換できる状態になったことを表します。 | ||
| 重要な理由 承認サイクルタイムの追跡やボトルネックの特定に欠かせない節目です。ここでの遅れは、発注書を作成して仕入先に送付するまでの時間に直接影響します。 入手先 EBANテーブルのリリースステータス項目(例:FRGZU:リリースインジケーター)から推定します。最終リリースステータスが設定された日時は、その変更を記録した変更文書(CDHDR/CDPOS)から取得します。 記録 EBANテーブルのリリースステータス項目に関する変更ログ(CDHDR/CDPOS)から推定します。 イベントタイプ inferred | |||
| サービス確認を入力 | このアクティビティは、発注書に記載されたサービスが提供されたことの確認を示します。サービス入力シートの作成時に明示的に記録されます。 | ||
| 重要な理由 サービス調達では、入庫に相当する処理です。サービスの提供期間を追跡し、仕入先への支払いを適切な時期に行ううえで重要です。 入手先 サービス入力シートの作成時に記録され、データはテーブルESSR(ヘッダー)およびESLL(明細)に保存されます。作成日をタイムスタンプとして使用します。 記録 テーブルESSRにあるサービス入力シート文書の作成日です。 イベントタイプ explicit | |||
| 商品を返品 | 品質上の問題、破損、誤出荷などの理由で、受領済みの商品を仕入先に返品したことを示します。返品の入出庫処理として明示的に記録されます。 | ||
| 重要な理由 このアクティビティから、手戻りや仕入先の品質、注文内容の正確性に関する問題の可能性を把握できます。特定の仕入先や品目で返品が頻発する場合は、問題があることを示しています。 入手先 特定の返品移動タイプ(例:122)を使った入出庫伝票として記録されます。イベントはMKPF/MSEGに記録され、発注書履歴テーブルEKBEに関連付けられます。 記録 EKBEにある返品移動タイプの入出庫伝票の転記日付です。 イベントタイプ explicit | |||
| 発注書を仕入先に送付 | EDI、メール、印刷などを通じて発注書が仕入先に送られた時点を示します。このイベントは、多くの場合、システムの出力管理ログから取得します。 | ||
| 重要な理由 このアクティビティは、仕入先のリードタイムの起点となります。仕入先が注文を受け取った時点からパフォーマンスを正確に測定するうえで重要です。 入手先 購買文書に送信されたメッセージを記録する出力管理テーブルNASTから取得します。該当する出力タイプ(例:EDI、メール)の日時を使用できます。 記録 NASTテーブルに記録された、発注書に対する最初の送信成功メッセージのタイムスタンプです。 イベントタイプ inferred | |||
| 発注書を削除 | 発注書の明細または文書全体の取消、あるいは論理削除を示します。ユーザーが文書に削除フラグを設定した時点で記録されます。 | ||
| 重要な理由 このアクティビティは、プロセスの終了点の一つであり、失敗または取消を示します。発注書が削除された理由を分析すると、需要計画や要件定義の問題が明らかになる場合があります。 入手先 発注書ヘッダー(EKKO)または明細(EKPO)テーブルの削除インジケーター(LOEKZ)から取得します。タイムスタンプは変更文書(CDHDR/CDPOS)から取得します。 記録 削除フラグ(LOEKZ)が設定された時点の変更文書(CDHDR/CDPOS)のタイムスタンプです。 イベントタイプ explicit | |||
| 発注書を変更 | このアクティビティは、作成後に発注書の数量、価格、納期などが変更されたことを示します。システムの変更ログに明示的に記録されます。 | ||
| 重要な理由 特に承認後の変更を追跡することは、プロセスの非効率や手戻り、コンプライアンス上の問題の可能性を特定するうえで重要です。変更が頻繁に発生する場合、当初の仕様に問題がある可能性があります。 入手先 発注書オブジェクト(EINKBELEG)の変更文書テーブルCDHDR(ヘッダー)およびCDPOS(明細)に記録されます。変更ごとに詳細なログが作成されます。 記録 EKKOまたはEKPOテーブルの主要項目が変更された際にイベントが記録され、CDHDR/CDPOSに保存されます。 イベントタイプ explicit | |||
| 請求書の支払いを完了 | 支払処理または手動支払いによって、仕入先の請求書の決済が完了したことを示します。消込伝票を作成する明示的な財務取引です。 | ||
| 重要な理由 技術的には支払プロセスの一部ですが、このアクティビティを含めることで、調達から支払いまでのサイクル全体を把握できます。支払条件や支払パフォーマンスの分析に役立ちます。 入手先 支払いはBKPF/ACDOCAに消込伝票として記録されます。テーブルBSEGまたはACDOCAにある請求書明細の消込日(AUGDT)が、支払いイベントを示します。 記録 BSEGまたはACDOCAにある請求書文書の消込日(AUGDT)です。 イベントタイプ explicit | |||
データ抽出ガイド
ステップ
- 前提条件とアクセス権限:SAP S/4HANAシステムのCore Data Services(CDS)ビューを照会するための適切な権限を持つユーザーをご用意ください。SAP HANA Studio、Eclipse用ABAP Development Tools(ADT)、またはSAP HANAデータベースへのSQL接続に対応したサードパーティ製データ抽出ツールからアクセスできます。
- システム接続情報の確認:SAP S/4HANAシステムへの接続に必要なホスト、インスタンス番号、認証情報を確認します。
- データベースへの接続:使用するSQLクライアントから、CDSビューが格納されているSAP S/4HANAデータベースに接続します。
- SQLクエリの準備:この文書のクエリ欄に記載されたSQLクエリ全体をコピーし、SQLエディターに貼り付けます。このクエリでは、必要なアクティビティと属性をすべて抽出します。
- フィルター条件の設定:クエリ内のプレースホルダーを確認します。_start_dateと_end_dateを分析対象の日付範囲(例:'20230101'と'20231231')に置き換えます。poh.CompanyCodeのフィルターは、分析対象の会社コードに変更します。
- クエリの実行:変更したSQLクエリをS/4HANAデータベースに対して実行します。データ量や指定した日付範囲によっては、実行に時間がかかる場合があります。
- 結果の確認:クエリの実行後、SQLクライアントで出力結果を簡単に確認します。各種アクティビティが含まれていること、タイムスタンプが正しく設定されていること、ケースID(PurchaseOrderNumber)が一貫していることを確認します。
- データのエクスポート:SQLツールから結果全体をCSV(カンマ区切り値)ファイルにエクスポートします。文字化けを防ぐため、UTF-8エンコーディングを指定してください。
- アップロードの準備:ProcessMindにアップロードする前にCSVファイルを開き、列見出しがデータ要件で定義された属性(PurchaseOrderNumber、ActivityName、EventTimeなど)と完全に一致していることを確認します。エクスポートツールによって列名が変更されている場合は修正してください。
- ProcessMindへのアップロード:完成したCSVファイルをProcessMindのプロジェクトにアップロードします。インポート時に、ファイル内の列を対応するケースID、アクティビティ、タイムスタンプの各フィールドに割り当てます。
設定
- 使用する主なCDSビュー:抽出処理では、意味情報が豊富な標準CDSビューを使用します。主なビューは次のとおりです。
- I_PurchaseOrderItemAPI01:発注明細の基本データ
- I_PurchaseRequisitionItemAPI01:購買依頼の詳細
- I_MaterialDocumentItem:入庫や返品などの在庫移動
- I_ServiceEntrySheetAPI01:サービス確認イベント
- I_SupplierInvoiceAPI01:仕入先請求書情報
- I_OperationalAcctgDocItem:請求書と会計伝票を関連付け、支払いを追跡
- I_ChangeDocument:発注内容の変更
- 日付範囲によるフィルタリング:処理性能とデータ量を管理するため、日付範囲のフィルターを必ず設定してください。クエリでは、発注作成日(PurchaseOrderDate)に対して_start_dateと_end_dateのプレースホルダーを使用します。まずは3~6か月分のデータを対象にすることをおすすめします。
- 組織単位でのフィルタリング:抽出対象を関連する事業部門に絞るため、必ずCompanyCodeでフィルタリングしてください。さらに絞り込む場合は、メインのPO_base共通テーブル式にPurchaseOrderTypeまたはPurchasingOrganizationのフィルターを追加できます。
- 前提条件:クエリを実行するユーザーには、上記のすべてのCDSビューに対するSELECT権限が必要です。通常、S/4HANAの特定の業務ロールまたは分析ロールを通じて、これらのビューへのアクセス権が付与されます。適切な権限がない場合、クエリは失敗します。
クエリの例 sql
WITH PO_base AS (
SELECT
poh.PurchaseOrder AS PurchaseOrderNumber,
poi.PurchaseOrderItem AS PurchaseOrderItem,
poh.CompanyCode,
poh.PurchaseOrderType AS DocumentType,
poh.Supplier AS VendorId,
poh.PurchaseOrderDate,
poi.PurchaseRequisition AS PurchaseRequisitionNumber,
poi.NetPriceAmount * poi.OrderQuantity AS TotalNetAmount, -- Note: This is item-level net amount
poh.CreationDate AS POCreationDate,
poh.CreationTime AS POCreationTime,
poh.LastChangeDateTime AS POLastChangeDateTime,
poi.IsDeleted,
poi.DeliveryIsCompleted,
poi.FinalInvoiceIsExpected,
poi.GoodsReceiptIsExpected,
poi.LastGoodsReceiptDate,
poi.LastInvoiceReceiptDate
FROM I_PurchaseOrderAPI01 poh
JOIN I_PurchaseOrderItemAPI01 poi
ON poh.PurchaseOrder = poi.PurchaseOrder
WHERE
poh.PurchaseOrderDate BETWEEN '_start_date' AND '_end_date' -- Placeholder: e.g., '20230101' and '20230630'
AND poh.CompanyCode IN ('[YourCompanyCode]') -- Placeholder: e.g., '1010'
)
-- 1. Purchase Requisition Created
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Created' AS ActivityName,
CAST(CONCAT(pr.CreationDate, 'T', pr.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem, -- Placeholder
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
pr.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate, -- Available in PR, add if needed
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
UNION ALL
-- 2. Purchase Requisition Approved
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Approved' AS ActivityName,
CAST(CONCAT(pr.PurReqnReleaseDate, 'T', '000000') AS TIMESTAMP) AS EventTime, -- Time is not available in this view
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
WHERE
pr.PurReqnReleaseDate IS NOT NULL
UNION ALL
-- 3. Purchase Order Created
SELECT
po.PurchaseOrderNumber,
'Purchase Order Created' AS ActivityName,
CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
poh.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
UNION ALL
-- 4. Purchase Order Approved
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Approved' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Assuming ReleaseDate reflects final approval
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 5. Purchase Order Sent to Vendor
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Sent to Vendor' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Using ReleaseDate as a proxy for sending time
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 6. Purchase Order Changed
SELECT DISTINCT
ch.OBJECTID AS PurchaseOrderNumber,
'Purchase Order Changed' AS ActivityName,
CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
ch.UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ChangeDocument ch
JOIN PO_base po ON ch.OBJECTID = po.PurchaseOrderNumber
WHERE
ch.ObjectClassName = 'EINKBELEG' -- Object Class for Purchase Documents
AND CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) > CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP)
UNION ALL
-- 7. Goods Receipt Posted
SELECT
po.PurchaseOrderNumber,
'Goods Receipt Posted' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '101'
UNION ALL
-- 8. Services Confirmation Entered
SELECT
po.PurchaseOrderNumber,
'Services Confirmation Entered' AS ActivityName,
CAST(se.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
se.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ServiceEntrySheetAPI01 se
JOIN PO_base po
ON se.PurchaseOrder = po.PurchaseOrderNumber AND se.PurchaseOrderItem = po.PurchaseOrderItem
UNION ALL
-- 9. Goods Returned
SELECT
po.PurchaseOrderNumber,
'Goods Returned' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '122'
UNION ALL
-- 10. Invoice Received
SELECT
po.PurchaseOrderNumber,
'Invoice Received' AS ActivityName,
CAST(inv.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
inv.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
inv.DebitCreditCode = 'H' -- 'H' for Credit (Supplier Invoice)
UNION ALL
-- 11. Invoice Paid
SELECT
po.PurchaseOrderNumber,
'Invoice Paid' AS ActivityName,
CAST(doc.ClearingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
doc.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN I_OperationalAcctgDocItem doc
ON inv.AccountingDocument = doc.AccountingDocument
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
doc.IsCleared = 'X' AND doc.ClearingDate IS NOT NULL
UNION ALL
-- 12. Purchase Order Completed
SELECT
po.PurchaseOrderNumber,
'Purchase Order Completed' AS ActivityName,
CAST(GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
'SYSTEM' AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.DeliveryIsCompleted = 'X'
AND (po.FinalInvoiceIsExpected = 'X' OR po.GoodsReceiptIsExpected = '') -- Logic for completion
AND GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) IS NOT NULL
UNION ALL
-- 13. Purchase Order Deleted
SELECT
po.PurchaseOrderNumber,
'Purchase Order Deleted' AS ActivityName,
CAST(po.POLastChangeDateTime AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- User who set the flag is in change docs
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.IsDeleted = 'X' ステップ
- EKKOとEKPOを含むSAP HANAスキーマへのSQL直接アクセスが可能であることを確認し、必要な読み取り権限を取得します。スキーマと接続情報のプレースホルダーは、システムに設定されている値に置き換えてください。
- [Start timestamp]と[End timestamp]を使って抽出期間を指定します。初回の読み込みでは、3~6か月分を対象にすることをおすすめします。レポートの対象範囲で必要な場合に限り、会社コードと伝票タイプのフィルターを設定してください。
- EKKOとEKPOから発注を特定し、発注番号、仕入先、伝票タイプ、会社コード、作成日、作成時刻、明細レベルの属性を保持します。EKPOの正味金額を集計し、発注単位のTotalNetAmountを算出します。
- EBANから購買依頼の作成イベントと承認イベントを抽出します。EKPOにある購買依頼番号と明細参照を使って、購買依頼を発注に関連付けます。購買依頼の承認インジケーターとタイムスタンプはリリース設定によって異なるため、[Configure based on your system]に従い、使用中のSAPリリース戦略に合わせて承認ステータスとタイムスタンプの式を設定してください。
- 発注の作成、承認、変更、削除、完了の各イベントを抽出します。作成にはEKKOの作成日と作成時刻を使用します。承認、変更、削除にはリリース履歴または変更履歴のデータソースが必要です。選択したスキーマで該当する履歴を参照できない場合は、[Your table name]と[Your column name]を使って対応するデータソースの式を設定してください。
- 該当する出力、在庫伝票、サービスエントリー、請求書、会計、消込の各データソースから、仕入先への連絡、入庫、サービス確認、返品、請求書受領、請求書支払いのイベントを抽出します。これらのデータソースはEKKOとEKPOだけでは表現できないため、クエリにはシステム固有のオブジェクトを指定するプレースホルダーが含まれています。
- すべてのデータソースのイベントを、同じイベントログ構造に統一します。各行にはPurchaseOrderNumber、ActivityName、EventTime、SourceSystem、LastDataUpdate、VendorId、UserName、TotalNetAmount、PurchaseRequisitionNumber、RequestedDeliveryDate、DocumentTypeを含めます。データソースに有効なイベントが複数ある場合は、同じアクティビティの複数回の発生を保持してください。
- タイムスタンプを検証し、完全に一致する重複行のみを削除します。データソースに記録のないアクティビティを推測で追加しないでください。ProcessMindはイベントログをそのまま読み込むため、プロセスの可視化に表示する各アクティビティを明示的な行として含める必要があります。
- 結果を、見出し行が1行あり、列名が一貫した区切りファイルまたはデータベースの結果セットとしてエクスポートします。ProcessMindのアップロード設定でサポートされるタイムスタンプ形式を使用し、PurchaseOrderNumberはテキストとして保持してください。設定済みのProcessMindデータ接続を通じて、イベントログ全体をアップロードします。
設定
- データソースオブジェクト:EKKOとEKPOは、発注ヘッダーと明細のデータソースとして確認済みです。購買依頼、リリース状況、変更履歴、出力、在庫移動、サービスエントリーシート、請求書、支払い、消込に関する追加オブジェクトは、SAP S/4HANAのリリースと使用中のデータモデルに応じて設定してください。
- ケース識別子:ケース識別子にはPurchaseOrderNumberを使用します。明細レベルのイベントは発注番号に関連付け、必要に応じて明細参照をデータソース固有の追加列に保持してください。
- 日付範囲:まずは3~6か月分を対象にします。過去データを読み込む場合は、期間を小さく区切って処理し、境界が重なる部分を照合してデータの欠落を防いでください。
- フィルター:必要な対象範囲に応じて、会社コード、伝票タイプ、VendorId、購買組織、購買グループ、イベント日付のフィルターを設定します。会社コードと伝票タイプには、対象システムで有効な値を指定してください。
- イベントの意味付け:該当する伝票フィールドまたはログを参照できる場合、作成と削除は明示的なイベントとして記録できます。承認と完了はステータスに基づくイベントであり、ステータスのタイムスタンプを設定する必要があります。根拠となるイベント時刻がない場合、現在のステータスだけをもとに行を作成しないでください。
- 処理性能:イベント日付と組織範囲で早い段階から絞り込み、可能な場合はイベントデータソースとの結合前にEKPOを集計し、過去データの大量読み込みは期間を区切って実行します。適切なデータベース統計情報を確保し、明細、会計、変更履歴のデータソースを無条件に結合しないでください。
- 更新日時:実行ごとに、すべての行のLastDataUpdateに抽出実行時刻を設定します。
- 前提条件:SAP HANAへの接続、設定したすべてのデータソースオブジェクトへの読み取り権限、購買、在庫管理、サービス調達、請求書照合、買掛金データへのアクセス、選択したファイルまたは結果セットをインポートできるProcessMind接続が必要です。
- システム固有の設定:クエリ内の角括弧付きプレースホルダーはすべて、対象のSAP S/4HANAシステムで承認されたテーブル、ビュー、列、または式に置き換えてください。認証情報をクエリや抽出設定に含めないでください。
クエリの例 sql
WITH
params AS (
SELECT
CAST('[Start timestamp]' AS TIMESTAMP) AS start_ts,
CAST('[End timestamp]' AS TIMESTAMP) AS end_ts,
CAST(CURRENT_TIMESTAMP AS TIMESTAMP) AS last_data_update,
CAST('[Source system]' AS NVARCHAR(100)) AS source_system
FROM DUMMY
),
po_base AS (
SELECT
h.MANDT,
h.EBELN AS PurchaseOrderNumber,
h.LIFNR AS VendorId,
h.BSART AS DocumentType,
h.BUKRS AS CompanyCode,
CAST(h.AEDAT AS DATE) AS POChangedDate,
CAST(h.AEDAT AS TIMESTAMP) AS POChangedTimestamp,
CAST(h.ERNAM AS NVARCHAR(100)) AS POCreatedBy,
CAST(h.BEDAT AS DATE) AS PODate,
CAST(h.EBELN AS NVARCHAR(20)) AS PurchaseOrderKey,
CAST(SUM(COALESCE(i.NETWR, 0)) AS DECIMAL(23, 2)) AS TotalNetAmount,
CAST(MIN(i.BEDNR) AS NVARCHAR(20)) AS PurchaseRequisitionNumber,
CAST(MIN(i.EINDT) AS DATE) AS RequestedDeliveryDate
FROM EKKO h
INNER JOIN EKPO i
ON i.MANDT = h.MANDT
AND i.EBELN = h.EBELN
WHERE h.AEDAT >= (SELECT start_ts FROM params)
AND h.AEDAT < (SELECT end_ts FROM params)
AND h.BUKRS IN ([Company Code filter])
AND h.BSART IN ([Document Type filter])
GROUP BY
h.MANDT,
h.EBELN,
h.LIFNR,
h.BSART,
h.BUKRS,
h.AEDAT,
h.ERNAM,
h.BEDAT
),
po_items AS (
SELECT
i.MANDT,
i.EBELN AS PurchaseOrderNumber,
i.EBELP,
i.BANFN AS PurchaseRequisitionNumber,
i.BEDNR,
i.EINDT AS RequestedDeliveryDate
FROM EKPO i
),
events AS (
SELECT
p.PurchaseOrderNumber,
'Purchase Requisition Created' AS ActivityName,
CAST(r.[Purchase requisition creation timestamp] AS TIMESTAMP) AS EventTime,
s.source_system AS SourceSystem,
s.last_data_update AS LastDataUpdate,
p.VendorId,
CAST(r.[Purchase requisition created by] AS NVARCHAR(100)) AS UserName,
p.TotalNetAmount,
CAST(r.[Purchase requisition number] AS NVARCHAR(20)) AS PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your requisition source table or view] r
ON r.[Client] = p.MANDT
AND r.[Purchase requisition number] = p.PurchaseRequisitionNumber
CROSS JOIN params s
WHERE r.[Purchase requisition creation timestamp] >= s.start_ts
AND r.[Purchase requisition creation timestamp] < s.end_ts
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Purchase Requisition Approved' AS ActivityName,
CAST(r.[Purchase requisition approval timestamp] AS TIMESTAMP) AS EventTime,
s.source_system,
s.last_data_update,
p.VendorId,
CAST(r.[Purchase requisition approver] AS NVARCHAR(100)),
p.TotalNetAmount,
CAST(r.[Purchase requisition number] AS NVARCHAR(20)),
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your requisition approval history table or view] r
ON r.[Client] = p.MANDT
AND r.[Purchase requisition number] = p.PurchaseRequisitionNumber
CROSS JOIN params s
WHERE r.[Purchase requisition approval timestamp] >= s.start_ts
AND r.[Purchase requisition approval timestamp] < s.end_ts
AND r.[Approval status] = '[Approved status value]'
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Purchase Order Created',
CAST(p.PODate AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
p.POCreatedBy,
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
CROSS JOIN params s
WHERE p.PODate >= CAST(s.start_ts AS DATE)
AND p.PODate < CAST(s.end_ts AS DATE)
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Purchase Order Approved',
CAST(a.[Purchase order approval timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(a.[Approver] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your purchase order release history table or view] a
ON a.[Client] = p.MANDT
AND a.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE a.[Purchase order approval timestamp] >= s.start_ts
AND a.[Purchase order approval timestamp] < s.end_ts
AND a.[Release status] = '[Approved release status value]'
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Purchase Order Sent to Vendor',
CAST(o.[Output timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(o.[Output user] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your purchase order output source table or view] o
ON o.[Client] = p.MANDT
AND o.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE o.[Output timestamp] >= s.start_ts
AND o.[Output timestamp] < s.end_ts
AND o.[Output status] = '[Successfully processed output status]'
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Purchase Order Changed',
CAST(c.[Change timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(c.[Changed by] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your purchase order change history table or view] c
ON c.[Client] = p.MANDT
AND c.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE c.[Change timestamp] >= s.start_ts
AND c.[Change timestamp] < s.end_ts
AND c.[Change indicator] = '[Changed indicator value]'
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Goods Receipt Posted',
CAST(g.[Goods movement timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(g.[Posted by] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your goods movement source table or view] g
ON g.[Client] = p.MANDT
AND g.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE g.[Goods movement timestamp] >= s.start_ts
AND g.[Goods movement timestamp] < s.end_ts
AND g.[Movement type] IN ([Goods receipt movement types])
AND g.[Reversal indicator] IS NULL
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Services Confirmation Entered',
CAST(v.[Service entry timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(v.[Entered by] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your service entry sheet source table or view] v
ON v.[Client] = p.MANDT
AND v.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE v.[Service entry timestamp] >= s.start_ts
AND v.[Service entry timestamp] < s.end_ts
AND v.[Service entry status] = '[Accepted service entry status]'
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Goods Returned',
CAST(g.[Goods movement timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(g.[Posted by] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your goods movement source table or view] g
ON g.[Client] = p.MANDT
AND g.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE g.[Goods movement timestamp] >= s.start_ts
AND g.[Goods movement timestamp] < s.end_ts
AND g.[Movement type] IN ([Goods return movement types])
AND g.[Reversal indicator] IS NULL
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Invoice Received',
CAST(i.[Invoice posting timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(i.[Posted by] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your supplier invoice source table or view] i
ON i.[Client] = p.MANDT
AND i.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE i.[Invoice posting timestamp] >= s.start_ts
AND i.[Invoice posting timestamp] < s.end_ts
AND i.[Invoice status] = '[Posted invoice status]'
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Invoice Paid',
CAST(i.[Clearing timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(i.[Cleared by] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your supplier invoice clearing source table or view] i
ON i.[Client] = p.MANDT
AND i.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE i.[Clearing timestamp] >= s.start_ts
AND i.[Clearing timestamp] < s.end_ts
AND i.[Clearing status] = '[Cleared status value]'
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Purchase Order Completed',
CAST(x.[Completion timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(x.[Completion user] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your purchase order item status source table or view] x
ON x.[Client] = p.MANDT
AND x.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE x.[Completion timestamp] >= s.start_ts
AND x.[Completion timestamp] < s.end_ts
AND x.[Delivery completed indicator] = '[Set indicator value]'
AND x.[Final invoice indicator] = '[Set indicator value]'
UNION ALL
SELECT
p.PurchaseOrderNumber,
'Purchase Order Deleted',
CAST(d.[Deletion timestamp] AS TIMESTAMP),
s.source_system,
s.last_data_update,
p.VendorId,
CAST(d.[Deleted by] AS NVARCHAR(100)),
p.TotalNetAmount,
p.PurchaseRequisitionNumber,
p.RequestedDeliveryDate,
p.DocumentType
FROM po_base p
INNER JOIN [Your purchase order deletion history table or view] d
ON d.[Client] = p.MANDT
AND d.[Purchase order number] = p.PurchaseOrderNumber
CROSS JOIN params s
WHERE d.[Deletion timestamp] >= s.start_ts
AND d.[Deletion timestamp] < s.end_ts
AND d.[Deletion indicator] = '[Set deletion indicator value]'
)
SELECT
PurchaseOrderNumber,
ActivityName,
EventTime,
SourceSystem,
LastDataUpdate,
VendorId,
UserName,
TotalNetAmount,
PurchaseRequisitionNumber,
RequestedDeliveryDate,
DocumentType
FROM events
WHERE PurchaseOrderNumber IS NOT NULL
AND ActivityName IS NOT NULL
AND EventTime IS NOT NULL
ORDER BY PurchaseOrderNumber, EventTime, ActivityName; ステップ
- 仕様と設計:イベントログファイルの最終的なデータ構造を定義し、必須属性と推奨属性をすべて含めます。13種類の必須アクティビティそれぞれのデータソースとして使用するSAPテーブル(例:EKKO、EKPO、EKBE、CDHDR、CDPOS、BKPF)を文書化します。
- プログラムの作成:SAP GUIでトランザクションコードSE38またはSE80を使い、ABAPエディターを開きます。たとえばZ_PM_PO_EXTRACTという新しい実行可能プログラムを作成します。
- 選択画面の定義:レポートの選択画面をコーディングします。これにより、抽出するデータをユーザーが絞り込めます。発注作成日の範囲(P_AEDAT)、会社コード(P_BUKRS)、購買伝票タイプ(P_BSART)のパラメーターを含めてください。
- データ宣言:プログラムに必要な内部テーブルとデータ構造を定義します。仕様の手順で定義した構造に合わせて、最終的なイベントログ用の内部テーブルを用意します。
- データ選択ロジックの実装:13種類のアクティビティそれぞれのデータを選択するABAPの主要ロジックを記述します。必要に応じて関連するSAPテーブルを結合し、一連のSELECT文を実行します。変更に基づくイベントでは、変更ログテーブルCDHDRとCDPOSを読み込みます。
- データの変換とマッピング:取得した各レコードについて、SAPテーブルのフィールドを最終的なイベントログの内部テーブルに対応する列へ割り当てます。処理中のイベントに応じてActivityNameを設定します(例:'Purchase Order Created')。日付と時刻のフィールドを、EventTime用の一貫したタイムスタンプ形式に変換します。
- イベントデータの統合:13種類すべてのアクティビティを処理した後、データが単一の統合された内部テーブルに集約されていることを確認します。このテーブルが、選択した発注のイベントログ全体になります。
- ファイル出力の実装:最終的な内部テーブルをファイルに書き出す機能を追加します。ユーザーがローカルマシンにCSVとして保存できるよう、cl_gui_frontend_services=>gui_downloadメソッドの使用をおすすめします。バックグラウンド処理の場合は、OPEN DATASETを使ってSAPアプリケーションサーバーに保存できます。
- トランザクションコードの作成(任意):業務ユーザーがプログラムに簡単にアクセスできるよう、トランザクションコードSE93を使い、ABAPプログラムを実行するカスタムトランザクションコード(例:ZPM_PO_EXTRACT)を作成します。
- バックグラウンドジョブのスケジュール:データ量が多い場合や抽出を自動化する場合は、トランザクションコードSM36を使ってプログラムをバックグラウンドジョブとしてスケジュールします。出力ファイルは、プログラムロジックで指定したアプリケーションサーバー上のパスに書き込まれます。
設定
- 選択条件:データを適切に絞り込めるよう、プログラムに選択パラメーターを含めます。主なフィルターは次のとおりです。
- 日付範囲:発注作成日(EKKO-AEDAT)の範囲を必須で指定します。データ量とレポートの処理性能を考慮し、まずは3~6か月分を対象にすることをおすすめします。
- 会社コード(BUKRS):複数の法人を持つ組織では、抽出対象を絞り込むために必要です。
- 購買伝票タイプ(BSART):標準発注、包括発注、在庫転送発注など、特定の発注タイプに絞って分析できます。
- 変更ログの読み込み:「Purchase Order Approved」や「Purchase Order Changed」などのアクティビティを抽出するには、SAPの変更ログテーブル(CDHDR、CDPOS)を読み込む必要があります。この処理はシステムリソースを多く消費する場合があります。ABAPロジックでは、必要なオブジェクトクラス(EINKBELEG、BANF)とテーブル/フィールドの組み合わせだけを選択するよう最適化してください。
- 権限:このレポートを実行するユーザーまたは技術アカウントには、資材管理(MM)、財務会計(FI)、システム共通テーブルなど、複数のSAPモジュールにまたがるテーブルの広範な読み取り権限が必要です。対象テーブルにはEKKO、EKPO、EBAN、EKBE、BKPF、BSAK、RBKP、NAST、CDHDR、CDPOSなどがあります。
- バックグラウンド実行:数か月を超えるデータを抽出する場合や、トランザクション量の多いシステムで実行する場合は、ダイアログ処理のタイムアウトを防ぐため、必ずバックグラウンドで実行してください。
クエリの例 abap
REPORT z_pm_po_extract.
" ====================================================================
" SELECTION SCREEN
" ====================================================================
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS: s_aedat FOR sy-datum OBLIGATORY.
SELECT-OPTIONS: s_bukrs FOR ekko-bukrs.
SELECT-OPTIONS: s_bsart FOR ekko-bsart.
PARAMETERS: p_sysid TYPE string DEFAULT '[Your SAP System ID]'.
SELECTION-SCREEN END OF BLOCK b1.
" ====================================================================
" DATA DECLARATIONS
" ====================================================================
TYPES: BEGIN OF ty_event_log,
purchaseordernumber TYPE ebeln,
activityname TYPE string,
eventtime TYPE timestamp,
sourcesystem TYPE string,
lastdataupdate TYPE timestamp,
vendorid TYPE lifnr,
username TYPE ernam,
totalnetamount TYPE netwr,
purchaserequisitionnumber TYPE banfn,
requesteddeliverydate TYPE eedat,
documenttype TYPE bsart,
END OF ty_event_log.
DATA: lt_event_log TYPE TABLE OF ty_event_log,
ls_event_log TYPE ty_event_log.
DATA: lt_ekko TYPE TABLE OF ekko,
lt_ekpo TYPE TABLE OF ekpo.
" ====================================================================
" START OF SELECTION
" ====================================================================
START-OF-SELECTION.
" Get current timestamp for LastDataUpdate
GET TIME STAMP FIELD ls_event_log-lastdataupdate.
ls_event_log-sourcesystem = p_sysid.
" --- Initial Data Selection: Purchase Orders in Scope ---
SELECT * FROM ekko INTO TABLE lt_ekko
WHERE aedat IN s_aedat
AND bukrs IN s_bukrs
AND bsart IN s_bsart.
IF lt_ekko IS INITIAL.
MESSAGE 'No Purchase Orders found for the given criteria.' TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
SELECT * FROM ekpo INTO TABLE lt_ekpo
FOR ALL ENTRIES IN lt_ekko
WHERE ebeln = lt_ekko-ebeln.
" --- 1. Purchase Requisition Created ---
SELECT ban.banfn, ban.erdat, ban.erzet, ban.ernam,
ekpo.ebeln, ekpo.netwr, ekpo.eindt, ekpo.bsart, ekpo.lifnr, ekko.bukrs
FROM eban AS ban
INNER JOIN ekpo AS ekpo ON ban.banfn = ekpo.banfn AND ban.bnfpo = ekpo.bnfpo
INNER JOIN ekko AS ekko ON ekpo.ebeln = ekko.ebeln
WHERE ekko.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_pr_created).
LOOP AT lt_pr_created INTO DATA(ls_pr_created).
ls_event_log-purchaseordernumber = ls_pr_created-ebeln.
ls_event_log-activityname = 'Purchase Requisition Created'.
CONVERT DATE ls_pr_created-erdat TIME ls_pr_created-erzet INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-vendorid = ls_pr_created-lifnr.
ls_event_log-username = ls_pr_created-ernam.
ls_event_log-totalnetamount = ls_pr_created-netwr.
ls_event_log-purchaserequisitionnumber = ls_pr_created-banfn.
ls_event_log-requesteddeliverydate = ls_pr_created-eindt.
ls_event_log-documenttype = ls_pr_created-bsart.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 2. Purchase Requisition Approved (via Change Docs on Release Indicator) ---
SELECT h.objectid, h.udate, h.utime, h.username
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.objectclas = p.objectclas AND h.objectid = p.objectid AND h.changenr = p.changenr
INNER JOIN ekpo AS ekpo ON h.objectid = ekpo.banfn
INNER JOIN ekko AS ekko ON ekpo.ebeln = ekko.ebeln
WHERE h.objectclas = 'BANF'
AND p.tabname = 'EBAN'
AND p.fname = 'FRGZU'
AND p.value_new = 'X' "Configure based on your system release indicator for 'Approved'
AND ekko.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_pr_approved).
LOOP AT lt_pr_approved INTO DATA(ls_pr_approved).
SELECT SINGLE ebeln FROM ekpo INTO ls_event_log-purchaseordernumber WHERE banfn = ls_pr_approved-objectid.
ls_event_log-activityname = 'Purchase Requisition Approved'.
CONVERT DATE ls_pr_approved-udate TIME ls_pr_approved-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_pr_approved-username.
" Other attributes can be populated with another SELECT if needed.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 3. Purchase Order Created ---
LOOP AT lt_ekko INTO DATA(ls_ekko_created).
ls_event_log-purchaseordernumber = ls_ekko_created-ebeln.
ls_event_log-activityname = 'Purchase Order Created'.
CONVERT DATE ls_ekko_created-aedat TIME ls_ekko_created-erzet INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-vendorid = ls_ekko_created-lifnr.
ls_event_log-username = ls_ekko_created-ernam.
ls_event_log-totalnetamount = ls_ekko_created-rlwrt.
ls_event_log-purchaserequisitionnumber = ''. "Can be enriched later if needed
ls_event_log-requesteddeliverydate = ''. "Can be enriched from EKPO
ls_event_log-documenttype = ls_ekko_created-bsart.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 4. Purchase Order Approved (via Change Docs on Release Indicator) ---
SELECT h.objectid, h.udate, h.utime, h.username
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.objectclas = p.objectclas AND h.objectid = p.objectid AND h.changenr = p.changenr
WHERE h.objectclas = 'EINKBELEG'
AND p.tabname = 'EKKO'
AND p.fname = 'FRGKE'
AND p.value_new = 'R' "R for Released
AND h.objectid IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_approved).
LOOP AT lt_po_approved INTO DATA(ls_po_approved).
ls_event_log-purchaseordernumber = ls_po_approved-objectid.
ls_event_log-activityname = 'Purchase Order Approved'.
CONVERT DATE ls_po_approved-udate TIME ls_po_approved-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_approved-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 5. Purchase Order Sent to Vendor ---
SELECT n.objky, n.vstat, n.datvr, n.uhrvr, e.ernam
FROM nast AS n
INNER JOIN ekko AS e ON n.objky = e.ebeln
WHERE n.kappl = 'EF' "Application for Purchasing
AND n.kschl = '[Your PO Output Type]' "e.g. NEU
AND n.vstat = '1' "Successfully processed
AND n.objky IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_sent).
LOOP AT lt_po_sent INTO DATA(ls_po_sent).
ls_event_log-purchaseordernumber = ls_po_sent-objky.
ls_event_log-activityname = 'Purchase Order Sent to Vendor'.
CONVERT DATE ls_po_sent-datvr TIME ls_po_sent-uhrvr INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_sent-ernam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 6. Purchase Order Changed ---
SELECT objectid, udate, utime, username FROM cdhdr
WHERE objectclas = 'EINKBELEG'
AND tcode IN ('ME22', 'ME22N')
AND objectid IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_changed).
LOOP AT lt_po_changed INTO DATA(ls_po_changed).
ls_event_log-purchaseordernumber = ls_po_changed-objectid.
ls_event_log-activityname = 'Purchase Order Changed'.
CONVERT DATE ls_po_changed-udate TIME ls_po_changed-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_changed-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 7. Goods Receipt Posted & 9. Goods Returned ---
SELECT e.ebeln, m.budat, m.cpudt, m.cputm, m.usnam, b.shkzg, b.bwart
FROM mkpf AS m
INNER JOIN mseg AS s ON m.mblnr = s.mblnr AND m.mjahr = s.mjahr
INNER JOIN t156 AS t ON s.bwart = t.bwart
INNER JOIN ekbe AS e ON s.ebeln = e.ebeln AND s.ebelp = e.ebelp AND s.mblnr = e.belnr AND s.mjahr = e.gjahr
WHERE e.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
AND e.bwart IN ('101', '102', '122', '123') "GR, GR Reversal, Return
INTO TABLE @DATA(lt_goods_mvmt).
LOOP AT lt_goods_mvmt INTO DATA(ls_goods_mvmt).
ls_event_log-purchaseordernumber = ls_goods_mvmt-ebeln.
IF ls_goods_mvmt-bwart = '101'.
ls_event_log-activityname = 'Goods Receipt Posted'.
ELSE.
ls_event_log-activityname = 'Goods Returned'.
ENDIF.
CONVERT DATE ls_goods_mvmt-cpudt TIME ls_goods_mvmt-cputm INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_goods_mvmt-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 8. Services Confirmation Entered ---
SELECT h.erdat, h.erzeit, h.ernam, l.ebeln
FROM essr AS h
INNER JOIN esll AS l ON h.lblni = l.lblni
WHERE l.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_services).
LOOP AT lt_services INTO DATA(ls_services).
ls_event_log-purchaseordernumber = ls_services-ebeln.
ls_event_log-activityname = 'Services Confirmation Entered'.
CONVERT DATE ls_services-erdat TIME ls_services-erzeit INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_services-ernam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 10. Invoice Received ---
SELECT r.ebeln, r.cpudt, r.cputm, r.usnam
FROM rbkp AS r
WHERE r.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_invoice_rcvd).
LOOP AT lt_invoice_rcvd INTO DATA(ls_invoice_rcvd).
ls_event_log-purchaseordernumber = ls_invoice_rcvd-ebeln.
ls_event_log-activityname = 'Invoice Received'.
CONVERT DATE ls_invoice_rcvd-cpudt TIME ls_invoice_rcvd-cputm INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_invoice_rcvd-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 11. Invoice Paid ---
SELECT b.ebeln, s.augdt, s.augbl, b.usnam
FROM rbkp AS b
INNER JOIN bseg AS e ON b.belnr = e.belnr AND b.gjahr = e.gjahr
INNER JOIN bsak AS s ON e.bukrs = s.bukrs AND e.belnr = s.belnr AND e.gjahr = s.gjahr AND e.buzei = s.buzei
WHERE b.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
AND s.augdt IS NOT NULL
INTO TABLE @DATA(lt_invoice_paid).
LOOP AT lt_invoice_paid INTO DATA(ls_invoice_paid).
ls_event_log-purchaseordernumber = ls_invoice_paid-ebeln.
ls_event_log-activityname = 'Invoice Paid'.
CONVERT DATE ls_invoice_paid-augdt INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_invoice_paid-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 12. Purchase Order Completed & 13. Purchase Order Deleted (via Change Docs) ---
SELECT h.objectid, h.udate, h.utime, h.username, p.fname
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.changenr = p.changenr
INNER JOIN ekpo AS ekpo ON h.objectid = |{ ekpo.ebeln }{ ekpo.ebelp }|
WHERE h.objectclas = 'EINKBELEG'
AND p.tabname = 'EKPO'
AND p.fname IN ('ELIKZ', 'EREKZ', 'LOEKZ')
AND p.value_new = 'X'
AND ekpo.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_status_change).
LOOP AT lt_po_status_change INTO DATA(ls_po_status_change).
ls_event_log-purchaseordernumber = substring( val = ls_po_status_change-objectid, off = 0, len = 10 ).
CASE ls_po_status_change-fname.
WHEN 'LOEKZ'.
ls_event_log-activityname = 'Purchase Order Deleted'.
WHEN 'ELIKZ' OR 'EREKZ'.
"This logic may need refinement to check if both are now set.
ls_event_log-activityname = 'Purchase Order Completed'.
ENDCASE.
CONVERT DATE ls_po_status_change-udate TIME ls_po_status_change-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_status_change-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- Final Output to CSV ---
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
filename = 'C:\temp\po_event_log.csv'
filetype = 'ASC'
CHANGING
data_tab = lt_event_log. 準備はよろしいですか?
このテンプレートは、プロセスマイニングを始めるための確かな基盤となります。SAP S/4HANAのデータを使って効率化の機会を見つけ、今すぐ調達から支払いまでのプロセスを改善しましょう。
発注プロセスを改善し、サイクルタイムを短縮
非効率な箇所をなくし、発注プロセスのサイクルタイムを30%短縮しましょう。
クレジットカードは不要です。数分で設定できます。