您的供应链管理数据模板
您的供应链管理数据模板
- 建议收集的属性
- 需要跟踪的关键活动
- 提取指南
供应链管理属性
| 名称 | 说明 | ||
|---|---|---|---|
| 事件时间 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公司Advanced Materials有限责任公司Precision Parts公司 | |||
| 客户名称 CustomerName | 订单履约对象的客户名称。 | ||
| 说明 此属性标识与销售订单及后续履约活动相关的最终客户,为供应链流程的需求侧提供背景信息。 在流程挖掘中,按客户分析有助于识别重点客户的不同履约模式或绩效水平。它可用于货物交付证明延迟分析等仪表板,以了解某些客户是否持续延迟确认。 为什么重要 支持按客户细分分析,揭示客户特有的行为、瓶颈或服务级别协议绩效。 获取位置 客户编号(KUNNR)存储在销售单据中(例如VBAK表)。客户名称从中央客户主数据表KNA1中获取。 示例 Retail公司Innovate SolutionsManufacturing Partners | |||
| 工厂 Plant | 活动发生的生产或配送设施。 | ||
| 说明 工厂是SAP中的组织单位,代表生产、存储或配送货物的地点,为流程活动提供地理或职能背景。 按工厂分析流程绩效是常见需求。它支持比较不同运营地点的效率、吞吐量和合规情况,从而识别最佳实践或需要改进的地点。 为什么重要 提供地理或组织维度,支持比较不同设施的绩效。 获取位置 可在许多单据项目表中找到,例如VBAP(销售)、EKPO(采购)和LIPS(交货)。字段通常命名为WERKS。 示例 100021003500 | |||
| 执行用户 ExecutingUser | 执行该活动人员的用户ID。 | ||
| 说明 此属性记录执行指定活动的员工SAP用户名或ID,例如创建采购订单或过账收货的员工,从而将流程步骤与相关人员关联起来。 按用户分析有助于了解工作负载分布、识别培训需求,以及发现个人或团队之间的绩效差异。它也有助于合规分析,了解关键流程步骤由谁执行。 为什么重要 将活动归属到具体用户,从而支持工作负载分析、绩效比较以及对不合规操作的调查。 获取位置 可在许多SAP表的“创建者”或“修改者”字段中找到,例如EKKO(PO抬头)中的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等表中的“In Progress”状态更新时间,结束时间可以取“Completed”状态更新时间。对于瞬时事件,EndTime可能等于StartTime。 示例 2023-04-15T11:30:00Z2023-04-18T14:05:00Z2023-04-22T09:00:00Z | |||
| 订单数量 OrderQuantity | 订单项目中物料的数量。 | ||
| 说明 此属性表示销售订单或采购订单项目中请求的物料单位数,为每笔交易提供数量规模信息。 按数量分析有助于优先关注高数量订单,因为这类订单可能产生更大的业务影响。它还可用于标准化其他指标,例如计算单位成本,或了解订单规模如何影响处理时间。 为什么重要 为交易提供数量背景,支持影响分析以及按规模细分案例。 获取位置 可在项目级表中找到,例如采购订单EKPO中的MENGE或销售订单VBAP中的KWMENG。 示例 100500025 | |||
| 采购订单编号 PurchaseOrderNumber | 采购订单(PO)单据的唯一标识符。 | ||
| 说明 采购订单编号是向供应商订购物料时使用的正式单据编号,是供应链采购环节的关键标识。 此属性支持深入分析采购流程,可用于采购端到端周期时间仪表板,并计算供应商准时交付率KPI,关联申请、下单、收货和付款活动。 为什么重要 作为深入分析采购子流程并关联相关采购事件的关键标识。 获取位置 可在PO抬头表EKKO和项目表EKPO中找到。字段名为EBELN。 示例 450007819245000781934500078194 | |||
| 销售订单编号 SalesOrderNumber | 销售订单(SO)单据的唯一标识符。 | ||
| 说明 销售订单编号是确认客户销售交易的正式单据编号,是供应链订单到现金环节的关键标识。 此属性对于跟踪特定客户订单的履约过程至关重要。它将客户最初的需求与后续交货、开票等活动关联起来,支持订单履约周期时间分析。 为什么重要 作为订单履约子流程的关键标识,将客户需求与物流和财务结算关联起来。 获取位置 可在SO抬头表VBAK和项目表VBAP中找到。字段名为VBELN。 示例 100023451000234610002347 | |||
供应链管理活动
| 活动 | 说明 | ||
|---|---|---|---|
| 确认货物交付证明 | 表示客户或承运商正式确认货物已按要求接收。通常通过更新出库交货单并录入POD信息来记录。 | ||
| 为什么重要 此活动标志着履约流程的确定性结束。它对于准确开票、争议解决以及衡量交付周期的最后环节至关重要。 获取位置 这是一个显式事件。货物交付证明日期记录在交货单抬头表(LIKP,字段PODAT)或相关POD表(VLPOD)中。 采集 使用交货单中的货物交付证明日期(LIKP-PODAT)。 事件类型 explicit | |||
| 货物已生产 | 此活动表示制造完成得到确认。通常通过生产订单收货进行记录,将成品转入库存。 | ||
| 为什么重要 这标志着生产周期结束。从生产订单创建到该事件之间的时间代表制造周期时间,是衡量生产效率的关键指标。 获取位置 您可以通过物料凭证过账明确捕获该事件,即生产订单收货;也可以根据生产订单的最终确认(AFRU表)或状态变更为“已交付”进行推断。 采集 根据生产订单最终收货物料凭证的过账日期或状态变更进行推断。 事件类型 inferred | |||
| 过账发货 | 此活动表示货物从仓库合法且实际地发出。它会减少库存并过账销售成本,标志着订单正式发运。 | ||
| 为什么重要 这是标志“运输中”阶段开始的重要里程碑,也是货物离开公司控制、开始交付的确定节点。 获取位置 这是创建物料凭证的显式事件。时间戳记录在物料凭证抬头(MKPF,字段BUDAT)中,并更新交货单据中的货物移动状态(LIKP,字段WBSTK)。 采集 使用与出库交货单关联的发货过账物料凭证中的过账日期(MKPF-BUDAT)。 事件类型 explicit | |||
| 采购订单已下达 | 表示向外部供应商正式创建并下达采购订单,以采购所需物料。此活动将采购申请转化为与供应商之间具有法律约束力的承诺。 | ||
| 为什么重要 作为关键里程碑,此活动对于衡量供应商周期时间和采购周期至关重要,也是评估供应商按时交付绩效的基准。 获取位置 这是创建采购订单时记录的明确事件。创建时间戳存储在采购订单抬头表(EKKO)的AEDAT字段中。 采集 采购订单使用文档创建日期(EKKO-AEDAT)。 事件类型 explicit | |||
| 采购订单收货已过账 | 表示根据采购订单从供应商处实际接收原材料或货物。当货物在仓库或工厂收货时,系统会记录此事件。 | ||
| 为什么重要 此活动完成采购周期中的供应商交付环节,对于计算供应商按时交付率和了解入库物流绩效至关重要。 获取位置 这是通过物料凭证过账捕获的明确事件。事件时间戳位于物料凭证抬头表(MKPF)的BUDAT字段中。采购订单关联信息位于项目表(MSEG)中。 采集 使用与采购订单关联的物料凭证中的过账日期(MKPF-BUDAT)。 事件类型 explicit | |||
| 销售订单已创建 | 此活动表示创建新的销售订单,用于正式记录客户对货物的需求。当用户在系统中保存新的销售订单文档时,系统会记录这一明确事件。 | ||
| 为什么重要 这是订单到现金流程的主要起点。分析该事件与其他事件之间的时间,可以了解整体订单履行周期,并识别初始处理延误。 获取位置 此事件会被明确记录。您可以在销售订单表的变更文档(CDHDR/CDPOS)中查找,也可以使用销售订单抬头表(VBAK)中的创建时间戳字段ERDAT。 采集 销售订单文档使用创建日期(VBAK-ERDAT)和时间(VBAK-ERZET)。 事件类型 explicit | |||
| 创建出库交货单 | 表示创建交货单据,该单据授权拣配并将货物运送给客户。此活动将流程从订单管理转入物流执行。 | ||
| 为什么重要 这是启动实物履约流程的关键步骤。订单创建与交货创建之间的延迟可能表明计划或可用性存在问题。 获取位置 这是一个显式事件。创建时间戳记录在交货单抬头表(LIKP,字段ERDAT)中。 采集 使用交货单抬头中的创建日期(LIKP-ERDAT)和时间(LIKP-ERZET)。 事件类型 explicit | |||
| 创建客户发票 | 此活动标志着根据已交付的货物或服务为客户创建开票单据,并启动流程中最终财务结算环节。 | ||
| 为什么重要 此活动对于分析开票周期时间至关重要。交付确认与开票之间的延迟可能对现金流产生不利影响。 获取位置 这是一个显式事件。创建时间戳记录在开票单据抬头表(VBRK,字段ERDAT)中。 采集 使用开票单据抬头中的创建日期(VBRK-ERDAT)。 事件类型 explicit | |||
| 创建装运单 | 表示创建装运单据,用于将一个或多个交货单归组,以便进行运输计划。该单据包含承运商、路线和运输方式等详细信息。 | ||
| 为什么重要 此活动标志着正式运输计划的开始。分析发货过账到装运完成之间的时间,可以了解运输流程的效率。 获取位置 这是记录在装运抬头表(VTTK,字段ERDAT)中的显式事件。该功能属于LE-TRA模块,并非所有组织都会使用。 采集 使用装运单据抬头中的创建日期(VTTK-ERDAT)。 事件类型 explicit | |||
| 完成拣配 | 此活动标志着为出库交货单从仓库拣取货物这一实物流程的完成。在许多系统中,当交货单的拣配状态更新后,即视为完成确认。 | ||
| 为什么重要 高效拣配对仓库吞吐量至关重要。跟踪此活动有助于识别仓库运营中的瓶颈并衡量拣配绩效。 获取位置 这通常不是单一的离散事件,而是可根据状态变化推断得出。当交货项目表(LIPS,字段KOSTA)中的拣配状态设为“C”(完全处理)时,即记录该事件。 采集 当拣配状态(LIPS-KOSTA)更新为完全拣配时,根据变更凭证推断该事件。 事件类型 inferred | |||
| 已执行质量检验 | 表示已完成对生产商品的质量控制检查。检查结果为合格或不合格,并记录在使用决策中。 | ||
| 为什么重要 此活动对于监控产品质量和识别生产问题至关重要。较高的拒收率或较长的检查时间可能构成重要瓶颈。 获取位置 这是在对质量检验批作出使用决策时记录的显式事件。决策日期位于QALS表(字段PASTRTERM)或QAVE表中。 采集 使用质量检验批记录使用决策时的时间戳(QALS/QAVE表)。 事件类型 explicit | |||
| 已检查库存可用性 | 表示系统或人工检查,用于确定请求的物料是否有库存以履行销售订单。这通常是创建销售订单时的自动步骤,但不一定会作为独立事件记录。 | ||
| 为什么重要 了解订单创建与库存检查之间的时间及检查结果,有助于分析库存水平如何影响履行周期。此处延误通常会引发采购或生产活动。 获取位置 这通常不是明确记录的事件。您可以根据销售订单项目表(VBEP)中首个确认计划行的创建情况,或订单项目中的状态变更进行推断。 采集 根据销售订单计划行(VBEP表)的确认状态更新进行推断。 事件类型 inferred | |||
| 生产订单已创建 | 表示已创建生产订单,用于制造销售订单所需的成品。这标志着内部生产流程正式开始。 | ||
| 为什么重要 创建生产订单标志着制造周期时间的开始。分析这一时间点,有助于识别需求信号与生产启动之间的延误。 获取位置 这是一个明确记录的事件。创建日期记录在生产订单抬头表(AUFK)的ERDAT字段中。 采集 使用订单抬头表中的创建日期(AUFK-ERDAT)。 事件类型 explicit | |||
| 货物在目的地卸载 | 此活动表示货物在客户所在地完成实物卸载。SAP中可能不会明确跟踪该事件,通常需要根据承运商数据或后续事件推断。 | ||
| 为什么重要 这标志着运输行程中在途环节的结束。从发货过账到此节点的时长即为运输时间,是物流优化的关键指标。 获取位置 这很少是核心ERP中的显式事件。可根据承运商EDI消息、Transportation Management(TM)模块数据,或可用时根据货物交付证明单据的时间戳推断。 采集 根据承运商状态更新(例如EDI 214)推断,或使用货物交付证明时间戳作为近似值。 事件类型 inferred | |||
| 采购申请已创建 | 此活动表示创建采购必要货物或原材料的内部申请。当库存不足以履行销售订单或低于补货点时,通常会触发该活动。 | ||
| 为什么重要 这是采购周期的第一步。跟踪其创建时间,有助于识别采购启动延误,并支持端到端采购流程分析。 获取位置 这是一个明确记录的事件。创建时间戳记录在采购申请抬头表(EBAN)的BADAT字段中。 采集 采购申请文档使用创建日期(EBAN-BADAT)。 事件类型 explicit | |||
提取指南
步骤
- 前提条件:确保您拥有具备足够权限的用户,可访问所需的SAP S/4HANA Core Data Services(CDS)视图。通常需要由SAP安全团队分配特定角色。您还需要DBeaver或SAP HANA Studio等可连接SAP HANA数据库的SQL客户端。
- 建立数据库连接:配置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 View的
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 View的复杂查询,执行可能消耗大量系统资源。请安排在非工作时间提取。对于超大数据集,可按月份拆分为较小的连续批次执行。
a 示例查询 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、质量、生产和开票数据可能存储在独立应用或扩展中。
- 安全性:遵循组织关于客户、供应商、物料、财务和用户数据的规定。必要时对敏感字段进行脱敏或限制访问。
a 示例查询 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。
a 示例查询 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天,无需信用卡。