您的供应链管理数据模板
您的供应链管理数据模板
- 建议收集的属性
- 需要跟踪的关键活动
- 数据提取指南
供应链管理属性
| 名称 | 说明 | ||
|---|---|---|---|
| 事件时间 EventTime | 表示活动发生日期和时间的时间戳。 | ||
| 说明 此属性提供流程中每项活动的准确日期和时间,是事件日志的时间顺序依据,可按实际发生顺序排列流程步骤。 事件时间是所有基于时间的分析的关键。它用于计算活动间的周期时间、衡量流程总周期时间、识别随时间变化的绩效趋势,并确定瓶颈最可能出现的时间。 重要性 此时间戳是计算各类时长和绩效指标的基础,可用于分析流程瓶颈和周期时间。 获取途径 从SAP核心表中与单据创建或状态变化相关的时间戳字段提取,例如更改凭证表CDHDR/CDPOS,或抬头表中的ERDAT/ERZET等日期和时间字段。 示例 2023-04-15T10:25:00Z2023-04-18T14:00:00Z2023-04-22T08:15:00Z | |||
| 活动名称 ActivityName | 供应链流程中某个时间点发生的业务活动或事件名称。 | ||
| 说明 此属性描述物流订单生命周期中的具体步骤或里程碑,例如“已发出采购订单”或“已过账发货”。这些活动按顺序构成流程。 分析活动顺序是流程挖掘的核心。您可以据此发现实际流程,比较实际执行情况与标准操作规程,并找出导致延迟或需要返工的步骤。 重要性 它定义了流程的各个步骤,是发现流程图、分析变体以及衡量活动间周期时间的基础。 获取途径 在数据转换过程中,将SAP各表中的事务代码或状态变化(例如EKKO、LIKP、VBUK)映射为易于理解的活动名称后生成。 示例 下达采购订单过账采购订单收货创建出库交货单已确认交货证明 | |||
| 物流订单 LogisticsOrder | 用于标识单个端到端供应链流程的唯一标识符,涵盖从初始需求到最终交货确认的全过程。 | ||
| 说明 物流订单是主要案例标识符,用于关联供应链中与特定需求或履约请求相关的所有活动。借助这种方式,您可以跟踪产品从规划、采购到生产和配送的完整生命周期,全面了解流程。 在流程挖掘中,按物流订单分析可以还原满足需求的完整路径。这样,您就能识别整个供应链中的常见变体、瓶颈和偏差,而不必将采购或销售等孤立流程分开分析。 重要性 这是将所有相关事件关联为单个流程实例的关键标识符,可用于端到端分析供应链。 获取途径 这是一个概念性标识符,可能需要通过关联多个单据编号来构建,例如将销售订单编号与后续采购订单和交货单编号关联。请参阅SAP S/4HANA供应链文档或咨询相关领域专家。 示例 LO-4500078192LO-4500078193LO-4500078194 | |||
| 上次数据更新 LastDataUpdate | 数据上次从源系统刷新或提取的时间戳。 | ||
| 说明 此属性表示事件日志数据上次更新的时间,为正在分析的数据提供更新时间信息,让您了解数据的时效性。 进行分析时,了解数据的更新时间至关重要,有助于您据此作出判断。此时间戳可以帮助您确认数据的可信度,并了解仪表板和KPI所覆盖的时间范围。 重要性 清楚说明数据的更新时间,让您了解流程分析所依据的数据有多新。 获取途径 这是一个元数据字段,通常由数据提取或ETL工具在成功刷新数据后生成并填充。 示例 2023-10-27T02:00:00Z2023-10-28T02:00:00Z2023-10-29T02:00:00Z | |||
| 源系统 SourceSystem | 数据的来源系统。 | ||
| 说明 用于标识生成事件数据的具体源系统实例。在复杂的系统环境中,公司可能会为不同地区或业务单元部署多个SAP S/4HANA实例。 此属性对于数据治理和分析细分至关重要。分析人员可以据此比较不同系统中的流程绩效,或仅分析来自单一权威来源的数据。 重要性 提供数据来源的重要背景信息,有助于验证数据并比较不同系统环境中的流程。 获取途径 通常在数据提取过程中添加为静态值,用于标识数据来源,例如SAP系统ID(SAPSID)。 示例 S4H_PROD_EUS4H_PROD_NAS4H_DEV | |||
| 供应商名称 SupplierName | 与采购活动相关的供应商名称。 | ||
| 说明 此属性用于标识采购货物或服务的供应商,通常与“已创建采购申请”和“已发出采购订单”等活动相关联。 供应商名称是供应商交付绩效仪表板的重要属性。您可以据此筛选和细分数据,比较不同供应商的准时交付率、周期时间和质量水平,为战略采购和供应商关系管理提供依据。 重要性 支持按供应商分析绩效,对于优化采购流程和评估供应商可靠性至关重要。 获取途径 供应商编号(LIFNR)存储在采购单据中(例如表EKKN、EBAN),名称则从中央供应商主数据表LFA1中获取。 示例 Global Components Inc.Advanced Materials LLCPrecision Parts Co. | |||
| 客户名称 CustomerName | 订单履约所服务的客户名称。 | ||
| 说明 此属性用于标识销售订单及后续履约活动所对应的最终客户,为供应链流程的需求端提供背景信息。 在流程挖掘中,按客户分析有助于发现重点客户的不同履约模式或绩效水平。您可以在交货证明延迟分析等仪表板中使用此属性,查看某些客户是否经常延迟确认收货。 重要性 支持按客户细分分析,揭示客户特有的行为、瓶颈或服务级别协议绩效。 获取途径 客户编号(KUNNR)存储在销售单据中(例如表VBAK),名称则从中央客户主数据表KNA1中获取。 示例 Retail CorpInnovate SolutionsManufacturing Partners | |||
| 工厂 Plant | 活动发生的生产或配送设施。 | ||
| 说明 工厂是SAP中的组织单位,代表生产、存储或配送货物的地点,为流程活动提供地理或职能背景。 按工厂分析流程绩效是常见需求。您可以据此对不同运营地点的效率、吞吐量和合规情况进行基准比较,发现最佳实践或需要改进的地点。 重要性 提供地理或组织维度,支持比较不同设施的绩效。 获取途径 可在许多单据项目表中找到,例如VBAP(销售)、EKPO(采购)和LIPS(交货)。字段通常命名为WERKS。 示例 100021003500 | |||
| 执行用户 ExecutingUser | 执行该活动人员的用户ID。 | ||
| 说明 此属性记录执行特定活动(例如创建采购订单或过账收货)的员工SAP用户名或ID,将流程步骤与相关人员关联起来。 按用户分析有助于了解工作量分布、识别培训需求,并发现个人或团队之间的绩效差异。通过合规分析,还可以查看由谁执行了关键流程步骤。 重要性 将活动关联到具体用户,以便分析工作量、比较绩效,并调查不符合要求的操作。 获取途径 可在许多SAP表的“创建者”或“更改者”字段中找到,例如EKKO(采购订单抬头)中的ERNAM、LIKP(交货抬头)和VBRK(发票抬头)。 示例 CBROWNJSMITHASINGH | |||
| 物料编号 MaterialNumber | 正在处理的产品或物料的唯一标识符。 | ||
| 说明 物料编号通常也称为SKU,是SAP中用于标识特定产品的唯一代码。它将流程活动与正在生产、采购或发运的实物或数字产品关联起来。 此属性对于产品维度分析至关重要。您可以据此判断特定产品是否更容易出现质量问题、生产延迟或缺货。还可以按物料筛选仪表板,调查特定产品线的绩效。 重要性 支持产品级分析,帮助识别延迟或质量问题等流程问题是否集中在特定物料上。 获取途径 可在大多数单据的项目级表中找到,例如销售订单表VBAP、采购订单表EKPO和交货单表LIPS。字段通常命名为MATNR。 示例 FG-100-ARM-2034-BSA-5500 | |||
| 要求交货日期 RequestedDeliveryDate | 要求供应商交付货物的日期。 | ||
| 说明 这是采购订单中指定的交货日期,代表对供应商的交付要求,也是衡量实际交付绩效的基准。 此日期是计算供应商准时交付率KPI的关键。将实际收货日期与要求交货日期进行比较,企业便可客观衡量供应商是否履行承诺。 重要性 这是计算供应商准时交付率KPI所用的基准日期,对于供应商绩效管理至关重要。 获取途径 可在采购订单项目表EKPO中找到,字段名为EINDT(交货日期)。 示例 2023-05-20T00:00:00Z2023-06-15T00:00:00Z2023-07-01T00:00:00Z | |||
| 质量检验结果 QualityInspectionResult | 质量检验的结果,例如“通过”或“未通过”。 | ||
| 说明 此属性记录对生产或接收的货物进行质量检查后的结果。结果决定货物能否进入下一步,或是否需要返工、退货或报废。 此属性是质量控制拒收率仪表板和KPI的关键依据。分析检验失败的频率和原因,有助于发现特定产品、供应商或生产线存在的系统性质量问题。 重要性 直接支持质量相关KPI的计算,并帮助定位供应链中质量不佳的来源。 获取途径 此信息通常存储在质量管理(QM)模块中。数据可能来自QALS等检验批表,以及QAVE中的使用决策代码。 示例 通过未通过需要返工有偏差但通过 | |||
| 承运商名称 CarrierName | 负责运输货物的运输公司或货运代理名称。 | ||
| 说明 承运商名称用于标识负责在不同地点之间运输货物的物流服务提供商,例如从仓库运送货物至客户。 此属性是运输周期时间分析仪表板的重要依据。您可以据此比较不同承运商的运输时间、成本和可靠性,从而改进物流规划和承运商选择。 重要性 支持按运输服务提供商分析绩效,是优化物流成本和交付时间的关键。 获取途径 承运商ID(货运代理)存储在运输单据中,例如VTTK表(运输单抬头)。名称则从LFA1等主数据表中获取。 示例 DHLFedExMaersk Logistics | |||
| 是否延迟交货 IsLateDelivery | 用于标记供应商交货是否晚于要求交货日期的布尔值。 | ||
| 说明 此计算字段以简单的真或假值表示交货是否准时。它通过比较“采购订单收货已过账”活动的时间戳与“要求交货日期”属性得出。 此属性简化了供应商绩效相关仪表板和KPI的创建。您可以快速筛选和汇总数据,计算供应商准时交付率,并识别延迟最频繁的供应商、物料或地区。 重要性 为每次交货提供明确的二元结果,简化供应商绩效分析,是计算准时交付KPI的重要依据。 获取途径 这是一个计算字段。逻辑为:IF('Goods Receipt For PO Posted'.EventTime > PurchaseOrder.RequestedDeliveryDate)THEN True ELSE False。 示例 truefalse | |||
| 是否返工 IsRework | 用于标记某项活动或一系列活动是否属于返工。 | ||
| 说明 此布尔属性用于标记流程中重复执行先前步骤的活动,表示发生了返工或纠正。例如,“质量检验”之后出现“已创建生产订单”,随后又进行一次“质量检验”,则第二次检验可标记为返工。 识别返工是了解流程低效和隐性成本的关键。此标记有助于量化返工循环的频率和影响,支持计算订单处理错误率KPI,并指出流程改进方向。 重要性 明确识别并统计返工循环中的活动,帮助量化流程低效问题。 获取途径 通常由流程挖掘工具通过识别同一案例中的重复活动序列来计算。 示例 truefalse | |||
| 结束时间 EndTime | 表示活动完成时间的时间戳,用于计算处理时间。 | ||
| 说明 结束时间表示某项活动完成的时间。开始时间(EventTime)表示活动何时开始,而结束时间则用于了解活动执行了多久,尤其适用于并非瞬时完成的活动。 同时记录开始和结束时间,才能准确衡量处理时间与等待时间。这有助于区分实际执行任务的时间和等待下一步的时间,是发现效率机会的关键。 重要性 可准确计算活动处理时间,帮助区分增值工作与等待时间。 获取途径 可根据SAP中的状态变化推导。例如,JEST/JCDS等表中的“进行中”状态更新可作为开始时间,“已完成”状态更新可作为结束时间。对于瞬时事件,EndTime可能与StartTime相同。 示例 2023-04-15T11:30:00Z2023-04-18T14:05:00Z2023-04-22T09:00:00Z | |||
| 订单数量 OrderQuantity | 订单行项目中物料的数量。 | ||
| 说明 此属性表示销售订单或采购订单行项目中所需的物料数量,用于衡量每笔交易的业务量。 按数量分析有助于优先关注业务量大的订单,因为这类订单可能产生更大的业务影响。数量还可用于标准化其他指标,例如计算单位成本,或了解订单规模对处理时间的影响。 重要性 提供交易量背景信息,支持分析影响并按规模细分案例。 获取途径 可在项目级表中找到,例如采购订单表EKPO中的MENGE或销售订单表VBAP中的KWMENG。 示例 100500025 | |||
| 采购订单编号 PurchaseOrderNumber | 采购订单(PO)单据的唯一标识符。 | ||
| 说明 采购订单编号是向供应商订购物料时使用的正式单据编号,也是供应链采购环节的关键标识符。 此属性支持深入分析采购流程,可用于采购端到端周期时间仪表板和供应商准时交付率KPI的计算,并关联采购申请、订单、收货和付款活动。 重要性 作为关键标识符,支持逐级下钻分析采购子流程,并关联相关采购事件。 获取途径 可在采购订单抬头表EKKO和项目表EKPO中找到,字段名为EBELN。 示例 450007819245000781934500078194 | |||
| 销售订单编号 SalesOrderNumber | 销售订单(SO)单据的唯一标识符。 | ||
| 说明 销售订单编号是确认向客户销售的正式单据编号,也是供应链订单到收款环节的关键标识符。 此属性对于跟踪特定客户订单的履约情况至关重要。它将客户的初始请求与后续交货和开票等活动关联起来,支持订单履约周期时间分析。 重要性 作为关键标识符,将客户需求与物流和财务结算关联起来,支持分析订单履约子流程。 获取途径 可在销售订单抬头表VBAK和项目表VBAP中找到,字段名为VBELN。 示例 100023451000234610002347 | |||
供应链管理活动
| 活动 | 说明 | ||
|---|---|---|---|
| 下达采购订单 | 表示正式创建并向外部供应商下达所需物料的采购订单。此活动将采购申请转化为与供应商之间具有法律约束力的承诺。 | ||
| 重要性 作为关键里程碑,此活动对于衡量供应商交付周期和采购周期至关重要,也为评估供应商按时交付绩效提供基准。 获取途径 系统会在创建采购订单时明确记录此事件。创建时间戳存储在采购订单抬头表(EKKO)的AEDAT字段中。 采集 使用采购订单的单据创建日期(EKKO-AEDAT)。 事件类型 explicit | |||
| 创建销售订单 | 此活动表示新销售订单的创建,用于正式记录客户的货物需求。用户在系统中保存新的销售订单单据时,系统会明确记录这一事件。 | ||
| 重要性 这是订单到收款流程的主要起点。分析此事件与后续事件之间的时间,可以了解订单履行的整体周期,并发现初始处理延误。 获取途径 系统会明确记录此事件。您可以在销售订单表的变更凭证(CDHDR/CDPOS)中查找,也可以使用销售订单抬头表(VBAK)中的创建时间戳字段ERDAT。 采集 使用销售订单单据的创建日期(VBAK-ERDAT)和时间(VBAK-ERZET)。 事件类型 explicit | |||
| 已确认交货证明 | 表示客户或承运商正式确认已按要求收到货物。通常通过在外向交货单中更新交货证明(POD)信息来记录。 | ||
| 重要性 此活动标志着履约流程正式结束。它对于准确开票、解决争议以及衡量交付最后阶段的时长至关重要。 获取途径 这是一个明确事件。交货证明日期记录在交货抬头表(LIKP,字段PODAT)或相关POD表(VLPOD)中。 采集 使用交货单中的交货证明日期(LIKP-PODAT)。 事件类型 explicit | |||
| 已过账发货 | 此活动表示货物在法律和实物层面离开仓库。它会减少库存并过账销售成本,标志着订单正式发运。 | ||
| 重要性 这是一个关键里程碑,标志着货物进入“运输途中”阶段,也是货物离开公司控制、开始交付的明确时间点。 获取途径 这是一个会生成物料凭证的明确事件。时间戳记录在物料凭证抬头(MKPF,字段BUDAT)中,同时更新交货凭证(LIKP,字段WBSTK)中的货物移动状态。 采集 使用与外向交货关联的发货物料凭证中的过账日期(MKPF-BUDAT)。 事件类型 explicit | |||
| 生产货物 | 此活动表示确认货物已完成生产。通常会将其记录为生产订单收货,并将成品转入库存。 | ||
| 重要性 这标志着生产周期结束。从创建生产订单到发生此事件的时间即为生产周期,是衡量生产效率的关键指标。 获取途径 您可以通过物料凭证过账明确记录此事件(生产订单收货),也可以根据生产订单的最终确认(AFRU表)或状态变更为“已交付”进行推断。 采集 根据生产订单最终收货物料凭证的过账日期或状态变更进行推断。 事件类型 inferred | |||
| 过账采购订单收货 | 表示根据采购订单,实际收到供应商交付的原材料或货物。货物到达仓库或工厂时,系统会记录此事件。 | ||
| 重要性 此活动标志着采购周期中的供应商交付环节完成。它对于计算供应商按时交付率和了解入库物流绩效至关重要。 获取途径 系统会通过物料凭证过账明确记录此事件。事件时间戳位于物料凭证抬头表(MKPF)的BUDAT字段中,与采购订单的关联信息位于项目表(MSEG)中。 采集 使用与采购订单关联的物料凭证过账日期(MKPF-BUDAT)。 事件类型 explicit | |||
| 创建出库交货单 | 表示已创建交货单据,授权拣货并向客户发运货物。此活动标志着流程从订单管理转入物流执行。 | ||
| 重要性 这是启动实物履行流程的关键步骤。订单创建与交货单创建之间的延误,可能表明计划或货物可用性存在问题。 获取途径 这是一个明确记录的事件。创建时间戳记录在交货单抬头表(LIKP)的ERDAT字段中。 采集 使用交货单据抬头中的创建日期(LIKP-ERDAT)和时间(LIKP-ERZET)。 事件类型 explicit | |||
| 创建生产订单 | 表示已创建生产订单,用于制造销售订单所需的成品。这是内部生产流程的正式起点。 | ||
| 重要性 创建生产订单标志着生产周期开始。分析这一时间点,有助于发现需求信号出现到生产启动之间的延误。 获取途径 这是一个明确记录的事件。创建日期记录在生产订单抬头表(AUFK)的ERDAT字段中。 采集 使用订单抬头表中的创建日期(AUFK-ERDAT)。 事件类型 explicit | |||
| 创建采购申请 | 此活动表示创建内部申请,以采购所需货物或原材料。库存不足以履行销售订单或低于再订货点时,通常会触发此活动。 | ||
| 重要性 这是采购周期的第一步。跟踪采购申请的创建时间,有助于发现采购启动延误,并分析端到端采购流程。 获取途径 这是一个明确记录的事件。创建时间戳记录在采购申请抬头表(EBAN)的BADAT字段中。 采集 使用采购申请单据的创建日期(EBAN-BADAT)。 事件类型 explicit | |||
| 完成拣货 | 此活动表示已完成从仓库中拣取出库交货所需货物的实物操作。在许多系统中,更新交货单据的拣货状态时会确认此活动。 | ||
| 重要性 高效拣货对仓库吞吐能力至关重要。跟踪此活动有助于发现仓库运营中的瓶颈并衡量拣货绩效。 获取途径 这通常不是单一的独立事件,而是根据状态变化推断得出。当交货项目表(LIPS,字段KOSTA)中的拣配状态设为“C”(已完全处理)时,即记录此事件。 采集 根据更改凭证推断:当拣配状态(LIPS-KOSTA)更新为已全部拣配时,即发生此事件。 事件类型 inferred | |||
| 已创建客户发票 | 此活动表示已根据交付的货物或服务为客户创建开票凭证,标志着流程进入最终财务结算阶段。 | ||
| 重要性 此活动是分析开票周期时间的关键。交货确认与开票之间的延迟可能会对现金流造成不利影响。 获取途径 这是一个明确事件。创建时间戳记录在开票凭证抬头表(VBRK,字段ERDAT)中。 采集 使用开票凭证抬头中的创建日期(VBRK-ERDAT)。 事件类型 explicit | |||
| 已创建运输单 | 表示已创建运输单据,用于将一份或多份交货单归组,以便进行运输规划。单据中包含承运商、路线和运输方式等信息。 | ||
| 重要性 此活动标志着正式运输规划的开始。分析从发货到运输完成所需的时间,有助于评估运输流程的效率。 获取途径 这是记录在运输单抬头表(VTTK,字段ERDAT)中的明确事件。该功能属于LE-TRA模块,并非所有组织都会使用。 采集 使用运输单据抬头中的创建日期(VTTK-ERDAT)。 事件类型 explicit | |||
| 执行质量检验 | 表示已完成对生产货物的质量检查。检验结果为通过或不通过,并记录在使用决策中。 | ||
| 重要性 此活动对于监控产品质量和发现生产问题至关重要。不合格率偏高或检验时间过长,都可能形成严重瓶颈。 获取途径 系统会在对质量检验批次作出使用决策时明确记录此事件。决策日期位于QALS表的PASTRTERM字段或QAVE表中。 采集 使用检验批次记录使用决策的时间戳(QALS/QAVE表)。 事件类型 explicit | |||
| 检查库存可用性 | 表示系统或人工检查库存中是否有可用于履行销售订单的所需商品。这通常是在创建销售订单时自动执行的步骤,但未必会作为独立事件记录。 | ||
| 重要性 了解订单创建与库存检查之间的时间及检查结果,有助于分析库存水平对履行周期的影响。此处发生延误通常会引发采购或生产活动。 获取途径 这通常不是一个明确记录的事件。您可以根据销售订单项目表(VBEP)中首个已确认计划行的创建情况,或订单项目中的状态变更推断此事件。 采集 根据销售订单计划行(VBEP表)中的确认状态更新进行推断。 事件类型 inferred | |||
| 货物已在目的地卸载 | 此活动表示货物已在客户所在地实际卸载。SAP中可能不会明确记录此事件,通常需要根据承运商数据或后续事件推断。 | ||
| 重要性 这标志着运输途中阶段的结束。从发货到此时的时长即为运输时间,是优化物流的关键指标。 获取途径 核心ERP中很少会明确记录此事件。可根据承运商EDI消息、运输管理(TM)模块的数据,或可用的交货证明单据时间戳进行推断。 采集 根据承运商状态更新(例如EDI 214)推断,或使用交货证明时间戳作为近似值。 事件类型 inferred | |||
数据提取指南
步骤
- 前置条件:确保您拥有足够权限的用户账号,可访问所需的SAP S/4HANA核心数据服务(CDS)视图。通常需要由SAP安全团队为该账号分配特定角色。您还需要能够连接SAP HANA数据库的SQL客户端,例如DBeaver或SAP HANA Studio。
- 建立数据库连接:配置SQL客户端以连接SAP S/4HANA数据库。您需要数据库服务器主机、端口(例如3xx15,其中xx为实例编号)、数据库用户名和密码。
- 准备SQL查询:将本文档查询部分提供的完整SQL查询复制到SQL客户端编辑器中。此查询用于从多个物流和销售模块提取指定的所有活动。
- 设置提取参数:运行查询前,找到各子查询
WHERE子句中的占位条件。将'YourCompanyCode'替换为要分析的实际公司代码,并将'YYYY-MM-DD'等日期范围占位值调整为所需的提取时间段。 - 执行查询:运行完整SQL脚本。执行时间取决于所选日期范围和系统中的数据量。建议在非高峰时段运行,以尽量降低系统负载。
- 检查初步结果:查询完成后,在SQL客户端中快速检查输出。确认行数合理,LogisticsOrder、ActivityName和EventTime等列均有值,并且结果中包含多种活动名称。
- 将数据导出为CSV:通过SQL客户端将完整结果集导出为CSV文件。请选择UTF-8编码,避免特殊字符显示异常。
- 整理上传文件:确保最终CSV文件的列标题与导入所需的属性名称完全一致,例如
LogisticsOrder、ActivityName和EventTime。如果使用提供的SQL查询,无需进一步转换数据。
配置
- 前置条件:需要能够访问底层SAP HANA数据库。数据库用户必须对查询中引用的所有CDS视图拥有
SELECT权限,包括但不限于I_SalesOrderItem、I_PurchaseOrderItem、I_OutboundDeliveryItem、I_MaterialDocumentItem、I_ProductionOrder、I_QualityInspection、I_Shipment和I_BillingDocumentItem。 - 日期范围筛选:提供的查询包含日期范围筛选占位符,通常使用创建日期字段(
CreationDate或DocumentDate)筛选。首次分析建议选择3至6个月的数据,以获得有代表性的数据集,同时避免系统负载过高。 - 关键业务筛选条件:必须按特定组织单元筛选数据,确保分析结果符合实际需求。查询已预留
CompanyCode占位符。您也可以根据分析范围,添加SalesOrganization、DistributionChannel或Plant筛选条件。 - 性能注意事项:此查询较为复杂,需要关联多个大型CDS视图,执行时可能占用大量系统资源。请安排在非工作时间提取数据。对于超大型数据集,可考虑按月分批、依次运行查询。
查询示例 sql
WITH SalesOrderLink AS (
SELECT DISTINCT
sd.SalesDocument AS SalesOrder,
pr.PurchaseRequisition AS PurchaseRequisition,
po.PurchaseOrder AS PurchaseOrder,
od.DeliveryDocument AS OutboundDelivery,
bd.BillingDocument AS BillingDocument
FROM I_SalesDocItemProcessFlow AS pf
LEFT JOIN I_SalesDocumentItem AS sd ON pf.PrecedingDocument = sd.SalesDocument AND pf.PrecedingDocumentItem = sd.SalesDocumentItem
LEFT JOIN I_PurchaseRequisitionItem AS pr ON pf.SubsequentDocument = pr.PurchaseRequisition AND pf.SubsequentDocumentItem = pr.PurchaseRequisitionItem
LEFT JOIN I_PurchaseOrderItem AS po ON pf.SubsequentDocument = po.PurchaseOrder AND pf.SubsequentDocumentItem = po.PurchaseOrderItem
LEFT JOIN I_OutboundDeliveryItem AS od ON pf.SubsequentDocument = od.DeliveryDocument AND pf.SubsequentDocumentItem = od.DeliveryDocumentItem
LEFT JOIN I_BillingDocumentItem AS bd ON pf.SubsequentDocument = bd.BillingDocument AND pf.SubsequentDocumentItem = bd.BillingDocumentItem
WHERE sd.SalesDocument IS NOT NULL
)
SELECT
so.SalesOrder AS "LogisticsOrder",
'Sales Order Created' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
so.SalesOrder AS "LogisticsOrder",
'Inventory Availability Checked' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Requisition Created' AS "ActivityName",
pr.CreationDate || ' ' || '00:00:00' AS "EventTime",
pr.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
pri.Material AS "MaterialNumber",
pri.Plant AS "Plant",
pri.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseRequisition AS pr
JOIN I_PurchaseRequisitionItem AS pri ON pr.PurchaseRequisition = pri.PurchaseRequisition
JOIN SalesOrderLink sl ON pr.PurchaseRequisition = sl.PurchaseRequisition
WHERE pr.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND pr.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Order Issued' AS "ActivityName",
po.PurchaseOrderDate || ' ' || '00:00:00' AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
poi.Material AS "MaterialNumber",
poi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseOrder AS po
JOIN I_PurchaseOrderItem AS poi ON po.PurchaseOrder = poi.PurchaseOrder
LEFT JOIN I_Supplier AS sup ON po.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON po.PurchaseOrder = sl.PurchaseOrder
WHERE po.PurchaseOrderDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND po.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Receipt For PO Posted' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_PurchaseOrderItem AS poi ON mdi.PurchaseOrder = poi.PurchaseOrder AND mdi.PurchaseOrderItem = poi.PurchaseOrderItem
LEFT JOIN I_Supplier AS sup ON poi.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON poi.PurchaseOrder = sl.PurchaseOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101' AND mdi.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Production Order Created' AS "ActivityName",
po.CreationDate || ' ' || po.CreationTime AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
po.Material AS "MaterialNumber",
po.ProductionPlant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_ProductionOrder AS po
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE po.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Produced' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_ProductionOrder AS po ON mdi.ManufacturingOrder = po.ManufacturingOrder
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101'
UNION ALL
SELECT
qi.SalesOrder AS "LogisticsOrder",
'Quality Inspection Performed' AS "ActivityName",
qi.InspLotUsageDecisionDate || ' ' || qi.InspLotUsageDecisionTime AS "EventTime",
qi.InspLotUsageDecisionMadeByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
qi.Material AS "MaterialNumber",
qi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
qi.InspLotUsageDecisionCode AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_QualityInspection AS qi
WHERE qi.InspLotUsageDecisionDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND qi.SalesOrder IS NOT NULL
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Outbound Delivery Created' AS "ActivityName",
od.CreationDate || ' ' || od.CreationTime AS "EventTime",
od.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Picking Completed' AS "ActivityName",
od.PickingDate || ' ' || od.PickingTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PickingDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPickingStatus = 'C'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Goods Issue Posted' AS "ActivityName",
od.ActualGoodsMovementDate || ' ' || od.ActualGoodsMovementTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.ActualGoodsMovementDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallGoodsMovementStatus = 'C'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Shipment Created' AS "ActivityName",
sh.CreationDate || ' ' || sh.CreationTime AS "EventTime",
sh.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
NULL AS "MaterialNumber",
sh.ShippingPoint AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_Shipment AS sh
JOIN I_ShipmentDelivery AS sd ON sh.Shipment = sd.Shipment
JOIN SalesOrderLink sl ON sd.Delivery = sl.OutboundDelivery
WHERE sh.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Proof Of Delivery Confirmed' AS "ActivityName",
od.PODActualDate || ' ' || '00:00:00' AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PODActualDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPODStatus = 'C'
UNION ALL
SELECT
bdi.SalesDocument AS "LogisticsOrder",
'Customer Invoice Created' AS "ActivityName",
bd.BillingDocumentDate || ' ' || bd.CreationTime AS "EventTime",
bd.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
bdi.Material AS "MaterialNumber",
bdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_BillingDocument AS bd
JOIN I_BillingDocumentItem AS bdi ON bd.BillingDocument = bdi.BillingDocument
LEFT JOIN I_Customer AS cust ON bd.SoldToParty = cust.Customer
WHERE bd.BillingDocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND bd.CompanyCode = 'YourCompanyCode' AND bdi.SalesDocument IS NOT NULL; 步骤
- 确认您可以直接读取包含相关物流、销售、采购、库存、生产、质量、交付、运输、交货证明和开票数据的SAP HANA架构。向SAP Basis或数据平台团队获取架构名称、连接信息和权限。请勿向源系统写入数据。
- 确认目标系统中实际使用的S/4HANA数据模型。采购订单使用EKKO和EKPO,出库交货使用LIKP和LIPS;销售订单、采购申请、物料凭证、生产订单、质量检验结果、运输、交货证明和开票等数据对象需另行配置。请根据系统数据字典核实对象,并替换查询中所有方括号标记的对象或列占位符。
- 定义LogisticsOrder关联规则。优先使用经核实的单据流关系,将销售订单与后续交货、物料凭证、生产或采购单据及开票单据关联起来。如果无法直接关联,请配置有文档记录的关联表或符合业务要求的映射规则。请勿仅凭物料编号或日期关联案例。
- 使用[Start date parameter]和[End date parameter]设置提取时间段。事件时间戳应统一应用该时间段;如果时间段内的事件需要依赖此前创建的单据进行解释,则应保留这些单据。
- 在标记的筛选区域配置公司代码、销售组织、工厂、采购组织、单据类型及其他业务筛选条件。确认目标系统中的实际值后再使用筛选条件。
- 将每个活动分支中的方括号表名和列名替换为已核实的名称。所有分支必须返回相同的列,且数据类型兼容。查询会为所需的15项活动分别生成一行,因为ProcessMind不会推断缺失事件。
- 在SAP HANA Database Explorer、SAP HANA cockpit SQL Console或获批的SQL客户端中执行查询。运行完整的UNION ALL查询前,请分别测试每个活动分支。检查执行计划,并在初次测试时限制日期范围。
- 验证单据关系、时间戳、用户标识、供应商和客户值、物料和工厂值以及质量结果。检查项目级关联产生的重复行,并应用已配置的事件粒度规则,例如每份单据一个事件或每个单据项目一个事件。
- 将结果导出为UTF-8 CSV或ProcessMind支持的其他表格格式。请保留以下准确的输出列名:LogisticsOrder、ActivityName、EventTime、SourceSystem、LastDataUpdate、ExecutingUser、SupplierName、CustomerName、MaterialNumber、Plant、RequestedDeliveryDate和QualityInspectionResult。确保EventTime为时间戳,并以一致的方式填充LastDataUpdate。
- 将文件上传至ProcessMind,并将LogisticsOrder映射为案例标识符、ActivityName映射为活动、EventTime映射为事件时间戳。确认15个活动标签均作为明确事件处理,并在验证增量提取行为后安排受控刷新。
配置
- **日期范围:**先提取3至6个月的数据。初次测试时使用更短的时间段,确认性能和单据关系无误后再扩大范围。
- **源架构:**将[SAP HANA schema name]设为包含已核实S/4HANA表或视图的架构。不要假设所有S/4HANA部署都使用相同名称的传统ERP表。
- **单据范围:**根据流程范围配置[Company Code filter]、[Sales Organization filter]、[Plant filter]、[Purchasing Organization filter]和[Document Type filter]。
- **关联规则:**配置[Your document flow or correlation object],确保每个事件都关联到一个LogisticsOrder。发现缺失或存在歧义的关联时,应报告问题,不要静默分配。
- **事件粒度:**选择每份单据、每个单据项目或每次与业务相关的状态变更作为一个事件。所有分支都应使用相同规则,并且只删除技术性重复行。
- **时间戳优先级:**根据各项活动使用已核实的过账、创建、确认、状态变更、检验、交货、卸货、POD或开票时间戳。请勿用提取时间代替业务事件时间。
- **来源标签:**将[Source system label]设为稳定值,例如经批准的SAP S/4HANA系统标识符。
- **刷新时间戳:**将[Last data update expression]设为经批准的提取时间戳或源系统刷新时间戳。
- **性能:**尽早应用日期和组织筛选条件,只选择所需列,避免不受限制的项目级关联,并检查执行计划。对于定期加载,可考虑使用持久化提取视图或暂存表。
- **权限:**需要具备相关SAP HANA架构对象的读取权限和SQL执行权限。业务验证还需要访问适用的销售、采购、库存、生产、质量、物流执行、运输和开票数据。
- **功能范围:**确认已部署系统包含所需活动对应的业务流程。运输、卸货、POD、质量、生产和开票数据可能存储在不同的应用或扩展中。
- **安全:**遵循组织对客户、供应商、物料、财务和用户数据的管理规定。必要时对敏感字段进行脱敏或限制访问。
查询示例 sql
WITH
parameters AS (
SELECT
CAST('[Start date parameter]' AS TIMESTAMP) AS start_ts,
CAST('[End date parameter]' AS TIMESTAMP) AS end_ts,
CAST('[Last data update expression]' AS TIMESTAMP) AS last_data_update,
CAST('[Source system label]' AS NVARCHAR(100)) AS source_system,
CAST('[Company Code filter]' AS NVARCHAR(20)) AS company_code_filter,
CAST('[Sales Organization filter]' AS NVARCHAR(20)) AS sales_org_filter,
CAST('[Plant filter]' AS NVARCHAR(20)) AS plant_filter,
CAST('[Purchasing Organization filter]' AS NVARCHAR(20)) AS purchasing_org_filter,
CAST('[Document Type filter]' AS NVARCHAR(20)) AS document_type_filter
FROM DUMMY
),
base_events AS (
SELECT
CAST('[Sales order correlation column]' AS NVARCHAR(100)) AS LogisticsOrder,
CAST('Sales Order Created' AS NVARCHAR(100)) AS ActivityName,
CAST('[Sales order creation timestamp]' AS TIMESTAMP) AS EventTime,
CAST('[Executing user column]' AS NVARCHAR(100)) AS ExecutingUser,
CAST('[Supplier name column]' AS NVARCHAR(255)) AS SupplierName,
CAST('[Customer name column]' AS NVARCHAR(255)) AS CustomerName,
CAST('[Material number column]' AS NVARCHAR(100)) AS MaterialNumber,
CAST('[Plant column]' AS NVARCHAR(100)) AS Plant,
CAST('[Requested delivery date column]' AS DATE) AS RequestedDeliveryDate,
CAST('[Quality inspection result column]' AS NVARCHAR(100)) AS QualityInspectionResult
FROM [Your sales order source object]
CROSS JOIN parameters p
WHERE CAST('[Sales order creation timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Sales order creation timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Sales order company code column]' AS NVARCHAR(20)) = p.company_code_filter
AND CAST('[Sales order sales organization column]' AS NVARCHAR(20)) = p.sales_org_filter
AND CAST('[Sales order document type column]' AS NVARCHAR(20)) = p.document_type_filter
UNION ALL
SELECT
CAST('[Inventory check correlation column]' AS NVARCHAR(100)),
CAST('Inventory Availability Checked' AS NVARCHAR(100)),
CAST('[Inventory check timestamp]' AS TIMESTAMP),
CAST('[Inventory check user column]' AS NVARCHAR(100)),
CAST('[Inventory supplier name column]' AS NVARCHAR(255)),
CAST('[Inventory customer name column]' AS NVARCHAR(255)),
CAST('[Inventory material number column]' AS NVARCHAR(100)),
CAST('[Inventory plant column]' AS NVARCHAR(100)),
CAST('[Inventory requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your inventory availability source object]
CROSS JOIN parameters p
WHERE CAST('[Inventory check timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Inventory check timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Inventory company code column]' AS NVARCHAR(20)) = p.company_code_filter
AND CAST('[Inventory sales organization column]' AS NVARCHAR(20)) = p.sales_org_filter
UNION ALL
SELECT
CAST('[Purchase requisition correlation column]' AS NVARCHAR(100)),
CAST('Purchase Requisition Created' AS NVARCHAR(100)),
CAST('[Purchase requisition creation timestamp]' AS TIMESTAMP),
CAST('[Purchase requisition user column]' AS NVARCHAR(100)),
CAST('[Purchase requisition supplier name column]' AS NVARCHAR(255)),
CAST('[Purchase requisition customer name column]' AS NVARCHAR(255)),
CAST('[Purchase requisition material number column]' AS NVARCHAR(100)),
CAST('[Purchase requisition plant column]' AS NVARCHAR(100)),
CAST('[Purchase requisition requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your purchase requisition source object]
CROSS JOIN parameters p
WHERE CAST('[Purchase requisition creation timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Purchase requisition creation timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Purchase requisition plant column]' AS NVARCHAR(20)) = p.plant_filter
UNION ALL
SELECT
CAST('[Purchase order correlation column]' AS NVARCHAR(100)),
CAST('Purchase Order Issued' AS NVARCHAR(100)),
CAST('[Purchase order issue timestamp]' AS TIMESTAMP),
CAST('[Purchase order user column]' AS NVARCHAR(100)),
CAST('[Purchase order supplier name column]' AS NVARCHAR(255)),
CAST('[Purchase order customer name column]' AS NVARCHAR(255)),
CAST('[Purchase order material number column]' AS NVARCHAR(100)),
CAST('[Purchase order plant column]' AS NVARCHAR(100)),
CAST('[Purchase order requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM EKKO po_header
INNER JOIN EKPO po_item
ON po_header.[Purchase order number column] = po_item.[Purchase order number column]
CROSS JOIN parameters p
WHERE CAST('[Purchase order issue timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Purchase order issue timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Purchase order company code column]' AS NVARCHAR(20)) = p.company_code_filter
AND CAST('[Purchase order purchasing organization column]' AS NVARCHAR(20)) = p.purchasing_org_filter
AND CAST('[Purchase order document type column]' AS NVARCHAR(20)) = p.document_type_filter
UNION ALL
SELECT
CAST('[Goods receipt correlation column]' AS NVARCHAR(100)),
CAST('Goods Receipt For PO Posted' AS NVARCHAR(100)),
CAST('[Goods receipt posting timestamp]' AS TIMESTAMP),
CAST('[Goods receipt user column]' AS NVARCHAR(100)),
CAST('[Goods receipt supplier name column]' AS NVARCHAR(255)),
CAST('[Goods receipt customer name column]' AS NVARCHAR(255)),
CAST('[Goods receipt material number column]' AS NVARCHAR(100)),
CAST('[Goods receipt plant column]' AS NVARCHAR(100)),
CAST('[Goods receipt requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your material document header source object] material_header
INNER JOIN [Your material document item source object] material_item
ON material_header.[Material document number column] = material_item.[Material document number column]
AND material_header.[Material document year column] = material_item.[Material document year column]
CROSS JOIN parameters p
WHERE CAST('[Goods receipt posting timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Goods receipt posting timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Goods receipt plant column]' AS NVARCHAR(20)) = p.plant_filter
AND CAST('[Goods receipt movement type column]' AS NVARCHAR(20)) = '[Goods receipt movement type value]'
UNION ALL
SELECT
CAST('[Production order correlation column]' AS NVARCHAR(100)),
CAST('Production Order Created' AS NVARCHAR(100)),
CAST('[Production order creation timestamp]' AS TIMESTAMP),
CAST('[Production order user column]' AS NVARCHAR(100)),
CAST('[Production order supplier name column]' AS NVARCHAR(255)),
CAST('[Production order customer name column]' AS NVARCHAR(255)),
CAST('[Production order material number column]' AS NVARCHAR(100)),
CAST('[Production order plant column]' AS NVARCHAR(100)),
CAST('[Production order requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your production order source object]
CROSS JOIN parameters p
WHERE CAST('[Production order creation timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Production order creation timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Production order plant column]' AS NVARCHAR(20)) = p.plant_filter
UNION ALL
SELECT
CAST('[Production receipt correlation column]' AS NVARCHAR(100)),
CAST('Goods Produced' AS NVARCHAR(100)),
CAST('[Production receipt timestamp]' AS TIMESTAMP),
CAST('[Production receipt user column]' AS NVARCHAR(100)),
CAST('[Production receipt supplier name column]' AS NVARCHAR(255)),
CAST('[Production receipt customer name column]' AS NVARCHAR(255)),
CAST('[Production receipt material number column]' AS NVARCHAR(100)),
CAST('[Production receipt plant column]' AS NVARCHAR(100)),
CAST('[Production receipt requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your production receipt source object]
CROSS JOIN parameters p
WHERE CAST('[Production receipt timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Production receipt timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Production receipt plant column]' AS NVARCHAR(20)) = p.plant_filter
UNION ALL
SELECT
CAST('[Quality inspection correlation column]' AS NVARCHAR(100)),
CAST('Quality Inspection Performed' AS NVARCHAR(100)),
CAST('[Quality inspection completion timestamp]' AS TIMESTAMP),
CAST('[Quality inspection user column]' AS NVARCHAR(100)),
CAST('[Quality supplier name column]' AS NVARCHAR(255)),
CAST('[Quality customer name column]' AS NVARCHAR(255)),
CAST('[Quality material number column]' AS NVARCHAR(100)),
CAST('[Quality plant column]' AS NVARCHAR(100)),
CAST('[Quality requested delivery date column]' AS DATE),
CAST('[Quality inspection result column]' AS NVARCHAR(100))
FROM [Your quality inspection source object]
CROSS JOIN parameters p
WHERE CAST('[Quality inspection completion timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Quality inspection completion timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Quality plant column]' AS NVARCHAR(20)) = p.plant_filter
UNION ALL
SELECT
CAST('[Outbound delivery correlation column]' AS NVARCHAR(100)),
CAST('Outbound Delivery Created' AS NVARCHAR(100)),
CAST('[Outbound delivery creation timestamp]' AS TIMESTAMP),
CAST('[Outbound delivery user column]' AS NVARCHAR(100)),
CAST('[Outbound delivery supplier name column]' AS NVARCHAR(255)),
CAST('[Outbound delivery customer name column]' AS NVARCHAR(255)),
CAST('[Outbound delivery material number column]' AS NVARCHAR(100)),
CAST('[Outbound delivery plant column]' AS NVARCHAR(100)),
CAST('[Outbound delivery requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM LIKP delivery_header
INNER JOIN LIPS delivery_item
ON delivery_header.[Delivery number column] = delivery_item.[Delivery number column]
CROSS JOIN parameters p
WHERE CAST('[Outbound delivery creation timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Outbound delivery creation timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Outbound delivery plant column]' AS NVARCHAR(20)) = p.plant_filter
UNION ALL
SELECT
CAST('[Picking correlation column]' AS NVARCHAR(100)),
CAST('Picking Completed' AS NVARCHAR(100)),
CAST('[Picking completion timestamp]' AS TIMESTAMP),
CAST('[Picking user column]' AS NVARCHAR(100)),
CAST('[Picking supplier name column]' AS NVARCHAR(255)),
CAST('[Picking customer name column]' AS NVARCHAR(255)),
CAST('[Picking material number column]' AS NVARCHAR(100)),
CAST('[Picking plant column]' AS NVARCHAR(100)),
CAST('[Picking requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your picking status source object]
CROSS JOIN parameters p
WHERE CAST('[Picking completion timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Picking completion timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Picking plant column]' AS NVARCHAR(20)) = p.plant_filter
AND CAST('[Picking completion status column]' AS NVARCHAR(50)) = '[Picking completed status value]'
UNION ALL
SELECT
CAST('[Goods issue correlation column]' AS NVARCHAR(100)),
CAST('Goods Issue Posted' AS NVARCHAR(100)),
CAST('[Goods issue posting timestamp]' AS TIMESTAMP),
CAST('[Goods issue user column]' AS NVARCHAR(100)),
CAST('[Goods issue supplier name column]' AS NVARCHAR(255)),
CAST('[Goods issue customer name column]' AS NVARCHAR(255)),
CAST('[Goods issue material number column]' AS NVARCHAR(100)),
CAST('[Goods issue plant column]' AS NVARCHAR(100)),
CAST('[Goods issue requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your goods issue source object]
CROSS JOIN parameters p
WHERE CAST('[Goods issue posting timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Goods issue posting timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Goods issue plant column]' AS NVARCHAR(20)) = p.plant_filter
AND CAST('[Goods issue movement type column]' AS NVARCHAR(20)) = '[Goods issue movement type value]'
UNION ALL
SELECT
CAST('[Shipment correlation column]' AS NVARCHAR(100)),
CAST('Shipment Created' AS NVARCHAR(100)),
CAST('[Shipment creation timestamp]' AS TIMESTAMP),
CAST('[Shipment user column]' AS NVARCHAR(100)),
CAST('[Shipment supplier name column]' AS NVARCHAR(255)),
CAST('[Shipment customer name column]' AS NVARCHAR(255)),
CAST('[Shipment material number column]' AS NVARCHAR(100)),
CAST('[Shipment plant column]' AS NVARCHAR(100)),
CAST('[Shipment requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your shipment source object]
CROSS JOIN parameters p
WHERE CAST('[Shipment creation timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Shipment creation timestamp]' AS TIMESTAMP) < p.end_ts
AND CAST('[Shipment plant column]' AS NVARCHAR(20)) = p.plant_filter
UNION ALL
SELECT
CAST('[Unloading correlation column]' AS NVARCHAR(100)),
CAST('Goods Unloaded at Destination' AS NVARCHAR(100)),
CAST('[Unloading timestamp]' AS TIMESTAMP),
CAST('[Unloading user column]' AS NVARCHAR(100)),
CAST('[Unloading supplier name column]' AS NVARCHAR(255)),
CAST('[Unloading customer name column]' AS NVARCHAR(255)),
CAST('[Unloading material number column]' AS NVARCHAR(100)),
CAST('[Unloading plant column]' AS NVARCHAR(100)),
CAST('[Unloading requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your unloading or carrier event source object]
CROSS JOIN parameters p
WHERE CAST('[Unloading timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Unloading timestamp]' AS TIMESTAMP) < p.end_ts
UNION ALL
SELECT
CAST('[POD correlation column]' AS NVARCHAR(100)),
CAST('Proof Of Delivery Confirmed' AS NVARCHAR(100)),
CAST('[POD confirmation timestamp]' AS TIMESTAMP),
CAST('[POD user column]' AS NVARCHAR(100)),
CAST('[POD supplier name column]' AS NVARCHAR(255)),
CAST('[POD customer name column]' AS NVARCHAR(255)),
CAST('[POD material number column]' AS NVARCHAR(100)),
CAST('[POD plant column]' AS NVARCHAR(100)),
CAST('[POD requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your proof of delivery source object]
CROSS JOIN parameters p
WHERE CAST('[POD confirmation timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[POD confirmation timestamp]' AS TIMESTAMP) < p.end_ts
UNION ALL
SELECT
CAST('[Billing correlation column]' AS NVARCHAR(100)),
CAST('Customer Invoice Created' AS NVARCHAR(100)),
CAST('[Billing creation timestamp]' AS TIMESTAMP),
CAST('[Billing user column]' AS NVARCHAR(100)),
CAST('[Billing supplier name column]' AS NVARCHAR(255)),
CAST('[Billing customer name column]' AS NVARCHAR(255)),
CAST('[Billing material number column]' AS NVARCHAR(100)),
CAST('[Billing plant column]' AS NVARCHAR(100)),
CAST('[Billing requested delivery date column]' AS DATE),
CAST(NULL AS NVARCHAR(100))
FROM [Your billing document source object]
CROSS JOIN parameters p
WHERE CAST('[Billing creation timestamp]' AS TIMESTAMP) >= p.start_ts
AND CAST('[Billing creation timestamp]' AS TIMESTAMP) < p.end_ts
)
SELECT
LogisticsOrder,
ActivityName,
EventTime,
parameters.source_system AS SourceSystem,
parameters.last_data_update AS LastDataUpdate,
ExecutingUser,
SupplierName,
CustomerName,
MaterialNumber,
Plant,
RequestedDeliveryDate,
QualityInspectionResult
FROM base_events
CROSS JOIN parameters
WHERE LogisticsOrder IS NOT NULL
AND ActivityName IS NOT NULL
AND EventTime IS NOT NULL
ORDER BY LogisticsOrder, EventTime, ActivityName; 步骤
- 前置条件:确保您拥有开发密钥和在SAP S/4HANA系统中创建、执行ABAP程序所需的权限(可访问事务码SE38),并且可以读取VBAK、LIKP、EKKO和MKPF等供应链表。
- 创建程序:使用事务码
SE38打开ABAP编辑器。输入新程序名称,例如Z_PM_SCM_EXTRACTION,然后点击“创建”。填写描述性标题,并将程序类型设为“可执行程序”。 - 插入代码:将下方“查询”部分中的完整ABAP代码复制并粘贴到新程序的ABAP编辑器中。
- 定义文本元素:依次选择“转到”>“文本元素”>“选择文本”。激活所有建议的选择屏幕标签,使界面清晰易用。
- 激活程序:按CTRL+S保存,再按CTRL+F3激活;也可以点击工具栏中的激活图标。根据系统配置修正可能出现的语法错误。
- 执行程序:按F8运行程序,或点击“直接处理”按钮。随后会显示选择屏幕,您可以筛选要提取的数据。
- 设置提取参数:在选择屏幕中指定销售订单创建日期范围。强烈建议同时按特定公司代码或销售组织筛选,以控制数据量。输入输出文件在SAP应用服务器上的完整路径。
- 后台运行:如果要处理数月的大型数据集,务必在后台执行程序,避免事务超时。从菜单中选择“程序”>“后台执行”,然后安排作业。
- 获取数据文件:程序执行完成后,使用事务码
AL11打开指定的应用服务器目录。找到生成的文件,并使用事务码CG3Y下载到本地计算机。 - 准备上传:确保下载的文件为纯文本格式,例如使用逗号或分号分隔的CSV,并采用UTF-8编码。文件现已准备好,可上传至流程挖掘工具。
配置
- 选择日期范围(S_ERDAT):这是最关键的筛选条件,用于根据销售订单创建日期(
VBAK-ERDAT)确定初始订单的时间范围。建议先选择较短的时间段,例如最近3至6个月,以控制数据量。 - 销售组织(S_VKORG):可选筛选条件,用于限定特定销售组织,适合聚焦某个业务单元或地区。
- 公司代码(S_BUKRS):可选筛选条件,用于限定特定公司代码。强烈建议使用,以缩小数据范围并提升性能。
- 输出文件路径(P_FILE):事件日志文件在SAP应用服务器上的完整保存路径。运行程序的用户必须拥有该目录的写入权限。例如:
/usr/sap/trans/tmp/scm_event_log.csv。 - 执行模式:小规模测试提取可在前台运行。数据量较大时,必须使用后台处理,以避免超时并减少高峰时段的系统负载。
- 系统权限:运行报表的用户需要具备所有底层表的读取权限,包括但不限于VBAK、VBAP、EKKO、EKPO、MSEG、MKPF、LIKP、LIPS、VBRK、AUFK、QAVE、KNA1和LFA1。
查询示例 abap
REPORT Z_PM_SCM_EXTRACTION.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
PARAMETERS: p_file TYPE string LOWER CASE DEFAULT '/usr/sap/trans/tmp/scm_event_log.csv'.
SELECT-OPTIONS: s_erdat FOR sy-datum OBLIGATORY,
s_vkorg FOR vbak-vkorg,
s_bukrs FOR vbak-bukrs.
*&---------------------------------------------------------------------*
*& Data Type Definitions
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
LogisticsOrder TYPE vbeln_va,
ActivityName TYPE string,
EventTime TYPE string,
SourceSystem TYPE sysysid,
LastDataUpdate TYPE string,
ExecutingUser TYPE ernam,
SupplierName TYPE name1_gp,
CustomerName TYPE name1_gp,
MaterialNumber TYPE matnr,
Plant TYPE werks_d,
RequestedDeliveryDate TYPE vdatu,
QualityInspectionResult TYPE string,
END OF ty_event_log.
*&---------------------------------------------------------------------*
*& Data Declarations
*&---------------------------------------------------------------------*
DATA: lt_event_log TYPE TABLE OF ty_event_log,
ls_event_log TYPE ty_event_log,
lv_sysid TYPE sysysid,
lv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& START-OF-SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.
lv_sysid = sy-sysid.
CONCATENATE sy-datum sy-uzeit INTO lv_last_update.
" Select base data: Sales Orders
SELECT h~vbeln, h~erdat, h~erzet, h~ernam, h~kunnr, h~bukrs, h~vdatu, i~posnr, i~matnr, i~werks
INTO TABLE @DATA(lt_so)
FROM vbak AS h
INNER JOIN vbap AS i ON h~vbeln = i~vbeln
WHERE h~erdat IN @s_erdat
AND h~vkorg IN @s_vkorg
AND h~bukrs IN @s_bukrs.
IF lt_so IS INITIAL.
MESSAGE 'No sales orders found for the given criteria.' TYPE 'I'.
RETURN.
ENDIF.
" Select related documents using Document Flow (VBFA)
SELECT *
INTO TABLE @DATA(lt_vbfa)
FROM vbfa
FOR ALL ENTRIES IN @lt_so
WHERE vbelv = @lt_so-vbeln
AND posnv = @lt_so-posnr.
" Collect all unique document numbers
DATA: lt_vbeln_pr TYPE RANGE OF banfn,
lt_vbeln_po TYPE RANGE OF ebeln,
lt_vbeln_dn TYPE RANGE OF vbeln_vl,
lt_vbeln_gi TYPE RANGE OF mblnr,
lt_vbeln_auf TYPE RANGE OF aufnr,
lt_vbeln_inv TYPE RANGE OF vbeln_vf,
lt_vbeln_shp TYPE RANGE OF tknum.
LOOP AT lt_vbfa INTO DATA(ls_vbfa).
CASE ls_vbfa-vbtyp_n.
WHEN 'H'. " Purchase Requisition
APPEND ls_vbfa-vbeln TO lt_vbeln_pr.
WHEN 'K'. " Purchase Order
APPEND ls_vbfa-vbeln TO lt_vbeln_po.
WHEN 'J'. " Delivery
APPEND ls_vbfa-vbeln TO lt_vbeln_dn.
WHEN 'R'. " Goods Movement (GI)
APPEND ls_vbfa-vbeln TO lt_vbeln_gi.
WHEN 'L'. " Production Order
APPEND ls_vbfa-vbeln TO lt_vbeln_auf.
WHEN 'M'. " Invoice
APPEND ls_vbfa-vbeln TO lt_vbeln_inv.
WHEN '8'. " Shipment
APPEND ls_vbfa-vbeln TO lt_vbeln_shp.
ENDCASE.
ENDLOOP.
SORT lt_vbeln_pr. DELETE ADJACENT DUPLICATES FROM lt_vbeln_pr.
SORT lt_vbeln_po. DELETE ADJACENT DUPLICATES FROM lt_vbeln_po.
SORT lt_vbeln_dn. DELETE ADJACENT DUPLICATES FROM lt_vbeln_dn.
SORT lt_vbeln_gi. DELETE ADJACENT DUPLICATES FROM lt_vbeln_gi.
SORT lt_vbeln_auf. DELETE ADJACENT DUPLICATES FROM lt_vbeln_auf.
SORT lt_vbeln_inv. DELETE ADJACENT DUPLICATES FROM lt_vbeln_inv.
SORT lt_vbeln_shp. DELETE ADJACENT DUPLICATES FROM lt_vbeln_shp.
" Select detailed data for each document type
SELECT banfn, badat, ernam FROM eban INTO TABLE @DATA(lt_eban) FOR ALL ENTRIES IN @lt_so WHERE bnfpo = @lt_so-posnr AND banfn IN @lt_vbeln_pr.
SELECT ebeln, aedat, ernam, lifnr FROM ekko INTO TABLE @DATA(lt_ekko) WHERE ebeln IN @lt_vbeln_po.
SELECT vbeln, erdat, erzet, ernam, kodat, wadat_ist, podat FROM likp INTO TABLE @DATA(lt_likp) WHERE vbeln IN @lt_vbeln_dn.
SELECT mblnr, mjahr, budat, usnam FROM mkpf INTO TABLE @DATA(lt_mkpf) WHERE mblnr IN @lt_vbeln_gi.
SELECT mblnr, mjahr, zeile, bwart, lfbnr, ebeln, aufnr FROM mseg INTO TABLE @DATA(lt_mseg) FOR ALL ENTRIES IN @lt_mkpf WHERE mblnr = @lt_mkpf-mblnr AND mjahr = @lt_mkpf-mjahr.
SELECT aufnr, erdat, ernam FROM aufk INTO TABLE @DATA(lt_aufk) WHERE aufnr IN @lt_vbeln_auf.
SELECT prueflos, vdatum, vcode FROM qave INTO TABLE @DATA(lt_qave) FOR ALL ENTRIES IN @lt_so WHERE aufnr IN @lt_vbeln_auf.
SELECT vbeln, erdat, erzet, ernam FROM vbrk INTO TABLE @DATA(lt_vbrk) WHERE vbeln IN @lt_vbeln_inv.
SELECT tknum, erdat, erzet FROM vttk INTO TABLE @DATA(lt_vttk) WHERE tknum IN @lt_vbeln_shp.
SELECT kunnr, name1 FROM kna1 INTO TABLE @DATA(lt_kna1) FOR ALL ENTRIES IN @lt_so WHERE kunnr = @lt_so-kunnr.
SELECT lifnr, name1 FROM lfa1 INTO TABLE @DATA(lt_lfa1) FOR ALL ENTRIES IN @lt_ekko WHERE lifnr = @lt_ekko-lifnr.
" Assemble Event Log
LOOP AT lt_so INTO DATA(ls_so).
CLEAR ls_event_log.
READ TABLE lt_kna1 INTO DATA(ls_kna1) WITH KEY kunnr = ls_so-kunnr BINARY SEARCH.
ls_event_log-LogisticsOrder = ls_so-vbeln.
ls_event_log-SourceSystem = lv_sysid.
ls_event_log-LastDataUpdate = lv_last_update.
ls_event_log-CustomerName = ls_kna1-name1.
ls_event_log-MaterialNumber = ls_so-matnr.
ls_event_log-Plant = ls_so-werks.
ls_event_log-RequestedDeliveryDate = ls_so-vdatu.
" 1. Sales Order Created
ls_event_log-ActivityName = 'Sales Order Created'.
CONCATENATE ls_so-erdat ls_so-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_so-ernam.
APPEND ls_event_log TO lt_event_log.
" 2. Inventory Availability Checked (proxy event)
ls_event_log-ActivityName = 'Inventory Availability Checked'.
CONCATENATE ls_so-erdat ls_so-erzet INTO ls_event_log-EventTime. " Using SO creation time as a proxy
ls_event_log-ExecutingUser = ls_so-ernam.
APPEND ls_event_log TO lt_event_log.
" Find related documents for this SO item
LOOP AT lt_vbfa INTO ls_vbfa WHERE vbelv = ls_so-vbeln AND posnv = ls_so-posnr.
CASE ls_vbfa-vbtyp_n.
WHEN 'H'. " 3. Purchase Requisition Created
READ TABLE lt_eban INTO DATA(ls_eban) WITH KEY banfn = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Purchase Requisition Created'.
CONCATENATE ls_eban-badat '000000' INTO ls_event_log-EventTime. " PR has no time field
ls_event_log-ExecutingUser = ls_eban-ernam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN 'K'. " 4. Purchase Order Issued
READ TABLE lt_ekko INTO DATA(ls_ekko) WITH KEY ebeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
READ TABLE lt_lfa1 INTO DATA(ls_lfa1) WITH KEY lifnr = ls_ekko-lifnr BINARY SEARCH.
ls_event_log-ActivityName = 'Purchase Order Issued'.
CONCATENATE ls_ekko-aedat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_ekko-ernam.
ls_event_log-SupplierName = ls_lfa1-name1.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN 'L'. " 6. Production Order Created
READ TABLE lt_aufk INTO DATA(ls_aufk) WITH KEY aufnr = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Production Order Created'.
CONCATENATE ls_aufk-erdat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_aufk-ernam.
APPEND ls_event_log TO lt_event_log.
" 8. Quality Inspection Performed
READ TABLE lt_qave INTO DATA(ls_qave) WITH KEY prueflos = ls_vbfa-vbeln. " Approximation linking lot to order
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Quality Inspection Performed'.
CONCATENATE ls_qave-vdatum '000000' INTO ls_event_log-EventTime.
ls_event_log-QualityInspectionResult = ls_qave-vcode.
APPEND ls_event_log TO lt_event_log.
CLEAR ls_event_log-QualityInspectionResult.
ENDIF.
ENDIF.
WHEN 'J'. " 9. Outbound Delivery Created
READ TABLE lt_likp INTO DATA(ls_likp) WITH KEY vbeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Outbound Delivery Created'.
CONCATENATE ls_likp-erdat ls_likp-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_likp-ernam.
APPEND ls_event_log TO lt_event_log.
" 10. Picking Completed
IF ls_likp-kodat IS NOT INITIAL.
ls_event_log-ActivityName = 'Picking Completed'.
CONCATENATE ls_likp-kodat '120000' INTO ls_event_log-EventTime. " Using Picking Date as proxy
APPEND ls_event_log TO lt_event_log.
ENDIF.
" 14. Proof Of Delivery Confirmed
IF ls_likp-podat IS NOT INITIAL.
ls_event_log-ActivityName = 'Proof Of Delivery Confirmed'.
CONCATENATE ls_likp-podat '000000' INTO ls_event_log-EventTime.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDIF.
WHEN 'M'. " 15. Customer Invoice Created
READ TABLE lt_vbrk INTO DATA(ls_vbrk) WITH KEY vbeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Customer Invoice Created'.
CONCATENATE ls_vbrk-erdat ls_vbrk-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_vbrk-ernam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN '8'. " 12. Shipment Created
READ TABLE lt_vttk INTO DATA(ls_vttk) WITH KEY tknum = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Shipment Created'.
CONCATENATE ls_vttk-erdat ls_vttk-erzet INTO ls_event_log-EventTime.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
" Find material movements (MSEG) not directly in VBFA
" 5. Goods Receipt For PO Posted
LOOP AT lt_mseg INTO DATA(ls_mseg_po) WHERE ebeln IN (SELECT ebeln FROM ekpo WHERE banfn IN (SELECT banfn FROM eban WHERE vbeln = ls_so-vbeln) ) AND bwart = '101'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_po) WITH KEY mblnr = ls_mseg_po-mblnr mjahr = ls_mseg_po-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Receipt For PO Posted'.
CONCATENATE ls_mkpf_po-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_po-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
" 7. Goods Produced
LOOP AT lt_mseg INTO DATA(ls_mseg_pp) WHERE aufnr IN (SELECT aufnr FROM afpo WHERE kdauf = ls_so-vbeln) AND bwart = '101'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_pp) WITH KEY mblnr = ls_mseg_pp-mblnr mjahr = ls_mseg_pp-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Produced'.
CONCATENATE ls_mkpf_pp-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_pp-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
" 11. Goods Issue Posted
LOOP AT lt_mseg INTO DATA(ls_mseg_gi) WHERE lfbnr IN (SELECT vbeln FROM lips WHERE vgbel = ls_so-vbeln) AND bwart = '601'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_gi) WITH KEY mblnr = ls_mseg_gi-mblnr mjahr = ls_mseg_gi-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Issue Posted'.
CONCATENATE ls_mkpf_gi-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_gi-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
ENDLOOP.
" Remove duplicate events for the same case
SORT lt_event_log BY LogisticsOrder ActivityName EventTime.
DELETE ADJACENT DUPLICATES FROM lt_event_log COMPARING LogisticsOrder ActivityName EventTime.
" Write data to file
DATA: lt_output TYPE TABLE OF string.
APPEND 'LogisticsOrder,ActivityName,EventTime,SourceSystem,LastDataUpdate,ExecutingUser,SupplierName,CustomerName,MaterialNumber,Plant,RequestedDeliveryDate,QualityInspectionResult' TO lt_output.
LOOP AT lt_event_log INTO ls_event_log.
DATA(lv_line) = |
{ ls_event_log-LogisticsOrder },
{ ls_event_log-ActivityName },
{ ls_event_log-EventTime },
{ ls_event_log-SourceSystem },
{ ls_event_log-LastDataUpdate },
{ ls_event_log-ExecutingUser },
{ ls_event_log-SupplierName },
{ ls_event_log-CustomerName },
{ ls_event_log-MaterialNumber },
{ ls_event_log-Plant },
{ ls_event_log-RequestedDeliveryDate },
{ ls_event_log-QualityInspectionResult }|
.
REPLACE ALL OCCURRENCES OF ',' IN lv_line WITH ' '.
REPLACE ALL OCCURRENCES OF REGEX '\s+' IN lv_line WITH '' LEADING.
CONDENSE lv_line.
APPEND lv_line TO lt_output.
ENDLOOP.
cl_gui_frontend_services=>gui_download(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_output
EXCEPTIONS
OTHERS = 24
).
IF sy-subrc <> 0.
MESSAGE 'Error downloading file.' TYPE 'E'.
ELSE.
MESSAGE |File downloaded successfully to { p_file }| TYPE 'S'.
ENDIF. 立即优化供应链管理
端到端掌握流程,几天内将预测准确率提升至90%。
免费试用14天,无需信用卡。