調達から支払いまで:購買発注のデータテンプレート
調達から支払いまで:購買発注のデータテンプレート
- 詳細な分析に推奨される属性
- プロセス内で追跡すべき主要なアクティビティ
- データ抽出の手順
調達から支払いまで:発注書の属性
| 名前 | 説明 | ||
|---|---|---|---|
| アクティビティ ActivityName | 購買発注プロセスで発生した業務イベントまたはステップの名称です。 | ||
| 説明 この属性は、購買発注のライフサイクルにおける特定のアクションやステータス変更を示します。例として、「購買発注を作成」「購買発注を承認」「入庫を計上」などがあります。これらのアクティビティの順序によってプロセスフローが形成されます。 アクティビティの順序と頻度の分析は、プロセスマイニングの中心です。実際のプロセスを把握し、設計済みモデルと比較し、ボトルネック(例:「請求書を受領」後の長い待機時間)を特定し、手戻り(例:「購買発注を変更」の繰り返し)を定量化できます。 重要な理由 プロセスのステップを定義し、エンドツーエンドのフロー、バリアント、ボトルネックを可視化・分析できます。 入手先 通常は、EKKO/EKPOのステータス項目やCDHDR/CDPOSの変更伝票ログなど、複数のテーブルと項目を組み合わせて導出し、主要な業務上の節目を表します。 例 購買発注を作成購買発注を承認入庫を計上請求書を受領 | |||
| イベント時刻 EventTime | アクティビティが発生した時点を示すタイムスタンプです。 | ||
| 説明 この属性は、プロセス内の各アクティビティが発生した正確な日付と時刻を記録します。プロセスマイニングにおける時間ベースの分析に欠かせません。 イベント時刻は、アクティビティを時系列に並べ、プロセスフローを構築するために使われます。また、アクティビティ間のサイクルタイム、待機時間、処理時間など、パフォーマンス分析とボトルネック特定に欠かせない、期間ベースのすべての指標を計算する基礎になります。 重要な理由 イベントを正しい順序に並べ、サイクルタイム、リードタイム、待機時間などのパフォーマンス指標を計算するために欠かせないタイムスタンプです。 入手先 特定のアクティビティに関連付けられたタイムスタンプ項目です。例として、作成日(変更の場合はEKKO-AEDAT)や転記日(入庫の場合はMKPF-BUDAT)があります。通常は複数のテーブルのデータを組み合わせる必要があります。 例 2023-04-15T10:00:00Z2023-04-15T14:30:00Z2023-05-01T09:15:00Z | |||
| 購買発注 PurchaseOrderNumber | 購買発注(PO)を一意に識別する項目で、調達ライフサイクルを追跡するための主要なケースIDです。 | ||
| 説明 購買発注番号は、初回作成から最終的な入庫、完了まで、関連するすべてのアクティビティを結び付ける中心的な識別子です。プロセスマイニング分析では、ケース識別子として機能します。 分析では、この番号でイベントをグループ化することで、個々の購買発注の進行を再構成できます。サイクルタイムの計算、プロセスバリアントの分析、単一の注文に固有のボトルネックや逸脱の特定に欠かせません。 重要な理由 すべての調達イベントを単一のエンドツーエンドプロセスに結び付けるための基本的なキーであり、各購買発注のライフサイクルを詳細に分析できます。 入手先 SAP S/4HANAのテーブルEKKOにある項目EBELNで確認できます。 例 450001712345000171244500017125 | |||
| ソースシステム SourceSystem | データの抽出元となるソースシステムを識別します。 | ||
| 説明 この属性は、イベントデータの発生元システムを示します。例として、「SAP S/4HANA本番」や「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 | |||
| サプライヤーID VendorId | 商品やサービスを提供するサプライヤーを一意に識別する項目です。 | ||
| 説明 サプライヤーIDは、購買発注を特定のサプライヤーに結び付ける重要なマスターデータです。調達プロセス全体で、連絡、納入、支払いに利用されます。 プロセスマイニングでは、この属性によってサプライヤー別にパフォーマンスを分析できます。「サプライヤーのリードタイムパフォーマンス」や「サプライヤー別返品率」などのダッシュボードに欠かせず、信頼性の高いサプライヤーや、遅延・品質問題の原因となるサプライヤーを特定できます。 重要な理由 サプライヤーを軸とした分析を可能にし、パフォーマンスの評価、優れたサプライヤーと課題のあるサプライヤーの特定、サプライチェーンの改善に役立ちます。 入手先 SAP S/4HANAのテーブルEKKOにある項目LIFNRで確認できます。 例 100023100045100088 | |||
| ユーザー UserName | 特定のアクティビティを実行したユーザーの識別子です。 | ||
| 説明 この属性は、伝票の作成、変更、承認を担当したSAPユーザーIDを記録します。システム内で行われた操作を追跡できます。 ユーザー別に分析すると、研修の必要性、業務量の配分、個人のパフォーマンスを把握できます。たとえば、特定のユーザーに承認時間の長期化や承認後の変更が継続的に関連しているかを確認し、人員管理やプロセス改善に役立てられます。 重要な理由 説明責任を明確にし、個人またはチーム単位のパフォーマンス分析を可能にします。研修機会やリソース不足の特定にも役立ちます。 入手先 EKKOのERNAM(作成者)や、変更伝票テーブルのユーザー項目(CDHDR-USERNAME)などで確認できます。 例 CB9980000012JSMITHRROE | |||
| 希望納入日 RequestedDeliveryDate | 事業部門がサプライヤーに商品やサービスの納入を希望した日付です。 | ||
| 説明 この属性は、購買発注で合意した目標納入日を示します。サプライヤーの納入パフォーマンスを測定する基準になります。 プロセスマイニングでは、この日付と実際の入庫日(「入庫を計上」のタイムスタンプ)を比較し、「サプライヤー納期遵守率」KPIを計算します。この日付からのずれを分析することで、サプライヤーの信頼性を評価し、サプライチェーンのリスクを管理できます。 重要な理由 サプライヤーの納期遵守パフォーマンスを測定する基準となり、サプライチェーン管理と業務計画に欠かせないKPIを支えます。 入手先 納入日程行テーブルEKETの項目EINDTで確認できます。 例 2023-06-012023-06-152023-07-01 | |||
| 正味合計金額 TotalNetAmount | 税金と運賃を除いた購買発注の合計金額です。 | ||
| 説明 この属性は、購買発注の正味金額を表します。調達取引の規模を示す重要な財務数値です。 この金額は、購買発注を金額別(高額・低額)に分類し、プロセス経路に違いがあるかを確認するなど、財務分析に欠かせません。金額の大きい発注は財務リスクや事業への影響が大きい可能性があるため、分析の優先順位付けにも利用できます。 重要な理由 金額に基づく分析を可能にし、購買発注を金額別に分類して、支出額の大きい領域の改善を優先できます。 入手先 SAP S/4HANAのテーブルEKKOにある項目NETWRで確認できます。 例 1500.0025000.50125.75 | |||
| 購買依頼 PurchaseRequisitionNumber | 購買発注の起点となった購買依頼(PR)の識別子です。 | ||
| 説明 この属性は、購買発注を起点となった購買依頼に結び付けます。購買依頼を経ずに直接作成された購買発注には、この項目がない場合があります。 初回の依頼から始まる調達プロセス全体を分析するために欠かせないリンクです。「購買依頼の承認時間」などのKPIを支え、承認済みの購買依頼を経ずに作成された購買発注による「無断購入」の特定にも役立ちます。 重要な理由 購買発注を初回の依頼に結び付け、エンドツーエンドのプロセス分析と、コンプライアンス違反につながる無断購入の特定を可能にします。 入手先 SAP S/4HANAのテーブルEKPO(購買発注明細レベル)にある項目BANFNで確認できます。 例 1001005110010052 | |||
| 購買発注伝票タイプ DocumentType | 標準購買発注、サービス購買発注、在庫転送発注など、異なる購買発注の種類を区別する分類です。 | ||
| 説明 伝票タイプはSAPの主要な設定要素で、購買発注のプロセスフロー、番号範囲、項目を制御します。さまざまな状況に合わせて調達プロセスを設定できます。 伝票タイプ別にプロセスを分析することは、プロセスの違いを理解するうえで重要です。たとえば、標準品の購買発注とサービス購買発注、在庫転送発注では、プロセスが大きく異なる場合があります。この属性によって異なるプロセスフローを絞り込み、比較し、改善機会を見つけられます。 重要な理由 購買発注を分類し、異なる調達プロセスを比較できます。プロセスフローやサイクルタイムの違いを説明するのにも役立ちます。 入手先 SAP S/4HANAのテーブルEKKOにある項目BSARTで確認できます。 例 NBFOUB | |||
| プラント 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 | |||
| 請求書を受領 | サプライヤーの請求書をSAPシステムに登録し、対応する購買発注に関連付けたことを示します。会計伝票を作成する明示的な財務転記です。 | ||
| 重要な理由 調達プロセスと買掛金プロセスをつなぐ重要な節目です。入庫から請求書処理までの時間を分析できます。 入手先 会計伝票のヘッダーはテーブルBKPFに作成され、明細はBSEGまたはユニバーサルジャーナルACDOCAに保存されます。伝票はテーブルRSEGで購買発注に関連付けられます。 取得 会計伝票ヘッダーテーブルBKPFの伝票入力日(CPUDT)です。 イベントタイプ explicit | |||
| 購買依頼を作成 | このアクティビティは、商品やサービスの正式な依頼を示し、調達プロセスを開始します。ユーザーが新しい購買依頼伝票を保存した時点(例:トランザクションME51N)で明示的に記録されます。 | ||
| 重要な理由 多くの購買発注ライフサイクルにおける主要な開始点です。このイベントから購買発注の作成までの時間を分析すると、調達や社内処理の遅延を特定できます。 入手先 テーブルEBAN(購買依頼)に記録されます。作成イベントのタイムスタンプは、EBANオブジェクトの変更履歴テーブルCDHDRおよびCDPOSで確認できます。 取得 EBANテーブルに伝票が作成された時点で記録されるイベントです。 イベントタイプ explicit | |||
| 購買依頼を承認 | マネージャーまたは指定された承認者が購買依頼を正式に承認したことを示します。通常は購買依頼伝票のステータス変更から推定され、購買発注へ変換できる状態になったことを意味します。 | ||
| 重要な理由 承認サイクルの時間を追跡し、ボトルネックを特定するための重要な節目です。ここでの遅延は、購買発注を作成してサプライヤーへ送付できるまでの時間に直接影響します。 入手先 EBANテーブルのリリースステータス項目(例:FRGZU:リリースインジケーター)から推定します。最終リリースステータスが設定された時点は、その変更を記録した変更伝票(CDHDR/CDPOS)から取得します。 取得 EBANテーブルのリリースステータス項目について、変更ログ(CDHDR/CDPOS)から推定します。 イベントタイプ inferred | |||
| 購買発注を作成 | 正式な購買発注伝票が作成されたことを示します。購買依頼を参照して作成する場合と、参照せずに作成する場合があります。購買発注伝票がシステムに初めて保存された時点で明示的に記録されます。 | ||
| 重要な理由 特に無断購入の分析では、プロセスの別の開始点として利用できます。購買発注の処理時間全体を追跡するための基本的なイベントです。 入手先 購買発注ヘッダーテーブルEKKOに記録されます。伝票の作成日(AEDAT)と時刻は、このテーブルに直接保存されます。 取得 購買発注伝票のEKKOテーブルにある作成タイムスタンプ(AEDAT)です。 イベントタイプ explicit | |||
| 購買発注を完了 | 購買発注明細が物流上クローズされたとみなされることを示します。「納入完了」と「最終請求書」の両方のインジケーターが設定された時点から推定されます。 | ||
| 重要な理由 購買発注ライフサイクル分析の終点です。このイベントまでの時間を測定することで、調達業務のエンドツーエンドのサイクルタイムを把握できます。 入手先 購買発注明細テーブルEKPOのステータスフラグから推定します。「納入完了」インジケーター(ELIKZ)と「最終請求書」インジケーター(EREKZ)の両方がtrueに設定された時点で発生します。 取得 EKPOの項目ELIKZとEREKZの両方が完了として設定された変更ログから推定します。 イベントタイプ inferred | |||
| 購買発注を承認 | 購買発注に必要な社内承認がすべて完了し、サプライヤーへの発行が承認されたことを示します。購買発注のリリース戦略におけるステータス変更から推定されます。 | ||
| 重要な理由 承認の効率と承認後の手戻りを測定するための重要な節目です。購買発注の作成から承認までの時間を分析すると、社内プロセスの遅延を把握できます。 入手先 EKKOテーブルのリリースインジケーター(FRGKE)から推定します。この項目が「リリース済み」に更新された時点を、変更履歴(CDHDR/CDPOS)から特定します。 取得 EKKOテーブルのリリースインジケーター項目(FRGKE)の変更ログから推定します。 イベントタイプ inferred | |||
| サービス確認を入力 | 購買発注で指定されたサービスが提供されたことを確認したアクティビティです。サービスエントリーシートの作成によって明示的に記録されます。 | ||
| 重要な理由 サービス調達では、入庫に相当します。サービス提供の期間を追跡し、サプライヤーへの支払いを適時に行うために重要です。 入手先 サービスエントリーシートの作成によって記録され、データはテーブルESSR(ヘッダー)およびESLL(明細)に保存されます。作成日がタイムスタンプになります。 取得 ESSRテーブルのサービスエントリーシート伝票の作成日です。 イベントタイプ explicit | |||
| 商品を返品 | 以前に受け取った商品を、品質問題、破損、誤納品などの理由でサプライヤーへ返品したことを示します。明示的な返品入庫移動として記録されます。 | ||
| 重要な理由 このアクティビティから、手戻りやサプライヤーの品質、発注精度に関する問題を把握できます。特定のサプライヤーや品目で返品が頻発している場合は、問題の兆候です。 入手先 特定の返品移動タイプ(例:122)を持つ品目伝票として記録されます。イベントはMKPF/MSEGに記録され、EKBEの履歴テーブルで購買発注に関連付けられます。 取得 EKBEにある返品移動タイプ付き品目伝票の転記日です。 イベントタイプ explicit | |||
| 請求書を支払い | 支払処理または手動支払いによって、サプライヤーの請求書を最終決済したことを示します。消込伝票を作成する明示的な財務トランザクションです。 | ||
| 重要な理由 技術的には支払いプロセスの一部ですが、このアクティビティを含めることで、調達から支払いまでのサイクル全体を把握できます。支払条件と支払パフォーマンスの分析に欠かせません。 入手先 支払いはBKPF/ACDOCAの消込伝票として記録されます。テーブルBSEGまたはACDOCAの請求書明細にある消込日(AUGDT)が支払いイベントを示します。 取得 請求書伝票の消込日(AUGDT)で、BSEGまたはACDOCAに記録されています。 イベントタイプ explicit | |||
| 購買発注をサプライヤーへ送付 | 購買発注がEDI、メール、印刷などを通じてサプライヤーに伝達された時点を示します。通常は、システムの出力管理ログから取得します。 | ||
| 重要な理由 サプライヤーのリードタイムは、このアクティビティから始まります。サプライヤーが注文を受け取った時点からパフォーマンスを正確に測定するために欠かせません。 入手先 購買伝票に対して送信されたメッセージを記録する出力管理テーブルNASTから取得します。該当する出力タイプ(例:EDI、メール)の日付と時刻を利用できます。 取得 NASTテーブルにある購買発注の最初の出力成功メッセージのタイムスタンプです。 イベントタイプ inferred | |||
| 購買発注を削除 | 購買発注明細または伝票全体を取り消す、あるいは論理削除することを示します。ユーザーが伝票に削除フラグを設定した時点で記録されます。 | ||
| 重要な理由 プロセスの別の終点であり、失敗またはキャンセルを示します。購買発注が削除された理由を分析すると、需要計画や要件定義の問題を見つけられます。 入手先 購買発注ヘッダー(EKKO)または明細(EKPO)テーブルの削除インジケーター(LOEKZ)から取得します。タイムスタンプは変更伝票(CDHDR/CDPOS)から導出します。 取得 削除フラグ(LOEKZ)が設定された時点の変更伝票(CDHDR/CDPOS)のタイムスタンプです。 イベントタイプ explicit | |||
| 購買発注を変更 | 初回作成後に購買発注が変更されたことを示します。数量、価格、納入日などの変更が該当します。システムの変更ログに明示的に記録されます。 | ||
| 重要な理由 特に承認後の変更を追跡することは、プロセスの非効率、手戻り、コンプライアンス上の潜在的な問題を特定するために重要です。変更が頻繁に発生している場合、初回の要件定義に問題がある可能性があります。 入手先 購買発注オブジェクト(EINKBELEG)の変更伝票テーブルCDHDR(ヘッダー)およびCDPOS(明細)に記録されます。変更ごとに詳細なログエントリが作成されます。 取得 EKKOまたはEKPOテーブルの主要項目に変更があった際のイベントで、CDHDR/CDPOSに記録されます。 イベントタイプ explicit | |||
抽出ガイド
ステップ
- 前提条件とアクセス権限:SAP S/4HANAシステムのCore Data Services(CDS)Viewを照会できる適切な権限を持つユーザーを用意します。SAP HANA Studio、Eclipse向けABAP Development Tools(ADT)、またはSAP HANAデータベースへのSQL接続に対応したサードパーティ製データ抽出ツールからアクセスできます。
- システム接続情報の確認:SAP S/4HANAシステムのホスト、インスタンス番号、認証情報など、必要な接続パラメータを取得します。
- データベースへの接続:使用するSQLクライアントから、CDS Viewが格納されているSAP S/4HANAデータベースに接続します。
- SQLクエリの準備:このドキュメントのクエリセクションに記載された完全なSQLクエリを、SQLエディターにコピーします。このクエリは、必要なすべてのアクティビティと属性を抽出するよう設計されています。
- フィルタリングパラメータの設定:クエリ内のプレースホルダー値を確認します。分析対象の日付範囲に合わせて、_start_dateと_end_dateを置き換えます(例:'20230101'と'20231231')。poh.CompanyCodeフィルターは、分析対象の会社コードに変更します。
- クエリの実行:変更したSQLクエリをS/4HANAデータベースに対して実行します。データ量や指定した日付範囲によっては、処理に時間がかかる場合があります。
- 初期結果の確認:クエリの実行が完了したら、SQLクライアントで出力結果を簡単に確認します。複数のアクティビティが含まれていること、タイムスタンプが正しく設定されていること、ケースID(PurchaseOrderNumber)が一貫していることを確認します。
- データのエクスポート:SQLツールから結果セット全体をCSV(Comma Separated Values)ファイルにエクスポートします。文字化けを防ぐため、UTF-8エンコーディングを使用します。
- アップロードの準備:ProcessMindにアップロードする前にCSVファイルを開き、列見出しがデータ要件で定義された属性(PurchaseOrderNumber、ActivityName、EventTimeなど)と完全に一致していることを確認します。エクスポートツールによって列名が変更されている場合は修正します。
- ProcessMindへのアップロード:完成したCSVファイルをProcessMindプロジェクトにアップロードします。インポート時に、ファイル内の列を対応するケースID、アクティビティ、タイムスタンプのフィールドにマッピングします。
設定
- 主なCDS View:抽出ロジックでは、標準化された意味情報を持つ複数のCDS Viewを使用します。主なViewは次のとおりです。
- 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 Viewに対するSELECT権限が必要です。通常、これらのViewへのアクセス権限は、S/4HANAの業務ロールまたは分析ロールを通じて付与されます。適切な権限がない場合、クエリは失敗します。
a サンプルクエリ 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か月分から始めます。過去データをロードする場合は、より短い期間に分け、境界が重なる部分を照合して抜け漏れを防ぎます。
- フィルター:必要な範囲に合わせて、Company Code、Document Type、VendorId、購買組織、購買グループ、イベント日付のフィルターを設定します。会社コードと伝票タイプのフィルターには、対象システムで有効な値を使用する必要があります。
- イベントの意味:該当する伝票フィールドまたはログが利用できる場合、作成と削除は明示的なイベントにできます。承認と完了はステータスに基づくイベントであり、設定済みのステータスタイムスタンプが必要です。根拠のあるイベント時刻がない場合、現在のステータスだけをもとに行を作成しないでください。
- 性能:イベント日付と組織範囲で早い段階からフィルタリングし、可能な場合はイベントソースと結合する前にEKPOを集計します。大量の過去データは期間を分けて実行します。適切なデータベース統計を設定し、明細、会計、変更履歴のデータソース間で制限のない結合を避けます。
- 更新時刻:1回の実行で生成するすべての行について、LastDataUpdateに抽出実行時刻を設定します。
- 前提条件:SAP HANAへの接続、設定したすべてのデータソースオブジェクトへの読み取り権限、購買、在庫管理、サービス調達、請求書照合、買掛金データへのアクセス、選択したファイルまたは結果セットをインポートできるProcessMind接続が必要です。
- システム固有の設定:クエリ内の角括弧で囲まれたすべてのデータソースプレースホルダーを、対象のSAP S/4HANAシステムで承認されたテーブル、View、列、または式に置き換えます。クエリや抽出設定に認証情報を記載しないでください。
a サンプルクエリ 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種類すべてのアクティビティを処理した後、すべてのデータが単一の統合された内部テーブルに収集されていることを確認します。このテーブルが、選択した購買発注の完全なイベントログになります。
- ファイル出力の実装:最終的な内部テーブルをファイルに書き出す機能を追加します。推奨方法は、cl_gui_frontend_services=>gui_downloadメソッドを使ってユーザーがローカルマシンにCSVとして保存できるようにするか、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)とテーブル/フィールドの組み合わせだけを選択するよう最適化します。
- 権限:このレポートを実行するユーザーまたは技術アカウントには、複数のSAPモジュールにまたがるテーブルへの広範な読み取り権限が必要です。対象には、Materials Management(MM)、Financial Accounting(FI)、システム共通テーブルが含まれます。具体的には、EKKO、EKPO、EBAN、EKBE、BKPF、BSAK、RBKP、NAST、CDHDR、CDPOSなどです。
- バックグラウンド実行:数か月を超えるデータを抽出する場合や、取引量の多いシステムで実行する場合は、ダイアログプロセスのタイムアウトを防ぐため、必ずバックグラウンドでプログラムを実行します。
a サンプルクエリ 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%短縮します。
クレジットカードは不要です。数分で設定できます。