ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SAP采购收货库存金额与会计凭证全链路解析

SAP采购收货库存金额与会计凭证全链路解析 有一次在客户现场领导让我把一张采购订单从收货到付款的全流程数据捞出来用于对账。我一开始以为跑几个表就能搞定结果发现 MARD 查出来只有数量MBEW 里的金额跟财务那边对不上MSEG 里的金额加起来也不等于总账凭证的金额。后来我仔细把 MM 和 FI 之间的凭证流、科目确定逻辑翻了一遍才算把采购验收的库存、数量、金额、会计凭证这件事彻底串起来。这篇文章就把这套数据链路完整讲清楚采购验收后库存放在哪个表物料数量以及金额在哪个表会计凭证是怎么产生出来的以及这些表之间到底怎么关联。适合正在做 SAP 二次开发、报表取数或者被 MM 和 FI 对账折磨的朋友参考。先说明一下文中涉及的字段和表名都基于标准 SAP ECC / S/4HANA如果有定制化开发字段可能改过但核心思路是一样的。1. 采购验收的数据落盘收货那一笔到底写了哪些表先说结论采购收货移动类型 101这一下数据不是写进一张表而是同时更新了物料凭证表、库存数量表、采购订单历史表并且在后台异步生成了财务凭证。要理清库存放在哪个表必须先分清流水和存量这两个概念。1.1 物料凭证MKPF MSEG 才是收货真正的主表MIGO 做收货后系统会生成一张物料凭证抬头存在 MKPF行项目存在 MSEG。这是整个采购收货最核心的两张表。MKPF物料凭证抬头主要存凭证号、凭证类型、记账日期、过账日期、创建人这些表头信息。关键字段MBLNR物料凭证编号MJAHR物料凭证年度BLART凭证类型标准收货一般是 WE冲销可能是后续的 102 等BUDAT过账日期MSEG物料凭证行项目才是真正存业务细节的表也是做报表时用得最多的一张表。一张收货单如果收了 10 行物料MSEG 就有 10 行。关键字段MBLNR、MJAHR、ZEILE凭证号、年度、行项目号三个字段定位唯一行BWART移动类型101 表示采购订单收货102 表示冲销收货MATNR物料号WERKS工厂LGORT库存地点MENGE、MEINS数量、基本计量单位DMBTR、WRBTR金额前者是本位币金额后者是凭证货币金额SHKZG借贷标志S 是借方H 是贷方EBELN、EBELP采购订单号和行项目号KOSTL、AUFNR、KDAUF、KDPOS成本中心、生产订单、销售订单号等科目分配信息LFBNR、LFBJA前置凭证号如果是冲销业务这里会指向被冲销的原始凭证有人会把 MSEG 当成库存表用这是不对的。MSEG 是流水账它记录的是每一次过账动作不是当前库存是多少。当前库存要看下面这张表。1.2 库存数量更新MARD 以及 MCHB / MSKU普通物料在工厂和库存地点层面的当前库存存在 MARD 表。MARD 的主键是 MATNR WERKS LGORT。需要注意MARD 里不是只有总库存一个字段而是把库存按类型拆成了几个字段LABST非限制使用库存也就是最常用的可用库存UMLME在途库存常见于跨工厂转储或收货到在途状态INSME质检库存SPEME冻结库存RETME退货库存如果物料启用了批次管理那库存要按批次继续细分存在 MCHB 表主键是 MATNR WERKS LGORT CHARG字段拆分逻辑和 MARD 类似。如果是特殊库存比如供应商寄售库存、销售订单库存、项目库存那 MARD 里根本没有要看 MSKU特殊库存相关表。这个后面单独说。所以回答标题第一个问题库存放在哪个表普通库存的数量在 MARD批次库存数量在 MCHB特殊库存数量在 MSKU而每次变化的明细在 MSEG。如果只想看某一时刻的库存余额不用去翻 MSEG 流水直接查 MARD / MCHB / MSKU 就行。1.3 采购订单历史EKBE 记录每一次交付除了物料凭证采购订单历史表 EKBE 也会同步更新。EKBE 是采购订单历史表每一行代表采购订单行项目的一次业务动作收货、发票校验、后续交货等。关键字段EBELN、EBELP采购订单号及行项目BELNR、BUZEI关联的物料凭证号和行号BEWTP业务类型比如 WE 表示收货RE 表示发票MENGE本次动作的数量DMBTR本次动作的金额BUDAT过账日期EKBE 的价值在于它能让你从采购订单的视角看这单到底收了多少货、来了多少发票、还剩多少没交付。很多采购订单状态报表都是基于 EKBE 做的。但要注意EKBE 存的是发生过的动作不是当前状态已冲销的动作不会自动从 EKBE 里消失查状态时要额外处理。2. 库存数量与金额的分家为什么库存表没有金额金额又去了哪在做物料账的人十有八九会有个困惑MARD 里没有金额字段那我的库存金额到底在哪这个问题要分两个层面回答。2.1 MARD 只有数量真的没有金额MARD 从设计之初就是一张数量账它只回答这个物料在这个工厂这个库位当前有多少可用、多少在检、多少冻结不回答这些库存值多少钱。因为库存金额在 SAP 里不是一个简单的数量乘单价它受到移动平均价、标准价、物料分类账、汇率差异等一堆因素影响。如果 MARD 里塞一个金额字段每次过账都要按不同估价方式更新维护成本会失控。所以在 MM 层面库存数量和库存价值是分开管理的。数量归 MARD价值归物料账和财务账。2.2 金额要看 MBEW / MBEWH 或者 FI 总账先看物料本身的价值。启用物料账Material Ledger之前物料当前的评估价格和价值在 MBEW 表主键是 MATNR BWKEY评估范围 BWTAR评估类型。MBEW 里和库存金额直接相关的是这几个字段LBKUM评估库存总数量SALK3评估库存总价值本位币VKSAL上期结转价值VBKUM上期结转数量VPRSV价格控制标识S 表示标准价V 表示移动平均价VERPR当前期间价格STPRS标准价格如果启用了物料分类账那按月、按凭证的库存价值明细就更复杂了核心表是 MLHD物料分类账抬头和 MLIT物料分类账行项目可以按期间、按凭证追溯库存数量和金额的变化。SAP 的 MR21、MR22 改价或者 CKMLCP 物料账结算都会写进这套表。再从财务视角看库存科目的当期余额其实是总账层面的金额。换句话说财务上真正的存货资产在 FI 的科目余额里比如总账科目 140001 原材料通过 BSEG/BSIS/FAGLFLEXT 等表反映。MBEW 里的 SALK3 只是物料维度的价值参考它和总账科目余额之间靠评估范围、科目表、评估类这些配置关联两边可能因为未清项、外币评估、未结算差异存在短期不一致月底通过物料分类账结算或重分类调整拉平。所以回答物料数量以及金额在哪个表数量看 MARD/MCHB/MSKU价值看 MBEW未启物料账时或 MLIT/MLHD FI 总账。如果想直接看某一期间的期初期末库存金额MB5L、MB5S 这些标准报表底层就是在处理这些表的组合。2.3 特殊库存和批次库存别用错了表这里提醒一句MARD 只包含普通库存也就是属于自己的、放在自有库存地点的库存。下面这几种情况都不要去 MARD 里找供应商寄售库存特殊库存标识 K数量在 MSKU物料属于供应商结算时才转自有库存销售订单库存特殊库存标识 E数量在 MSKU挂在具体销售订单下项目库存特殊库存标识 Q数量在 MSKU挂在 WBS 元素下批次库存数量在 MCHB字段逻辑和 MARD 类似判断到底该查哪张表可以看物料凭证流水里的 SOBKZ特殊库存标识字段。SOBKZ 为空就是普通库存查 MARD有值就按值去找 MSKU 或 MCHB。另外一个实用经验是MB51 查物料凭证时勾上物料编号、工厂、库存地点这些字段就能直接看出每一笔冲的是普通库存还是特殊库存不用自己猜。3. 从物料凭证到 FI 凭证101 过账和 OBYC 科目确定的完整逻辑现在回答标题里最核心的问题采购验收是如何产生会计凭证的。流程本身不复杂MIGO 收货保存后系统先写物料凭证MKPF/MSEG同时根据物料主数据和后台科目确定配置自动生成一张 FI 会计凭证BKPF/BSEG。但自动生成背后有一套完整的规则理解它才能看懂金额为什么这样拆。3.1 收货过账的关键配置OBYC 中的 BSX / WRX / PRDSAP 的 MM 自动科目确定配置集中在一个事务码里OBYC。这里面按事务键Transaction Key区分不同业务场景采购收货时最常碰到的三个事务键是BSX库存记账。收货时借记存货科目的规则WRXGR/IR 结算。收货时贷记应付账款-暂估Goods Receipt / Invoice Receipt的规则PRD采购价格差异。标准价物料收货产生价差时差异进这个科目KDM供应商折扣/后续贷记通常发票校验后处理OBYC 的科目确定不是移动类型选科目而是靠三个维度组合科目表Chart of Accounts、评估修改Valuation Modifier、评估类Valuation Class。其中评估类存在物料主数据的会计视图表 MARC-BKLAS它把物料按属性分组比如原材料、半成品、成品各用一个评估类然后在 OBYC 里给每个评估类指定对应的存货科目和 GR/IR 科目。所以流程可以概括为收货时系统根据物料主数据找到评估类再根据工厂所属的评估范围和后台配置的评估修改在 OBYC 中匹配出应记账的存货科目和 GR/IR 科目然后生成分录。3.2 价格控制方式决定差异怎么走这一步是最容易懵的地方。同样一笔收货物料主数据里如果价格控制是 V移动平均价和 S标准价会计凭证的分录是不同的。移动平均价V存货科目按采购订单的净价入账分录就是借存货科目BSX贷GR/IRWRX金额相等没有差异行标准价S存货科目按物料主数据里的标准价格入账GR/IR 按采购订单价格入账两者之间的差额进采购价格差异科目PRD举个例子某物料标准价是 100 元这次采购订单净价是 120 元移动类型 101 收货后FI 凭证是三行借原材料存货科目BSX 100 元借采购价格差异PRD 20 元贷GR/IRWRX 120 元这就是为什么你拿着 MSEG 里的 DMBTR 去对 FI 凭证经常对不上的原因。MSEG 的 DMBTR 反映的是物料凭证层面的总金额通常是采购价或评估价而 BSEG 是会计凭证层面的分录行两者是多条分录对一条流水的关系。3.3 一张 101 凭证科目确定实例标准配置下一次普通采购收货产生的会计凭证大致是这个套路行科目方向科目来源金额来源1借存货科目OBYC-BSX按评估类确定标准价或移动平均价2借/贷价格差异科目OBYC-PRD仅标准价物料存在差额时标准价与采购价差额3贷GR/IR 科目OBYC-WRX采购订单净价如果这张采购订单涉及运费、关税、杂费或者收货时启用了收货自动冲销逻辑科目行还会更多。例如 103收货到质检库存转 105质检转可用库存是两笔凭证跨工厂转储 101从工厂 A 转出用 303 等则涉及不同的移动类型和科目规则但科目确定思路都一样找 BSX、找 WRX、找 PRD。另外S/4HANA 里 GR/IR 记账还多了供应商维度后台可以在 OBYC 的 GR/IR 科目上开启供应商字段这样每一笔 GR/IR 都能按供应商挂账发票校验时自动清账降低了余额对账的难度。这也是为什么新项目上财务都会要求把 GR/IR 科目的未清项管理打开。4. 表关联实操从一张收货单反查科目、库存数量与库存金额这一节直接给你关联路径重点是理解 SAP 里物料凭证和会计凭证之间的隐藏桥。4.1 从物料凭证到会计凭证的黄金桥BKPF-AWKEYMSEG 里面其实没有一个叫FI 凭证号的字段很多人在这里卡住。那怎么从物料凭证找到会计凭证答案是看会计凭证抬头表 BKPF 的 AWKEY 字段。BKPF-AWKEY 存的是一个参考关键字它把 FI 凭证和源业务单据联系起来。对于收货产生的 FI 凭证AWKEY 的规则是物料凭证号 物料凭证年度直接拼成一个字符串。同时 BKPF-AWTYP参考事务类型会标记出来源类型比如 MKPF 代表物料凭证。所以从收货物料凭证找 FI 凭证的逻辑是从 MSEG 拿到 MBLNR、MJAHR用 AWTYP MKPF 且 AWKEY MBLNR MJAHR 在 BKPF 里查 FI 凭证抬头从 BKPF 拿到 BUKRS、BELNR、GJAHR再去 BSEG 按 BUKRS BELNR GJAHR 取分录行反过来说如果财务给了一张 FI 凭证你想看它是不是来自收货也看 BKPF-AWTYP 和 AWKEY。AWTYP 是 MKPF 的就是物料凭证再把 AWKEY 拆开前 10 位是物料凭证号后面是年度就能去 MKPF/MSEG 查明细。4.2 反向追查会计凭证如何知道它来自收货还有一种常见场景BSEG 里的某一行的来源不明比如看到一笔 20 元的采购价格差异借方不知道是谁产生的。这时可以回到 BKPF 找 AWTYP 和 AWKEY如果是 MKPF再去 MSEG 查对应的物料凭证。MSEG 里有 EBELN、EBELP能一路追到采购订单有 MATNR、WERKS能追到物料和工厂有 LFBNR能追到它是不是冲销了某个原始收货。要注意冲销凭证比如 102 冲 101的 AWKEY 指向的是一张新的物料凭证而不是原始凭证。原始 101 和冲销 102 之间靠 MSEG-LFBNR/LFBJA 关联。所以做凭证链追溯时要同时用 AWKEY 和 LFBNR 两条路才能把原凭证-冲销凭证完整串起来。另外MSEG 里还有两个字段经常被忽略KDAUF/KDPOS销售订单号/行和 AUFNR生产订单号采购收货如果是为了某个订单采购这些字段会带上订单号做采购收货成本归集报表时非常有用。4.3 完整 SQL 排查链示例给你一套可以拿去改的查询思路。假设现在要查供应商 1000 在 2024 年 5 月 1 日收货后某物料的库存数量、库存金额和 FI 分录。第一步按采购订单或物料查 MSEG 流水SELECT MBLNR, MJAHR, ZEILE, BWART, SHKZG, MENGE, DMBTR, EBELN, EBELP FROM MSEG WHERE MATNR 物料号 AND WERKS 1000 AND BUDAT 20240501 AND BUDAT 20240531 AND BWART 101;第二步拿第一行返回的 MBLNR、MJAHR 去 BKPF 找 FI 凭证SELECT BUKRS, BELNR, GJAHR, AWTYP, AWKEY, BLART, BUDAT FROM BKPF WHERE AWTYP MKPF AND AWKEY 该MBLNR || 该MJAHR;第三步用 BKPF 返回的 BUKRS、BELNR、GJAHR 去 BSEG 看行项目SELECT BUZEI, SHKZG, HKONT, DMBTR, WRBTR, KOSTL, AUFNR FROM BSEG WHERE BUKRS 公司代码 AND BELNR 凭证号 AND GJAHR 年度;第四步看当前库存数量和库存金额-- 普通库存数量 SELECT LABST, UMLME, INSME, SPEME FROM MARD WHERE MATNR 物料号 AND WERKS 1000 AND LGORT 库存地点; -- 物料当前价值 SELECT LBKUM, SALK3, VPRSV, VERPR FROM MBEW WHERE MATNR 物料号 AND BWKEY 1000;如果启用了物料分类账想按期间看数量和金额变化可以查 MLIT按 MBLNR、MJAHR 过滤它会把每一笔物料凭证对应的物料账金额和 FI 过账标记都带出来。我在项目上做进销存差异分析时MLIT 的效率比 MSEG BSEG 手工核对高很多因为 MLIT 已经把物料号、期间、数量、金额、FI 凭证号串好。5. 开发采购收货报表时几个绕不开的坑和通用做法最后聊点实战经验。这几条是我在多个项目里真金白银踩出来的尤其是做 MM-FI 对账报表的同事建议认真看。5.1 坑一MSEG 的金额直接累加不等于入账金额前面说过标准价物料的收货会产生差异行差异在 BSEG不在 MSEG。如果你直接 SELECT SUM(DMBTR) FROM MSEG 来算库存金额变化得到的结果和总账一定对不上。通用做法以 BSEG 的库存科目行BSX 对应的科目为准累加金额或者用 MLIT 汇总物料账金额再或者干脆以总账科目余额为主表MSEG 只用来核对明细张数不做金额汇总。开发报表时我一般这样分数量变化看 MSEGMENGE金额变化看 BSEG 或 MLIT两条链路分开设计不要混在一个 SQL 里。5.2 坑二MARD 没有历史查期间库存不能用它MARD 只存当前数量每笔过账直接更新对应字段。你查 5 月 31 日的 MARD看到的是当前值不是 5 月底的历史值等于把 6 月发生的业务也算进去了。要查某期间期初期末库存有几个标准路径物料分类账MLIT/MLHD 按期间过滤最准确物料凭证流水起点库存 期间内入 - 期间内出 期末库存工作量比较大标准报表 MB5B物料库存的收发货日期清单和 MB5L库存余额它们底层就是把物料凭证流水按期间结转计算所以做库存期间报表不要设计成SE16N 导出 MARD 就能出数的思路。MARD 只能用于此时此刻还有多少的场景。5.3 坑三冲销、退货、质检库存和寄售库存的关联差异冲销收货移动类型 102在 MSEG 里是一行反向数据SHKZG 会反过来但 MARD 的更新要看原始 101 是不是已经入账。如果原始 101 是把货收进质检库存INSME冲销 102 也是从 INSME 扣减不会动 LABST。所以做库存数量变化报表时必须按库存类型分类统计不能只盯着 LABST。退货给供应商移动类型 122也是容易错的地方。122 虽然挂着采购订单但它不是简单的收货冲销它可能产生额外的退货费用或触发发票校验的后续处理。查表时MSEG 里的 BWART 要单独按 122 过滤不能和 101 混在一起算采购入库量。寄售库存更特殊供应商寄售库存SOBKZ K在 MSKU 里物料还没有所有权不产生存货科目入账。当从寄售库存转自有库存移动类型 201 或 411/412 结合消费/领用时才按转储的移动类型产生 FI 凭证。如果做采购库存金额报表时把寄售库存的 MSKU 数量当成普通库存金额去算会虚增存货。这一点我在项目上栽过最后加了 SOBKZ 过滤条件才把报表调整正确。最后说一个我现在做事的习惯新接手的 SAP 报表需求先画两条线——一条走 MM 数量MKPF/MSEG → MARD/MCHB/MSKU一条走 FI 金额BKPF/BSEG → 总账或 MLIT两条线在物料凭证号MBLNR和会计凭证BELNR这个交叉点汇合。这样既不会漏掉数量也不会算错金额后续对账、排查问题都省心很多。
返回列表