您的库存管理数据模板
您的库存管理数据模板
- 建议收集的属性
- 流程发现需跟踪的关键活动
- 针对SAP S/4HANA的提取指南
库存管理属性
| 名称 | 说明 | ||
|---|---|---|---|
| 事件时间 EventTime | 库存活动在系统中记录的准确日期和时间。 | ||
| 说明 Event Time是记录活动确切发生时间的时间戳。该数据点对于按时间顺序排列事件、重建每个库存批次的流程顺序至关重要,也是所有基于时间的流程挖掘分析的基础。 Event Time的准确性对于计算周期时间、交付周期和持续时间等关键绩效指标至关重要。它支持分析不同时间段的流程绩效,帮助识别瓶颈出现的时间,并为理解流程延误提供事实依据,例如批次在质量检查中等待释放所花费的时间。 为什么重要 该时间戳按时间顺序排列事件,是所有时长和绩效计算的基础。 获取位置 通常由物料凭证抬头表MKPF中的过账日期(MKPF-BUDAT)和录入时间(MKPF-CPUTM)组合而成。 示例 2023-10-26T09:00:00Z2023-11-15T14:35:10Z2024-01-05T23:15:00Z | |||
| 库存批次或批号 InventoryBatchLot | 用于跟踪产品生命周期的特定数量产品的唯一标识符,也是案例ID。 | ||
| 说明 库存批次或批号是主要案例标识符,用于汇总与特定产品数量相关的所有活动。借助该标识符,您可以完整、按时间顺序查看一批库存从最初入库,到经历各种内部移动和状态变化,再到最终用于销售、生产或处置的全过程。 在流程分析中,该属性至关重要。它支持您跟踪每个批次的端到端流程、准确衡量周期时间、识别流程差异,并了解不同批次的处理方式。对于制药、食品饮料和化工等高度依赖可追溯性、质量控制和有效期管理的行业,按批次分析流程尤为重要。 为什么重要 这是将所有相关库存事件连接到同一案例的核心标识符,使端到端流程分析成为可能。 获取位置 通常为批次号,可在SAP的MCHA(批次主数据)或MCH1(批次)表的CHARG字段中找到。 示例 B001-A452023L202405-XYZ789456123BATCH-05-24 | |||
| 活动 ActivityName | 库存管理流程中特定时间点发生的业务事件名称。 | ||
| 说明 Activity属性描述批次库存生命周期中的单个步骤或事件。这些事件代表收货、移动库存、执行质量检查或发料等关键业务操作。每项活动都是库存批次在特定时间点发生某项变化的记录。 活动分析是流程挖掘的基础。它支持可视化流程顺序、识别常见和少见路径、发现活动延迟造成的瓶颈,以及分析返工循环。了解“Stock Scrapped”或“Quality Inspection”等活动的顺序和频率后,企业可以准确定位流程改进和运营效率提升的方向。 为什么重要 它定义流程中的步骤,从而支持库存生命周期的可视化与分析。 获取位置 这是一个派生属性,通常根据SAP移动类型(MSEG-BWART)或事务代码(MKPF-TCODE2)映射为便于用户理解的名称。 示例 已过账收货已过账上架转储交货发货已过账库存已报废 | |||
| 存储地点 StorageLocation | 工厂内实际存放库存的具体位置。 | ||
| 说明 Storage Location是用于区分工厂内物料库存的组织单位。例如,一个工厂可能为原材料、成品和质量检验库存设置不同的存储地点。 与Plant相比,该属性提供更细粒度的位置信息。它用于分析不同库存区域之间的移动,例如从收货区转移到主仓库所需的周期时间。按存储地点分析空间利用率和移动频率,有助于优化仓库布局和内部物流。 为什么重要 它提供工厂内库存位置的细粒度视图,有助于分析内部移动和存储效率。 获取位置 位于物料凭证项目表MSEG的LGORT字段(存储地点)中。 示例 0001RM01FG01QI01 | |||
| 工厂 Plant | 代表库存所在设施的组织单位,例如工厂或配送中心。 | ||
| 说明 Plant是SAP中的核心组织单位,可代表生产设施、中央存储地点或企业总部。所有库存都在物理或逻辑上归属于某个Plant。 按Plant分析对于比较不同地点的流程绩效至关重要。它有助于回答以下问题:“哪个工厂的上架周期时间最长?”或“工厂A的库存差异率是否高于工厂B?”这种地理或组织维度的细分,是识别地点特定问题并在组织内共享最佳实践的关键。 为什么重要 它支持比较公司不同地点的库存流程和绩效。 获取位置 位于物料凭证项目表MSEG的WERKS字段(工厂)中。 示例 10001710DE01US01 | |||
| 库存移动原因代码 MovementReasonCode | 用于说明库存移动原因的代码。 | ||
| 说明 移动原因代码为货物移动的执行原因提供更多背景,通常用于解释库存调整、退货或报废等非计划移动。 该属性对于根因分析非常有价值。在“手动库存调整驱动因素”仪表板中,按原因代码分析可以揭示差异产生的原因,例如损坏、盗窃或数据录入错误。这些洞察有助于企业解决根本问题,而不仅仅是纠正表面现象。 为什么重要 它解释非计划库存移动背后的原因,支持有针对性的根因分析。 获取位置 位于物料凭证项目表MSEG的GRUND字段(移动原因)中。 示例 00010005102 | |||
| 数量 Quantity | 库存移动涉及的物料数量。 | ||
| 说明 该属性表示在某项活动中移动、接收、发出或调整的物料数量,按物料的基本计量单位记录。 分析数量对于了解库存流程的规模和影响至关重要。它支持创建可视化货物处理量的仪表板,例如“按SKU统计的发货吞吐量”。它还用于计算“库存报废或处置率”等KPI,为流程分析提供超越事件计数的数量维度。 为什么重要 它量化每项活动中的物料数量,支持分析吞吐量、报废量和调整影响。 获取位置 位于物料凭证项目表MSEG的MENGE字段(数量)中。 示例 10012.55000-10 | |||
| 物料号 MaterialNumber | 所管理产品或物料的唯一标识符。 | ||
| 说明 物料号通常也称为SKU(库存保有单位),是分配给特定产品的唯一代码。它是库存管理中的基础主数据元素,用于跟踪货物的数量、价值和移动。 在流程挖掘中,按物料号分析可以从产品视角查看库存流程。它有助于回答以下问题:哪些产品的质量检验时间最长,哪些产品最常被报废,哪些产品的内部转移量最高。按此维度细分,对于识别特定产品的问题、优化不同类型货物的库存策略至关重要。 为什么重要 它支持按产品细分分析,揭示特定物料的模式和问题。 获取位置 位于物料凭证项目表MSEG的MATNR字段中。主数据位于MARA表。 示例 RM-1001FG-2050-B100-400-A | |||
| 用户名 UserName | 在SAP中执行交易的人员的用户ID。 | ||
| 说明 该属性记录过账凭证或执行活动的员工SAP用户ID,通过显示具体操作负责人,为库存管理流程提供可追溯性。 按用户分析对于了解绩效、合规和培训需求至关重要。例如,“手动库存调整驱动因素”仪表板使用该属性识别执行调整最多的人员。它有助于发现需要额外培训的用户、识别未经授权的活动,或表彰表现优秀的人员。 为什么重要 它明确责任归属,并帮助识别特定用户的行为、培训需求或合规问题。 获取位置 位于物料凭证抬头表MKPF的USNAM字段(用户名)中。 示例 JSMITHMBROWNWAREHOUSE_OPS | |||
| 移动类型 MovementType | SAP中的三位数代码,用于控制货物移动的过账方式。 | ||
| 说明 移动类型是SAP库存管理中的关键控制代码,用于确定物料移动的特征。它规定更新哪些科目、交易界面如何显示,以及更新哪些数量或价值字段。例如,“101”表示收货,“311”表示转储过账,“551”表示报废。 该属性通常用于派生便于用户理解的Activity名称。按移动类型分析流程,可以从技术层面详细了解库存流动情况。它对于验证流程图准确性,以及识别可能导致瓶颈或偏差的特定交易类型至关重要。 为什么重要 它为每个库存事件提供精确的技术分类,对于派生活动和开展详细分析至关重要。 获取位置 位于物料凭证项目表MSEG的BWART字段(移动类型)中。 示例 101311261551601 | |||
| 最近数据更新时间 LastDataUpdate | 表示该记录数据最近一次从源系统刷新时间的时间戳。 | ||
| 说明 该属性记录最近一次从源系统提取或更新数据的日期和时间,提供有关分析信息新鲜度的重要元数据。它帮助用户判断当前查看的是近实时数据,还是上一时段的快照。 在任何分析中,了解数据时效性都是得出相关且准确结论的关键。该字段使分析人员和业务用户能够确认数据是否为最新,通常也会显示在仪表板中,为呈现的洞察提供背景。 为什么重要 它告知用户数据的新鲜度,确保分析基于最新信息。 获取位置 该时间戳在数据提取、转换和加载(ETL)过程中生成并添加。 示例 2024-05-21T08:00:00Z2024-05-20T08:00:00Z | |||
| 存储箱位 StorageBin | 仓库中最细粒度的存储单元,物料实际存放于此。 | ||
| 说明 Storage Bin代表仓库中的具体坐标,例如货架位置。通常在实施SAP Warehouse Management(WM)或Extended Warehouse Management(EWM)时使用这一层级的信息。 对于“仓库存储利用率”仪表板,该属性至关重要。它支持分析仓库空间使用效率、识别潜在拥堵热点,并发现低效的上架或拣配路径。分析存储箱位之间的移动,有助于优化仓库布局并减少操作人员的行走时间。 为什么重要 它提供最细粒度的位置数据,支持分析仓库空间利用率和运营效率。 获取位置 如果使用WM,可在LTAK/LTAP等Transfer Order表中找到。对于库存凭证,可能位于MSEG-LGPBE。请参阅SAP S/4HANA文档。 示例 A-01-01-AB-05-10-CRCV-AREA-01 | |||
| 库存类型 StockType | 表示库存状态,例如非限制使用、质量检验中或冻结。 | ||
| 说明 Stock Type根据库存可用性对库存进行分类。主要类型包括非限制使用库存(可自由使用)、质量检验库存(等待质量检查)和冻结库存(不可使用)。货物移动通常会涉及库存类型变化。 跟踪库存类型变化是理解库存可用性流程的基础,也直接支持“库存已过账至质量检验”和“库存状态已更改为冻结”等活动。分析库存处于每种类型的时间,尤其是处于“质量检验”状态的时间,是识别影响货物销售或生产可用性的延误的关键。 为什么重要 它跟踪库存的可用性状态,对于分析质量检验延误和库存可用性至关重要。 获取位置 位于物料凭证项目表MSEG的INSMK字段(库存类型)中。 示例 非限制使用质量检验冻结库存 | |||
| 有效期 ExpirationDate | 物料批次到期且不再可用的日期。 | ||
| 说明 保质期到期日(SLED)是易腐或有时效性货物的关键主数据。它按批次管理,并决定产品何时不得再销售或使用。 该属性对于“过时和过期库存分析”仪表板至关重要。结合有效期分析活动,企业可以识别即将过期的批次并采取主动措施。它有助于衡量先进先出策略(FEFO)的执行效果,并量化过期库存报废造成的损失。 为什么重要 它支持分析过时和过期库存,帮助减少浪费和财务损失。 获取位置 位于批次主数据表MCH1或MCHA的VFDAT字段(保质期到期日)中。 示例 2024-12-312025-06-302024-09-01 | |||
| 源系统 SourceSystem | 标识提取数据的源系统。 | ||
| 说明 该属性指定库存管理数据来源的记录系统。在此场景中,通常是特定的SAP S/4HANA实例。当数据来自多个ERP、仓库管理系统或遗留平台时,这一信息尤为重要。 在单系统分析中,它看似固定不变;但在合并不同来源的数据、构建全局流程视图时,它至关重要。它有助于数据治理、排查数据提取问题,并确保数据血缘清晰。 为什么重要 它提供数据来源背景,对于数据治理和多系统分析不可或缺。 获取位置 通常是在数据转换过程中硬编码的值,用于标识特定的SAP S/4HANA实例。 示例 S4H_PROD_100SAP_S4_FINANCES4HANA_GLOBAL | |||
| 物料凭证编号 MaterialDocumentNumber | 用于标识记录货物移动的物料凭证的唯一编号。 | ||
| 说明 在SAP中过账货物移动时,系统会生成物料凭证,作为移动凭据。该属性是该凭证的唯一标识符。一张物料凭证可以包含多个项目或活动。 在流程挖掘中,物料凭证编号是关键交易标识符,可用于汇总一同过账的相关事件。它对于审计也十分重要,并支持从流程分析下钻到源系统,调查具体交易。 为什么重要 它作为交易键用于审计,并支持汇总一同执行的活动。 获取位置 位于MKPF(抬头)和MSEG(项目)表的MBLNR字段(物料凭证编号)中。 示例 490000123450000056784900002345 | |||
| 计量单位 UnitOfMeasure | 用于计量物料数量的单位,例如件、千克。 | ||
| 说明 Unit of Measure指定Quantity属性所使用的单位。常见示例包括件(PC)、千克(KG)、升(L)或箱(BOX),为数量字段提供必要背景。 虽然它通常只是一个简单描述,但在确保数据质量以及需要将不同单位转换为统一标准的分析中,该属性十分重要。例如,要准确计算报废库存的总价值,必须明确不同单位的含义,并在必要时进行换算。 为什么重要 它为Quantity属性提供必要背景,确保能够准确理解物料数量。 获取位置 位于物料凭证项目表MSEG的MEINS字段(基本计量单位)中。 示例 PCKGEAM | |||
| 订单履行周期时间 OrderFulfillmentCycleTime | 从开始拣配到为交货过账发货的端到端持续时间。 | ||
| 说明 这是一个计算指标,用于衡量从“拣配已启动”到“交货发货已过账”的总时间。它表示流程开始后,仓库准备并发运客户订单所需的总时间。 该属性直接衡量“订单履行周期时间”KPI。分析这一时长有助于企业了解响应客户需求的速度。您可以按产品、仓库或客户拆分分析,以识别拣配、包装和发运流程中的延误位置,这些延误会直接影响客户满意度和物流效率。 为什么重要 它衡量仓库出库流程的速度和效率,是影响客户满意度的关键因素。 获取位置 这是一个计算属性,针对每个批次,通过计算“Picking Initiated”和“Goods Issue for Delivery Posted”事件之间的时间差得出。 示例 7200144003600 | |||
库存管理活动
| 活动 | 说明 | ||
|---|---|---|---|
| 交货发货已过账 | 记录出库流程的最后一步,此时批次所有权转移给客户或承运商。这是一项会减少库存并过账至会计系统的明确交易。 | ||
| 为什么重要 这是订单履行流程的关键完成事件,对于衡量准时交付和计算整体订单履行周期时间至关重要。 获取位置 记录在MATDOC表中。通过销售订单交货发货对应的移动类型(BWART)识别,通常为601。 采集 从MATDOC中的物料凭证提取,移动类型为601。 事件类型 explicit | |||
| 已过账上架转储 | 表示批次从收货区或暂存区转移到最终存储位置或存储箱位的实际移动。该操作在SAP中记录为转储过账物料凭证。 | ||
| 为什么重要 完成入库收货流程。完成该活动所需的时间称为上架时间,是衡量仓库效率的关键KPI。 获取位置 在MATDOC表中记录为转储过账,通常发生在不同存储地点之间,例如存储地点转移使用移动类型311。具体移动方式可能因仓库结构而异。 采集 通过MATDOC中的转储过账凭证识别,这些凭证将库存从临时或收货存储地点转移到最终存储地点。 事件类型 explicit | |||
| 已过账收货 | 标志着库存批次首次进入仓库,通常来自供应商或生产环节。收货时会创建物料凭证,因此该事件会在SAP S/4HANA中明确记录。 | ||
| 为什么重要 这是库存生命周期的主要开始事件。分析该活动与上架等其他活动之间的时间,对于衡量收货月台效率至关重要。 获取位置 记录在MATDOC表中。通过特定移动类型(BWART)识别,例如采购订单收货使用101,或将收货记入冻结库存使用103。 采集 从MATDOC中的物料凭证及对应的收货移动类型中获取。 事件类型 explicit | |||
| 库存已报废 | 标志库存批次最终处置,并将其永久移出库存记录。通常适用于过期、损坏或过时库存。 | ||
| 为什么重要 这是代表财务损失的结束事件。分析报废事件有助于识别库存老化、搬运流程或需求预测方面的问题。 获取位置 记录在MATDOC表中。通过报废移动类型(BWART)识别,例如551(从非限制使用库存报废)、553(从质量检验库存报废)或555(从冻结库存报废)。 采集 从MATDOC中的物料凭证提取,使用报废移动类型,例如551。 事件类型 explicit | |||
| 库存调整已过账 | 记录因实物盘点或其他差异导致的库存数量变化。该事件会明确调整账面库存,使其与实物盘点结果一致。 | ||
| 为什么重要 这些调整对于保持库存准确性至关重要。调整频繁发生,通常表明库存搬运、安全管理或数据录入存在根本问题。 获取位置 记录在MATDOC表中。通过实物盘点移动类型(BWART)识别,例如701(盘盈)或702(盘亏)。 采集 从MATDOC中的物料凭证提取,使用实物盘点调整移动类型,例如701、702。 事件类型 explicit | |||
| 生产发货已过账 | 表示生产订单或工艺订单消耗库存批次。该交易会减少库存,并将物料成本分配至制造订单。 | ||
| 为什么重要 这是主要的消耗事件,标志着组件库存生命周期结束。对于分析生产物料可用性和消耗模式至关重要。 获取位置 记录在MATDOC表中。通过订单发货对应的移动类型(BWART)识别,例如261。 采集 从MATDOC中的物料凭证提取,移动类型为261。 事件类型 explicit | |||
| 质量检验库存已放行 | 表示批次已通过质量检验,现在可以使用或上架。该事件记录为从质量检验库存转移至其他库存类型的转储过账,例如非限制使用库存。 | ||
| 为什么重要 这一里程碑标志着质量流程完成,库存正式可用。此处延迟可能对生产或订单履行造成严重的后续影响。 获取位置 记录在MATDOC表中,形式为转储过账。通常通过移动类型(BWART)321识别,即将库存从“Quality Inspection”转移至“Unrestricted-use”。 采集 从MATDOC中的物料凭证获取,移动类型为321。 事件类型 explicit | |||
| 内部库存转移已过账 | 记录同一工厂内库存批次在不同存储地点或存储箱位之间的移动。这是一项会生成物料凭证的明确交易。 | ||
| 为什么重要 跟踪内部转移有助于分析仓库运营效率、识别不必要的移动,并衡量不同存储地点之间的库存补货周期时间。 获取位置 记录在MATDOC表中。存储地点之间的转移通常通过移动类型(BWART)311识别。 采集 从MATDOC中的物料凭证提取,使用内部库存移动类型,例如311。 事件类型 explicit | |||
| 已收到销售退货 | 记录此前发出的批次从客户退回仓库。这是一项会增加库存的明确交易。 | ||
| 为什么重要 跟踪退货对于了解产品质量问题和客户不满至关重要。退货处理和处置流程也可能成为效率低下的来源。 获取位置 记录在MATDOC表中。通过销售退货移动类型(BWART)识别,例如651(转为非限制使用)或653(转为质量检验)。 采集 从MATDOC中的物料凭证提取,使用销售退货移动类型,例如651、653。 事件类型 explicit | |||
| 已过账至质量检验库存 | 表示将已收货批次转入质量检验暂存状态,在检验通过前无法使用。这是SAP中的明确交易,会改变该批次的库存类型。 | ||
| 为什么重要 该活动启动质量检验流程。从此活动到质量检验放行之间的时长,是了解质量相关延迟的关键指标。 获取位置 记录在MATDOC表中。可以是库存类型(INSMK)设为“Q”(Quality Inspection)的收货移动,例如101,也可以是转储过账,例如322。 采集 通过MATDOC中将库存置于“Quality Inspection”库存类型的物料凭证识别。 事件类型 explicit | |||
| 库存状态已更改为冻结 | 表示批次状态发生变化,使其无法发料,通常由损坏、冻结申请或其他原因导致。这是SAP中的一项明确转储过账。 | ||
| 为什么重要 突出显示库存可用性中断。冻结事件频繁发生,可能表明搬运、存储条件或供应商质量存在问题。 获取位置 在MATDOC表中记录为转储过账。移动类型(BWART)344通常用于将库存从“冻结”转为“非限制使用”,343用于从“非限制使用”转为“冻结”。本活动对应343。 采集 通过MATDOC中移动类型为343的物料凭证识别。 事件类型 explicit | |||
| 库存状态已更改为非限制使用 | 表示批次状态发生变化,从冻结或质量冻结状态中释放,使其可供使用。该操作记录为明确的转储过账。 | ||
| 为什么重要 该活动标志着库存冻结的解除。分析库存处于冻结状态的时间,有助于改进问题解决流程。 获取位置 在MATDOC表中记录为转储过账。移动类型(BWART)344用于将库存从“冻结”转为“非限制使用”。 采集 通过MATDOC中移动类型为344的物料凭证识别。 事件类型 explicit | |||
| 批次状态已更改 | 反映批次主数据记录发生变化,例如将状态从“非限制使用”改为“受限”。这不是物料移动,而是对主数据的更改,并会被记录。 | ||
| 为什么重要 批次状态变化会直接影响其在销售或生产中的可用性。分析这些变化,可以发现与库存过期或质量控制有关、但不涉及实际移动的问题。 获取位置 根据批次主数据表(MCH1、MCHA)的更改日志推断。CDHDR和CDPOS表记录批次状态字段(MCH1-ZUSTD)的变化。 采集 根据CDHDR/CDPOS中批次主数据记录状态字段(MCH1-ZUSTD)的更改凭证推导。 事件类型 inferred | |||
| 拣配已启动 | 标志订单履行流程开始,仓库会创建仓库任务,从存储箱位拣取指定批次。通常在创建Transfer Order或Warehouse Task时记录。 | ||
| 为什么重要 该活动是拣配流程的触发点。分析从此事件到拣配完成的时间,有助于衡量仓库操作人员效率并识别延误。 获取位置 通常不记录在MATDOC中。在使用Warehouse Management(WM/EWM)的系统中,可根据Transfer Order(LTAK表)或Warehouse Task的创建时间戳推断。 采集 根据与物料批次关联的Transfer Order(WM中)或Warehouse Task(EWM中)的创建记录推断。 事件类型 inferred | |||
提取指南
步骤
- 建立系统访问权限:确保您拥有具备必要授权的用户,可查询SAP S/4HANA系统中的Core Data Services(CDS)视图。通常需要由系统管理员授予访问权限。
- 选择SQL客户端:选择可连接SAP HANA数据库的SQL客户端工具。常用工具包括SAP HANA Studio、SAP HANA Database Explorer,以及DBeaver等第三方工具。
- 配置数据库连接:使用SQL客户端创建新的数据库连接。您需要HANA数据库主机名、端口号(通常为3<instance_number>15)以及数据库用户凭据。
- 准备SQL查询:将本文档“query”部分提供的完整SQL查询复制到SQL客户端编辑器中。
- 设置查询参数:找到查询中的占位值。您必须将
I_MaterialDocumentItem.PostingDate BETWEEN 'YYYYMMDD' AND 'YYYYMMDD'替换为所需日期范围,例如BETWEEN '20230101' AND '20230630'。同时更新公司或工厂专用筛选条件,例如将MaterialDocumentItem.Plant IN ('Plant1', 'Plant2')调整为符合组织结构的值。 - 执行查询:在S/4HANA数据库中运行修改后的SQL查询。执行时间取决于日期范围以及系统中的库存数据量。
- 检查数据:查询完成后,在SQL客户端中检查结果,确保数据正确且完整。确认包含不同活动,并检查关键属性是否已填充。
- 导出事件日志:将完整结果集从SQL客户端导出为CSV文件。请确保导出设置使用UTF-8编码,避免出现字符问题。
- 准备上传:CSV文件中的列名必须与查询中的别名完全一致,例如
InventoryBatchLot、ActivityName、EventTime等。现在即可将该文件上传到流程挖掘工具。
配置
- 授权:运行查询的用户需要对以下CDS View拥有
SELECT权限:I_MaterialDocumentItem、I_BatchChangeDocument和I_WarehouseTask。同时还需要访问这些视图所在底层数据库架构的权限。 - 日期范围筛选:必须对
PostingDate、ChangeDocumentCreationDate或WarehouseTaskCreationDate字段应用日期范围筛选。典型分析范围为3至12个月。查询多年数据可能导致严重的性能问题。 - 组织筛选:为提升性能并聚焦分析范围,请添加
WHERE子句,按Plant或CompanyCode筛选。这可以减少数据量,将提取范围限定在相关业务部分。 - 数据量:请注意,库存管理系统会生成大量数据。较大的日期范围可能产生数百万行数据,进而影响提取期间源系统以及客户端工具的性能。
- Extended Warehouse Management(EWM):“Picking Initiated”活动依赖
I_WarehouseTaskCDS View,只有在使用SAP Extended Warehouse Management时才会填充。如果您的组织使用较旧的Warehouse Management(WM)模块,或仅使用Inventory Management(IM),则不会提取此活动。
a 示例查询 sql
SELECT
mat_doc.Batch AS "InventoryBatchLot",
CASE
WHEN mat_doc.MovementType = '101' AND mat_doc.InventoryStockType = '2' THEN 'Stock Posted to Quality Inspection'
WHEN mat_doc.MovementType = '101' THEN 'Goods Receipt Posted'
WHEN mat_doc.MovementType = '321' THEN 'Quality Inspection Stock Released'
WHEN mat_doc.MovementType = '311' THEN 'Internal Stock Transfer Posted'
WHEN mat_doc.MovementType = '344' THEN 'Stock Status Changed to Blocked'
WHEN mat_doc.MovementType IN ('343', '322') THEN 'Stock Status Changed to Unrestricted'
WHEN mat_doc.MovementType IN ('701', '702') THEN 'Inventory Adjustment Posted'
WHEN mat_doc.MovementType = '601' THEN 'Goods Issue for Delivery Posted'
WHEN mat_doc.MovementType = '261' THEN 'Goods Issue for Production Posted'
WHEN mat_doc.MovementType IN ('651', '653') THEN 'Sales Return Received'
WHEN mat_doc.MovementType = '551' THEN 'Stock Scrapped'
WHEN mat_doc.MovementType = '313' THEN 'Put-Away Transfer Posted' -- Example for two-step transfers
ELSE 'Unknown Material Movement'
END AS "ActivityName",
TO_TIMESTAMP(mat_doc.PostingDate || LPAD(mat_doc.CreationTime, 6, '0'), 'YYYYMMDDHH24MISS') AS "EventTime",
mat_doc.Material AS "MaterialNumber",
mat_doc.CreatedByUser AS "UserName",
mat_doc.MovementType AS "MovementType",
mat_doc.Plant AS "Plant",
mat_doc.StorageLocation AS "StorageLocation",
mat_doc.QuantityInEntryUnit AS "Quantity",
mat_doc.ReasonForMovement AS "MovementReasonCode"
FROM
I_MaterialDocumentItem AS mat_doc
WHERE
mat_doc.Batch IS NOT NULL AND mat_doc.Batch <> ''
AND mat_doc.PostingDate BETWEEN '20230101' AND '20231231' -- Placeholder: Set your date range
-- AND mat_doc.Plant IN ('Plant1', 'Plant2') -- Placeholder: Add filters for relevant plants
UNION ALL
SELECT
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 3) AS "InventoryBatchLot",
'Batch Status Changed' AS "ActivityName",
change_doc.ChangeDocumentCreationDateTime AS "EventTime",
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 1) AS "MaterialNumber",
change_doc.ChangedByUser AS "UserName",
NULL AS "MovementType",
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 2) AS "Plant",
NULL AS "StorageLocation",
NULL AS "Quantity",
NULL AS "MovementReasonCode"
FROM
I_BatchChangeDocument AS change_doc
WHERE
change_doc.ChangeDocumentTable = 'MCHA' AND change_doc.ChangeDocumentTableFieldName = 'ZUSTD'
AND TO_VARCHAR(change_doc.ChangeDocumentCreationDate) BETWEEN '20230101' AND '20231231' -- Placeholder: Set your date range
UNION ALL
SELECT
wh_task.Batch AS "InventoryBatchLot",
'Picking Initiated' AS "ActivityName",
wh_task.WarehouseTaskCreationDateTime AS "EventTime",
wh_task.Product AS "MaterialNumber",
wh_task.CreatedByUser AS "UserName",
NULL AS "MovementType",
wh_task.Plant AS "Plant",
wh_task.SourceStorageLocation AS "StorageLocation",
wh_task.TargetQuantity AS "Quantity",
NULL AS "MovementReasonCode"
FROM
I_WarehouseTask AS wh_task
WHERE
wh_task.Batch IS NOT NULL AND wh_task.Batch <> ''
AND wh_task.WarehouseProcessType IN ('P210', 'P220') -- Placeholder: Adjust process types based on your picking configuration
AND TO_VARCHAR(wh_task.WarehouseTaskCreationDate) BETWEEN '20230101' AND '20231231'; -- Placeholder: Set your date range 步骤
- 确认已批准直接访问SAP HANA SQL,并确认提取用户拥有访问MATDOC及系统所需批次主数据表的读取权限。确认物理架构所有者,并将[您的SAP HANA架构]替换为获批的架构名称。
- 确认目标SAP S/4HANA版本中可用的MATDOC和批次表字段。以下查询使用常见的MATDOC字段和MCHA字段,但字段可用性和命名可能因版本、部署方式及启用范围而异。执行前请替换所有标记为[根据您的系统配置]的字段。
- 将[开始时间戳]和[结束时间戳]替换为ISO时间戳值,定义提取期间。首次提取建议使用三至六个月的数据,验证数据量和性能后再延长期间。
- 在获批的SQL客户端、SAP HANA Database Explorer或其他经授权的数据库工具中执行查询。替换相应筛选占位符,按需将结果限制为指定公司代码、工厂、凭证类型或移动类型。
- 检查活动CTE中的移动类型映射。移动类型取决于系统和业务配置。将示例移动类型列表替换为目标系统中为收货、质量检验、放行、上架、内部调拨、冻结库存、非限制库存、库存调整、拣货、交货发料、生产发料、销售退货和报废配置的移动类型。
- 验证每个输出行都包含InventoryBatchLot、ActivityName和EventTime。确认批次标识符足够稳定,可以作为ProcessMind案例标识符。如果业务场景需要通过物料、工厂或存储地点区分不同组织单元中的相同批次值,请使用已配置的组合案例标识符,而不要单独使用批次值。
- 验证事件顺序、重复行、冲销凭证、已取消凭证和时区处理。MATDOC记录凭证过账,因此除非明确排除或映射,冲销和取消记录可能作为单独事件出现。
- 将查询结果导出为扁平文件,每行一个事件,并包含InventoryBatchLot、ActivityName、EventTime、MaterialNumber、UserName、MovementType、Plant、StorageLocation、Quantity和MovementReasonCode列。以一致的ISO 8601格式保留时间戳,并保留物料、批次、工厂和存储地点值中的前导零。
- 将生成的事件日志上传至ProcessMind,并将InventoryBatchLot映射为案例标识符,ActivityName映射为活动,EventTime映射为事件时间戳。不要依赖ProcessMind推断活动、合并记录或生成缺失事件。
配置
- 提取方式:直接对SAP HANA库存和批次数据执行SQL查询。查询读取MATDOC,并从MCHA连接批次主数据。只有在确认目标系统中的相关字段和批次层级后,才添加MCH1或其他批次表。
- 日期范围:先使用三至六个月。根据MATDOC中可用的物料凭证过账日期和时间设置EventTime。增量加载时,使用受控的重叠时间窗口捕获延迟过账,然后根据已配置的凭证和项目标识去重。
- 必要筛选:根据流程范围配置公司代码、工厂、物料凭证类型、移动类型、批次存在性和过账日期。添加公司代码和凭证类型字段前,必须确认已安装版本支持这些字段。
- 活动映射:移动类型含义取决于配置。请维护经批准的映射表,或将查询中的移动类型列表替换为业务实际使用的值。不要将示例列表视为SAP通用语义。
- 批次范围:由于案例标识为InventoryBatchLot,查询会排除没有批次值的行。如果需要从其他来源推导批次,请在提取前明确配置该来源。
- 事件粒度:每个符合条件的MATDOC项目输出一行事件记录。查询不会根据后续记录推断拣货、质量决策、批次状态变更或其他活动。
- 批次主数据变更:仅依靠MATDOC无法可靠表示批次状态变更。请为Batch Status Changed活动配置变更凭证或批次历史来源。查询包含一个占位分支,执行前必须将其连接到经过验证的数据源。
- 拣货:拣货启动通常属于仓库执行数据,而不是MATDOC过账数据。请配置经过验证的仓库任务或转储订单来源,并在执行前替换占位分支。
- 性能:按过账时间戳或过账日期、工厂、公司代码和相关移动类型筛选。仅选择所需列,避免不受限的历史数据扫描,并在批准的工作时段执行。对于大型MATDOC数据量,建议采用分区或增量提取。
- 授权和前提条件:获取经批准的数据库连接、架构访问权限、读取授权、SAP S/4HANA库存数据访问权限,以及所使用的仓库执行或变更历史数据源的访问权限。确认直接数据库访问符合组织的SAP运营模式和支持政策。
- 时区:确认数据库和应用程序时区。在上传至ProcessMind前,统一转换EventTime。
- 数据保护:按照组织要求,对用户ID、物料数据、客户相关数据和数据库凭据实施控制。不要将凭据写入查询文本。
a 示例查询 sql
WITH
params AS (
SELECT
TO_TIMESTAMP('[Start timestamp]') AS start_ts,
TO_TIMESTAMP('[End timestamp]') AS end_ts
FROM DUMMY
),
movement_map AS (
SELECT '101' AS movement_type, 'Goods Receipt Posted' AS activity_name FROM DUMMY
UNION ALL SELECT '105', 'Goods Receipt Posted' FROM DUMMY
UNION ALL SELECT '107', 'Goods Receipt Posted' FROM DUMMY
UNION ALL SELECT '109', 'Goods Receipt Posted' FROM DUMMY
UNION ALL SELECT '321', 'Stock Posted to Quality Inspection' FROM DUMMY
UNION ALL SELECT '322', 'Quality Inspection Stock Released' FROM DUMMY
UNION ALL SELECT '343', 'Stock Status Changed to Unrestricted' FROM DUMMY
UNION ALL SELECT '344', 'Stock Status Changed to Blocked' FROM DUMMY
UNION ALL SELECT '311', 'Internal Stock Transfer Posted' FROM DUMMY
UNION ALL SELECT '309', 'Internal Stock Transfer Posted' FROM DUMMY
UNION ALL SELECT '301', 'Internal Stock Transfer Posted' FROM DUMMY
UNION ALL SELECT '311', 'Put-Away Transfer Posted' FROM DUMMY
UNION ALL SELECT '309', 'Put-Away Transfer Posted' FROM DUMMY
UNION ALL SELECT '701', 'Inventory Adjustment Posted' FROM DUMMY
UNION ALL SELECT '702', 'Inventory Adjustment Posted' FROM DUMMY
UNION ALL SELECT '703', 'Inventory Adjustment Posted' FROM DUMMY
UNION ALL SELECT '704', 'Inventory Adjustment Posted' FROM DUMMY
UNION ALL SELECT '705', 'Inventory Adjustment Posted' FROM DUMMY
UNION ALL SELECT '706', 'Inventory Adjustment Posted' FROM DUMMY
UNION ALL SELECT '601', 'Goods Issue for Delivery Posted' FROM DUMMY
UNION ALL SELECT '602', 'Goods Issue for Delivery Posted' FROM DUMMY
UNION ALL SELECT '261', 'Goods Issue for Production Posted' FROM DUMMY
UNION ALL SELECT '262', 'Goods Issue for Production Posted' FROM DUMMY
UNION ALL SELECT '651', 'Sales Return Received' FROM DUMMY
UNION ALL SELECT '653', 'Sales Return Received' FROM DUMMY
UNION ALL SELECT '654', 'Sales Return Received' FROM DUMMY
UNION ALL SELECT '551', 'Stock Scrapped' FROM DUMMY
UNION ALL SELECT '552', 'Stock Scrapped' FROM DUMMY
),
matdoc_events AS (
SELECT
m.MATNR AS MaterialNumber,
m.CHARG AS InventoryBatchLot,
COALESCE(m.BUDAT_MKPF, m.BUDAT) AS EventTime,
CAST(NULL AS NVARCHAR(80)) AS UserName,
CAST(m.BWART AS NVARCHAR(3)) AS MovementType,
m.WERKS AS Plant,
m.LGORT AS StorageLocation,
m.MENGE AS Quantity,
m.GRUND AS MovementReasonCode,
mm.activity_name AS ActivityName,
m.MBLNR AS MaterialDocumentNumber,
m.MJAHR AS MaterialDocumentYear,
m.ZEILE AS MaterialDocumentItem
FROM [Your SAP HANA schema].MATDOC m
INNER JOIN movement_map mm
ON CAST(m.BWART AS NVARCHAR(3)) = mm.movement_type
CROSS JOIN params p
WHERE m.CHARG IS NOT NULL
AND TRIM(m.CHARG) <> ''
AND COALESCE(m.BUDAT_MKPF, m.BUDAT) >= p.start_ts
AND COALESCE(m.BUDAT_MKPF, m.BUDAT) < p.end_ts
AND m.WERKS IN ([Configure based on your system])
),
batch_enriched_events AS (
SELECT
e.InventoryBatchLot,
e.ActivityName,
e.EventTime,
e.MaterialNumber,
e.UserName,
e.MovementType,
e.Plant,
e.StorageLocation,
e.Quantity,
e.MovementReasonCode,
e.MaterialDocumentNumber,
e.MaterialDocumentYear,
e.MaterialDocumentItem,
c.CUOBJ_BM AS BatchObjectNumber
FROM matdoc_events e
LEFT JOIN [Your SAP HANA schema].MCHA c
ON c.MATNR = e.MaterialNumber
AND c.CHARG = e.InventoryBatchLot
AND c.WERKS = e.Plant
),
verified_batch_status_events AS (
SELECT
CAST(NULL AS NVARCHAR(40)) AS InventoryBatchLot,
'Batch Status Changed' AS ActivityName,
CAST(NULL AS TIMESTAMP) AS EventTime,
CAST(NULL AS NVARCHAR(40)) AS MaterialNumber,
CAST(NULL AS NVARCHAR(80)) AS UserName,
CAST(NULL AS NVARCHAR(3)) AS MovementType,
CAST(NULL AS NVARCHAR(4)) AS Plant,
CAST(NULL AS NVARCHAR(4)) AS StorageLocation,
CAST(NULL AS DECIMAL(31,3)) AS Quantity,
CAST(NULL AS NVARCHAR(3)) AS MovementReasonCode,
CAST(NULL AS NVARCHAR(20)) AS MaterialDocumentNumber,
CAST(NULL AS NVARCHAR(4)) AS MaterialDocumentYear,
CAST(NULL AS NVARCHAR(6)) AS MaterialDocumentItem,
CAST(NULL AS NVARCHAR(40)) AS BatchObjectNumber
FROM DUMMY
WHERE 1 = 0
),
verified_picking_events AS (
SELECT
CAST(NULL AS NVARCHAR(40)) AS InventoryBatchLot,
'Picking Initiated' AS ActivityName,
CAST(NULL AS TIMESTAMP) AS EventTime,
CAST(NULL AS NVARCHAR(40)) AS MaterialNumber,
CAST(NULL AS NVARCHAR(80)) AS UserName,
CAST(NULL AS NVARCHAR(3)) AS MovementType,
CAST(NULL AS NVARCHAR(4)) AS Plant,
CAST(NULL AS NVARCHAR(4)) AS StorageLocation,
CAST(NULL AS DECIMAL(31,3)) AS Quantity,
CAST(NULL AS NVARCHAR(3)) AS MovementReasonCode,
CAST(NULL AS NVARCHAR(20)) AS MaterialDocumentNumber,
CAST(NULL AS NVARCHAR(4)) AS MaterialDocumentYear,
CAST(NULL AS NVARCHAR(6)) AS MaterialDocumentItem,
CAST(NULL AS NVARCHAR(40)) AS BatchObjectNumber
FROM DUMMY
WHERE 1 = 0
),
all_events AS (
SELECT InventoryBatchLot, ActivityName, EventTime, MaterialNumber, UserName, MovementType, Plant, StorageLocation, Quantity, MovementReasonCode, MaterialDocumentNumber, MaterialDocumentYear, MaterialDocumentItem, BatchObjectNumber FROM batch_enriched_events
UNION ALL SELECT InventoryBatchLot, ActivityName, EventTime, MaterialNumber, UserName, MovementType, Plant, StorageLocation, Quantity, MovementReasonCode, MaterialDocumentNumber, MaterialDocumentYear, MaterialDocumentItem, BatchObjectNumber FROM verified_batch_status_events
UNION ALL SELECT InventoryBatchLot, ActivityName, EventTime, MaterialNumber, UserName, MovementType, Plant, StorageLocation, Quantity, MovementReasonCode, MaterialDocumentNumber, MaterialDocumentYear, MaterialDocumentItem, BatchObjectNumber FROM verified_picking_events
)
SELECT
InventoryBatchLot,
ActivityName,
EventTime,
MaterialNumber,
UserName,
MovementType,
Plant,
StorageLocation,
Quantity,
MovementReasonCode
FROM all_events
WHERE InventoryBatchLot IS NOT NULL
AND EventTime IS NOT NULL
ORDER BY InventoryBatchLot, EventTime, MaterialDocumentYear, MaterialDocumentNumber, MaterialDocumentItem, ActivityName; 步骤
- 访问ABAP编辑器:登录SAP S/4HANA系统。使用事务代码
SE38打开ABAP编辑器。 - 创建新程序:在“Program”字段中输入新程序名称,例如
Z_PM_INVENTORY_EXTRACT,然后点击“Create”按钮。填写描述性标题,将“Type”设置为“Executable Program”,并将其保存到一个软件包中。 - 定义程序参数:在程序编辑器中定义作为提取用户界面的选择屏幕。用户可以在此指定数据提取的日期范围、工厂等参数。
- 实现提取逻辑:复制“Query”部分提供的完整ABAP代码,并粘贴到ABAP编辑器中。该代码用于从不同SAP表中提取全部14项所需库存活动的数据。
- 了解核心逻辑:程序从各个源表中选择不同库存活动的数据,例如从
MKPF和MSEG获取物料移动数据,从CDHDR和CDPOS获取主数据变更。随后使用UNION ALL将各次选择结果合并到一个代表事件日志的内部表中。 - 配置文件输出:代码最后负责将内部表中的汇总数据写入文件。程序使用
OPEN DATASET语句在SAP应用服务器上创建文件。您必须指定一个有效的服务器路径,并确保SAP系统用户拥有写入权限。 - 执行程序:保存并激活ABAP程序(Ctrl+F3)。按F8执行。在选择屏幕中输入所需日期范围及其他相关筛选条件,例如Plant或Company Code。
- 作为后台作业运行:对于大量数据,必须将程序作为后台作业执行,以避免会话超时。在执行屏幕(F8)中进入菜单
Program -> Execute in Background,安排作业在业务低峰时段运行。 - 获取输出文件:作业完成后,在SAP应用服务器上找到输出文件。使用事务代码
AL11浏览服务器目录并查找文件,再使用事务CG3Y将文件下载到本地计算机。 - 准备上传:使用文本编辑器或电子表格软件打开下载的文件。确保文件为CSV格式,包含标题行,使用逗号作为分隔符、双引号作为文本限定符。上传至流程挖掘工具前,请确认列名符合要求。
配置
- 过账日期范围:这是最关键的参数。建议按可控批次提取数据,例如每次提取3至6个月,以确保良好性能并避免系统超时。
- 工厂筛选:强烈建议按一个或多个特定工厂(
WERKS)筛选。一次提取所有工厂的数据可能消耗大量系统资源。 - 公司代码筛选:如果您的组织在同一系统中运营多个公司代码,可以选择按公司代码(
BUKRS)筛选,进一步缩小数据范围。 - 应用服务器文件路径:ABAP程序需要SAP应用服务器上预先定义且有效的目录路径。请确保SAP系统用户(
SY-UNAME)拥有向该目录写入文件所需的操作系统权限。 - 授权:执行提取的用户需要拥有事务
SE38权限(用于创建和运行程序)、表MKPF、MSEG、MCH1、CDHDR、CDPOS、LTAK和LTAP的显示权限,以及安排后台作业(SM36/SM37)的权限。
a 示例查询 abap
REPORT Z_PM_INVENTORY_EXTRACT.
" ====================================================================
" SELECTION SCREEN
" ====================================================================
SELECT-OPTIONS: s_budat FOR sy-datum OBLIGATORY.
SELECT-OPTIONS: s_werks FOR mseg-werks.
PARAMETERS: p_fpath TYPE string DEFAULT '/usr/sap/trans/tmp/inventory_log.csv' OBLIGATORY.
" ====================================================================
" DATA STRUCTURES
" ====================================================================
TYPES: BEGIN OF ty_event_log,
InventoryBatchLot TYPE charg,
ActivityName TYPE string,
EventTime TYPE string,
MaterialNumber TYPE matnr,
UserName TYPE xubname,
MovementType TYPE bwart,
Plant TYPE werks_d,
StorageLocation TYPE lgort_d,
Quantity TYPE menge_d,
MovementReasonCode TYPE grund,
END OF ty_event_log.
DATA: lt_event_log TYPE TABLE OF ty_event_log.
" ====================================================================
" DATA SELECTION
" ====================================================================
START-OF-SELECTION.
SELECT
mseg~charg AS InventoryBatchLot,
'Goods Receipt Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('101', '103', '105', '501', '521', '561')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
CASE mseg~shkzg
WHEN 'H' THEN 'Stock Posted to Quality Inspection'
WHEN 'S' THEN 'Quality Inspection Stock Released'
END AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '321' " For QI to Unrestricted
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Put-Away Transfer Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '311' AND mseg~shkzg = 'H' " Assume put-away is the credit side
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Internal Stock Transfer Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('301', '311', '313', '315')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
CASE mseg~bwart
WHEN '343' THEN 'Stock Status Changed to Blocked'
WHEN '344' THEN 'Stock Status Changed to Unrestricted'
END AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('343', '344')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Inventory Adjustment Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('701', '702', '711', '712')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Goods Issue for Delivery Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '601'
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Goods Issue for Production Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '261'
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Sales Return Received' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('651', '653')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Stock Scrapped' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '551'
UNION ALL
SELECT
ltap~charg AS InventoryBatchLot,
'Picking Initiated' AS ActivityName,
CONCAT( ltak~bdatu, ltak~bzeit ) AS EventTime,
ltap~matnr AS MaterialNumber,
ltak~bname AS UserName,
ltak~bwart AS MovementType,
ltap~werks AS Plant,
ltap~lgort AS StorageLocation,
ltap~nista AS Quantity,
'' AS MovementReasonCode
FROM ltap
JOIN ltak ON ltak~tanum = ltap~tanum
WHERE ltak~bdatu IN s_budat
AND ltap~werks IN s_werks
AND ltap~charg IS NOT NULL AND ltap~charg <> ''
UNION ALL
SELECT
SUBSTRING( cdhdr~objectid, 5, 18 ) AS InventoryBatchLot, " Object ID for BATCH is MATNR+WERKS+CHARG
'Batch Status Changed' AS ActivityName,
CONCAT( cdhdr~udate, cdhdr~utime ) AS EventTime,
SUBSTRING( cdhdr~objectid, 1, 4 ) AS MaterialNumber,
cdhdr~username AS UserName,
'' AS MovementType,
'' AS Plant,
'' AS StorageLocation,
0 AS Quantity,
'' AS MovementReasonCode
FROM cdhdr
JOIN cdpos ON cdpos~objectclas = cdhdr~objectclas
AND cdpos~objectid = cdhdr~objectid
AND cdpos~changenr = cdhdr~changenr
WHERE cdhdr~udate IN s_budat
AND cdhdr~objectclas = 'BATCH'
AND cdpos~tabname = 'MCH1'
AND cdpos~fname = 'ZUSTD'
INTO TABLE @lt_event_log.
" ====================================================================
" WRITE OUTPUT FILE
" ====================================================================
DATA: lv_string TYPE string.
DATA: lo_conv TYPE REF TO cl_abap_conv_out_ce.
lo_conv = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
OPEN DATASET p_fpath FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc <> 0.
MESSAGE 'Error opening file.' TYPE 'E'.
RETURN.
ENDIF.
" Write Header
lv_string = 'InventoryBatchLot,ActivityName,EventTime,MaterialNumber,UserName,MovementType,Plant,StorageLocation,Quantity,MovementReasonCode'.
TRANSFER lv_string TO p_fpath.
" Write Data
LOOP AT lt_event_log ASSIGNING FIELD-SYMBOL(<fs_log>).
CONCATENATE
<fs_log>-InventoryBatchLot
<fs_log>-ActivityName
<fs_log>-EventTime
<fs_log>-MaterialNumber
<fs_log>-UserName
<fs_log>-MovementType
<fs_log>-Plant
<fs_log>-StorageLocation
<fs_log>-Quantity
<fs_log>-MovementReasonCode
INTO lv_string
SEPARATED BY ','.
TRANSFER lv_string TO p_fpath.
ENDLOOP.
CLOSE DATASET p_fpath.
WRITE: 'Extraction complete. File written to:', p_fpath. 在SAP S/4HANA中优化您的库存管理
精准定位低效环节,将周期时间缩短30%,降低成本。
无需信用卡•几分钟即可完成设置