简介:《SAP 库存调拨与发货》面向SAP MM顾问、库存仓储人员及ERP学习者,聚焦MB1B库存调拨、发货过账与后台配置,帮助理解一步/二步转储、工厂间转储和物料状态变更。压缩包含1个docx文件,约2.25MB,便于集中查阅。内容覆盖311、313/315、301、303/305、309等移动类型,结合MMBE、MB52、MB5T查看库存与在途状态,并说明344/343状态转变及MRP影响。后台部分讲到采购订单库存调拨凭证类型、SD工厂装运数据、一步转储判定、转储单类型NB与UB差异,以及351等场景的出货单生成条件。已有1520人学习,适合需要系统掌握SAP库存调拨流程、对照配置并查漏补缺的初中级用户。
1. 移动类型才是真正的主角:同一个 MB1B 为什么能拆出 311、313 和 301
库存调拨看着像"把物料从一个地方挪到另一个地方"这么朴素的动作,但真正决定账怎么记的,往往是屏幕角落那个三位数的移动类型。同样一个 MB1B 界面,敲 311 是一次过账、账面上干干净净;敲 313 就凭空多出一段"已发出、未收货"的在途;敲 301 跨过了工厂边界;敲 309 甚至会把物料的移动平均价一起搬走。绝大多数库存对不上的事故,追到最后不是操作员手滑,而是移动类型选歪了、后台配置没跟上。MB1B 只是入口,移动类型才是账本上那条真正的指令——搞清楚它背后的记账逻辑,才谈得上把库存调拨跑稳。
2. 一步与二步:库存数字背后那笔「在途」账
先给一个容易被忽略的现象:做一次二步转储,313 发完货、315 还没收货的那段时间里,你去 MB52 看,发出库存地的数量已经减了,接收库存地的数量却一点没加,两边加起来的总数比操作前少了。新人第一次看到这个往往会慌,以为库存丢了。其实没丢,它只是从"某个库存地"变成了"一段状态"。
理解这条分界线,就能理解整个库存调拨模块的设计骨架:系统中的库存不是只有"有"和"没有"两种形态,中间还存在一种"所有权还归我、但物理位置已经模糊"的过渡态。一步转储把这个过渡态压缩到一次过账里消掉,二步转储则把它显式地保留下来,让你能用报表看见、能用时间窗口管理。
2.1 311 一步转储:为什么一次过账就够
一步转储(移动类型 311)处理的场景是:物料、工厂都不变,只是从一个库存地挪到另一个库存地。因为物理位置的变化在系统看来可以瞬间完成——库管员推个小车走过去,几秒钟的事——所以系统也只记一次账。
过账后生成的是一张物料凭证,凭证下挂两个行项目:一个是发出库存地的负数(SHKZG = S),一个是接收库存地的正数(SHKZG = H)。两行金额、数量在凭证内部自洽,工厂层级的库存总量纹丝不动。
这里有个设计上的取舍值得注意:为什么不用两条独立的凭证分别记发出和收入?因为一旦拆成两张凭证,中间就必然出现"已发未收"的时间差,而这个时间差对同工厂场景毫无业务意义——物料就在同一栋楼里。把它压缩成一张凭证,等于用"凭证的原子性"换掉了"业务上的多余状态",记账干净,对账也简单。
代价是它不记录"过程"。一旦 311 过账完成,你没法从系统里看出这批货是几点从 A 库位出发、几点进的 B 库位,只知道"某一刻它已经在 B 了"。这在同工厂场景下无所谓,但跨工厂、跨公司、甚至跨法人主体的调拨,就必须留痕了——这就是二步转储存在的理由。
MB1B 下311 的必填要素是"物料 + 工厂 + 发出库存地 + 接收库存地 + 数量"。发出地和接收地如果填成同一个,系统会直接报错,这个校验看起来废话,实际拦住了不少批量导入脚本里的低级错误。
2.2 313/315 二步转储:在途库存到底存在哪一张表里
二步转储把一次物理移动拆成两个动作、两张凭证:313 负责"发出",315 负责"接收"。中间这段时间,库存处于在途状态。
关键问题是:这段在途库存,物理上记录在哪?
答案可能和直觉相反——它不存在于任何一个真实的库存地点里。SAP 并没有为同工厂二步转储准备一个专门的"在途库存地"让货"停"在那里。313 过账后发生的事情是:发出库存地的库存被实实在在地扣减了,而接收库存地什么也没发生。至于报表上你看到的那个"在途量",是系统在查询时动态算出来的——它去扫描所有"已发货但未收货"的转储凭证,把差额汇总出来给你看。
这个设计非常克制。如果真搞一个虚拟库存地来存货,那就需要维护这个库存地的容量、盘点、库龄,等于凭空造出一个管理成本极高的影子仓库。而"动态计算"只需要维护一条"未清关系":313 的凭证号被 315 引用,引用解除,在途归零。
下面这段查询能直接把这层关系看穿:
-- 313 发货与 315 收货是两张独立凭证,靠物料+移动类型+时间窗口关联 SELECT mblnr, -- 物料凭证号 mjahr, -- 凭证年度(跨年查询必须带上) zeile, -- 行项目号 bwart, -- 移动类型:313 发货 / 315 收货 werks, -- 工厂 lgort, -- 库存地:313 时是发出地,315 时是接收地 matnr, -- 物料号 menge, -- 数量 shkzg -- 借贷标识:S=发出(负),H=收入(正) FROM mseg WHERE matnr = 'MAT-0001' AND bwart IN ('313', '315') AND budat BETWEEN '20240101' AND '20240131' ORDER BY budat, mblnr, zeile;几个参数值得说清楚:shkzg是判断方向的关键,313 那行一定是 S,315 那行一定是 H;lgort在两张凭证里含义不同,313 记的是发出库存地,315 记的是接收库存地,所以别拿 lgort 去做两行之间的等值关联,那样永远对不上;mjahr必须带上,物料凭证号是按年度循环的,跨年对账时不带年份会捞出重号。较新的版本里物料凭证行收敛到了MATDOC这类表,字段名有差异,但"两行一对、借贷相对"的结构没变。
315 收货这一步,MB1B 315 和 MIGO 走的是同一套过账逻辑,区别只在界面。MIGO 的好处是可以直接把 313 的凭证号填进"参考凭证"字段,系统自动带出物料、数量、库存地,减少手工输入导致的错配。血泪经验是:大批量的二步转储,尽量走 MIGO 带参考凭证的形式,手工敲 315 时数量填错、库存地填错的比例高得吓人。
2.3 MMBE、MB52、MB5T:三个报表看到的不是同一份库存
这一段是很多人的认知盲区。三个报表名字都叫"查库存",但它们统计的维度完全不同,混着用就会得出矛盾结论。
| 报表 | 统计维度 | 能看到在途吗 | 典型用途 |
|---|---|---|---|
| MMBE | 物料 × 工厂 × 库存地,含状态细分 | 能,有专门的在途列 | 单物料全景,查某一笔转储卡在哪 |
| MB52 | 物料 × 工厂 × 库存地,批量列表 | 不能,只算已落地的库存 | 大批量盘点、导出对账 |
| MB5T | 跨工厂的在途 | 只看跨工厂在途 | 工厂间转储的追踪 |
MMBE 是在途库存的主战场。它把同一工厂内 313 已发未收的量单独列出来,你一眼就能看出"少了的那部分去哪了"。而 MB52 是"落地库存"的视角,它在设计上就不关心过程,所以二步转储进行到一半时用 MB52 对账,必然会发现总数对不上——这不是数据错了,是你用错了报表。
MB5T 的边界更窄,它只处理跨工厂的在途。同工厂的 313 在途它根本不看,因为那是工厂内部的事,不涉及工厂间的库存归属转移。这个分工很清晰:工厂内的过程用 MMBE,工厂间的过程用 MB5T,落地的结果用 MB52。
理解了这三者的分工,前面那个"总数凭空少了"的现象就自然解释了:你缺的不是库存,你缺的是把 MMBE 的在途列加进来一起算。
3. 工厂间转储:为什么 301 能跑通却不是推荐做法
工厂间转储表面上只是一步和二步的区别,但它牵动的东西比同工厂调拨多一个量级——工厂是 MRP 运算的基本单位,也是库存归属、成本核算、甚至法人主体的边界。跨过这条线,库存就不只是"换了个地方",而是"换了个账本"。
3.1 301 与 303/305:工厂边界上的两张脸
301 是工厂间一步转储。MB1B 里填物料、发出工厂与库存地、接收工厂与库存地、数量,一次过账,一张物料凭证两个行项目,发出工厂减、接收工厂加,同时完成。
303/305 是工厂间二步。303 发货:发出工厂扣减,货进入跨工厂在途;305 收货:接收工厂增加,在途解除。这段时间的在途,就是 MB5T 里能看到的那部分。
从记账效率看,301 明显更省事。但从业务可控性看,301 有个致命弱点:它没有"中间态",也就没有"拦截点"。货一旦过账,发出工厂的账已经减了,接收工厂的账已经加了,中间没有任何环节允许你确认"这批货真的到了吗"。如果运输途中发生损耗、错发、被截留,系统里完全看不出来,只能靠事后盘亏去倒推。
二步转储把这段路程显式化了。303 之后,货在系统里处于"已发出、未接收",MB5T 上挂着一笔在途。这笔在途是有账龄的——挂了三天、三周还是三个月,一眼可见。对于跨城市、跨区域甚至跨境的长距离调拨,这个账龄就是管理抓手:超过阈值的在途必须有人去追。
我一般的理解是,一步转储适合"物理距离短、风险可控"的场景,二步转储适合"运输周期长、需要责任划分"的场景。这个判断标准跟系统能力无关,纯粹是业务风险的成本核算。
还有一个细节容易翻车:303 发货后,发出工厂的库存已经扣了,如果这时候接收工厂那边发现物料有问题拒收,你需要做的是冲销或者反向移动,而不是简单地"不做 305 了"。挂着不动的在途会一直占着发出工厂的账,时间久了没人记得这笔货是什么状态——这就是典型的历史遗留问题,越拖越难清。
3.2 MRP 视角下的转储订单:需求为什么必须留痕
这是整个模块里最容易被低估的一点:工厂间转储会参与 MRP 运算。
MRP 的逻辑是"看供给、看需求、算缺口"。当你用 301 把 100 个物料从 A 工厂挪到 B 工厂,MRP 看到的是:A 工厂库存突然少了 100,B 工厂库存突然多了 100。它会认为 B 工厂供给充足,同时认为 A 工厂出现了缺口——但这个缺口是怎么来的、要不要补、什么时候补,系统一无所知,因为它看不到任何"需求单据"。
结果就是:A 工厂莫名其妙被建议采购,B 工厂却囤着货。这种"一边缺料一边压库存"的局面,是手工转储最典型的后遗症。
转储订单(Stock Transport Order,STO)解决的正是这个问题。它用一张采购订单的壳子,把"我要从 A 工厂调 100 个到 B 工厂"这件事变成一条有开始、有结束、有数量的需求记录。MRP 读到这张单,就知道 A 工厂有 100 个的供应责任、B 工厂有 100 个的需求,供给需求两头都对上了。
所以原文那句"考虑工厂间转储涉及 MRP 运算(库存需求传递),工厂间转储应采用转储订单方式操作",不是一句建议,是一条硬约束。凡是会进入 MRP 视野的物料,工厂间转储就不该用 301 裸奔。
STO 有两条实现路径:MM 功能和 SD 功能。MM 路径下,STO 就是一张特殊的采购订单,发货走移动类型 351(或 303/305),收货走 101 之类;SD 路径下,STO 会触发销售订单和交货单,走完整的装运流程,适合需要运输单据、需要计费、需要外部承运商的场景。大部分纯内部调拨用 MM 路径就够了,SD 路径是为了那些"调拨本身也要走商务流程"的场景准备的。
3.3 309 物料到物料:移动平均价差异从哪冒出来
309 处理的是"物料号变了"的转储——同一批东西,在系统里从物料 A 记成物料 B。它最典型的用途是同一物料在不同工厂或仓库之间移动平均价不一致时做价值调整。
机制是这样的:物料在工厂层级维护移动平均价,不同工厂的采购历史不同,价格自然不同。309 过账时,发出方按自己的移动平均价把价值转出,接收方按自己的移动平均价把价值接收,两边一减,差额就出来了。这个差额不会凭空消失,它会进到差异科目里去。
发出方:数量 N × 发出方移动平均价 P1 → 转出价值 V1 = N × P1 接收方:数量 N × 接收方移动平均价 P2 → 接收价值 V2 = N × P2 差额:ΔV = V2 - V1 → 过账到价格差异科目这段推导解释了为什么"一般不建议采用此方式":每一次 309 都在制造一笔差异,差异累积起来会让成本分析变得极其难读。你以为只是挪了批货,财务那边多出一堆差异凭证要解释。
如果物料用的是标准价而不是移动平均价,情况会更糟——标准价物料的 309 会把全部差额推进差异科目,数量和金额的对应关系彻底断掉。所以这条路只在确实需要"改物料号"的极少数场景下用,绝不能当成日常调拨工具。
4. 后台配置的因果链:转储单类型、装运数据与 SD 开关
前台操作能不能跑通、跑出来是什么形态,几乎完全由后台几个配置节点决定。这几个节点之间是因果串联的:凭证类型决定这张单子是什么身份,装运数据决定它走不走 SD,号码范围决定它的单号落在哪。任何一个环节没配上,前台就会出现"能过账但结果不对"的诡异现象。
4.1 采购订单凭证类型:给转储业务一个身份
转储订单本质是一张采购订单,所以它必须先有一个凭证类型。配置路径在采购模块下,核心动作是给"库存调拨订单"分配凭证类型。
这里的关键是单据类别和凭证类型的组合。凭证类型决定号码范围、字段控制、审批策略;单据类别决定这张单在系统里被当成"标准采购订单"还是"库存转储订单"处理。UB 这类凭证类型之所以特殊,就是它的单据类别被定义为库存转储,系统据此知道"这张单不产生对外采购,只产生内部调拨"。
配置错位的典型症状是:单子能建,但发货时移动类型带不出来,或者带出来的是采购收货的移动类型而不是转储发货的移动类型。这时候别在前台反复试,直接回去看凭证类型分配对不对——前台的一切异常,八成能在后台找到根。
4.2 工厂装运数据里的「一步/二步」开关
这是整个配置链里最有意思的一个节点。它要维护的信息包括:工厂、对应的客户(内部客户,代表收货方)、是否采用一步转储、转储单类型。
那个"是否一步转储"的勾选框,本质上是一个流程分支开关:
- 勾上:STO 发货时直接一步过账,不生成交货单,走的是 MM 内部的移动类型。
- 不勾:STO 发货时会生成交货单,走 SD 的装运流程,需要拣配、包装、发货过账一整套动作。
这个设计的动机很实在。一步转储适合"自己的车、自己的人、几公里路"的场景,没必要为一段短途运输生成一堆单据;二步转储适合"要走第三方物流、要出运输单据、要跟踪"的场景,交货单就是那个跟踪载体。
配置里的"客户"字段是另一个隐形开关。这个客户不是真实的外部客户,而是系统里代表"收货工厂"的内部客户。填了它,系统才知道收货方是谁,才可能生成交货单;不填,这条路就走不通。原文提到"此处填写则会生成出货单,采用的是 SD 方式",说的就是这个机制。
转储单类型(比如 NB)则是告诉系统"生成交货单时用哪种单据类型"。NB 是标准采购订单的类型,配在这里意味着这条 STO 链路会借用标准采购的装运逻辑。
4.3 UB 与 NB 的分野:351 为什么会掉进 4500
UB 和 NB 最核心的区别在于走不走 SD。UB 不采用 SD 方式,不生成出货单,整条链路封闭在 MM 内部;NB 配合工厂装运数据里的客户配置,会触发交货单,把 SD 拉进来。
这个区别直接决定了发货时用哪个移动类型。走 MM 内部一步转储的,用 351 这类移动类型;走 SD 的,交货单发货过账时会用另一套移动类型。同一个业务动作,因为配置不同,落到账上的移动类型就不同——这也是为什么两个人做同样一件事,物料凭证长得完全不一样。
至于原文提到的 351 过账后单号落到 4500 这个号段,常见的实现思路是:这类凭证的号码范围对象没有被显式维护,系统退回默认段分配。单号能生成,凭证能过账,看起来一切正常,但对账时会发现这批单据混在一个不属于它们的号段里,按号段归集业务时怎么都对不上。
提示:号码范围这类"不影响过账、只影响追溯"的配置,是最容易被跳过的一类。它不会让流程报错,只会让你在半年后做数据归集时抓瞎。
排查顺序建议固定下来:先确认凭证类型分配,再确认工厂装运数据里的客户和一步转储勾选,最后确认号码范围。这个顺序对应"身份 → 流程 → 编号"三层,从粗到细,避免在细节里打转。
5. 排查与避坑:五类把库存搞丢的典型现场
库存调拨的问题有个共同特点:过账当时一切正常,问题在几天甚至几周后才浮现。等发现时,当事人早忘了当时点了什么。下面这几类是踩得最多的,按"现象 → 原因 → 解决"记下来,能省不少排查时间。
5.1 现象:313 发了,315 迟迟没做,在途越挂越多
现象很直观:MB5T 或者 MMBE 的在途列数字持续上涨,发出工厂的可用库存被吃掉,接收工厂却一直缺料。
原因通常不是忘了做,而是没人认领这个动作。313 是发出方做的,315 是接收方做的,跨了部门甚至跨了工厂,责任链在中间断了。发出方认为"我发完了",接收方认为"我没收到货凭什么收",两边都没错,货就挂在中间。
解决要分两层。系统层面,建立按账龄分档的在途报表,超过阈值自动推给责任人,别等人想起来;流程层面,把 315 收货和实物签收绑定,签收单没回来就不许过账。我见过更狠的做法是把在途账龄挂到部门考核里,效果立竿见影。
还有一个技术性坑:315 收货时如果数量填错,冲销重做比直接改要安全。改历史凭证的连锁反应很难预估,尤其是在已经参与过 MRP 运算之后。
5.2 现象:工厂间转储做完,MRP 突然报 A 工厂缺料
现象是 MRP 运行后,A 工厂冒出一堆采购建议,而这些物料明明刚从 A 工厂调走,B 工厂那边还堆着。
原因是用了 301 这类无单据的裸转储。MRP 看不到任何需求记录,只看到 A 工厂库存凭空减少,于是判定为缺口。B 工厂那边库存凭空增加,MRP 判定为供给充足,不会再建议补货。
解决办法是把这类业务切到转储订单上。已经用 301 做过的历史数据,短期可以在 MRP 参数里做特殊处理把需求补回来,但这是打补丁,长期必须改流程。切换时要注意,STO 建单到发货之间也有时间差,这段差量同样会被 MRP 感知,所以转储订单的交期要填得贴近实际,别随手填个遥远的日期,那样需求会被推到很远的将来,等于没填。
5.3 现象:同一物料在两个工厂,金额对不上
现象是财务对账时发现,同一物料在 A 工厂和 B 工厂的库存金额,按数量折算出来的单价差异明显,而且这个差异在持续扩大。
原因是用了 309 做物料到物料的转储,每次过账都在制造价格差异。移动平均价物料还好,差异分摊进单价里;标准价物料就麻烦了,差额全进差异科目,库存金额和数量彻底脱钩。
处理思路是先停用 309 走日常调拨,再清理历史差异。清理时不要直接调账,先把每一笔 309 的差异来源列出来,确认哪些是合理的价格差、哪些是操作失误。合理的部分保留,失误的部分走冲销。这个活很枯燥,但跳过它,后面的成本分析永远做不准。
5.4 现象:351 过账后单号跳到一个陌生号段
现象是过账成功,但生成的凭证号不在预期的号段里,落在 4500 这个看着很陌生的段上。单子能用,也能冲销,就是对账时按号段归集怎么都对不上。
原因是号码范围配置缺失,系统退回了默认段。这类问题不影响业务流转,所以最容易被忽略,往往是几个月后做数据治理时才被发现。
解决办法是回到号码范围维护节点,确认这类凭证对应的号码范围对象是否已经分配了区间。分配之后,新产生的凭证会进正确号段,但历史凭证不会自动迁移,需要单独处理。所以这类配置最好在系统上线前就一次性配全,别等到跑了一年再补。
5.5 现象:冻结库存解冻后,数量对不上
现象是用 344 把非限制库存转成冻结,再用 343 转回来,两次操作的数量加起来和原始数量不一致。
原因多半是中间有人在冻结状态下做了其他操作,比如盘点、或者又做了一次状态转换。冻结库存虽然不可用于 MRP 和发货,但它仍然是一个可以被操作的状态,不是保险箱。
解决办法是给状态转换加上审批或者至少加上日志。344 和 343 这类移动类型看着无害,实际上每一次都在改库存的状态归属,链条长了就对不上。排查时直接查物料凭证里这两个移动类型的完整序列,按时间排序,哪一步数量跳变一目了然。
6. 设计取舍:二步转储的价值不在「多一步」
回到最开始那个问题:既然一步转储又快又干净,为什么系统还要费力设计二步转储,甚至为它专门维护在途状态、专门的报表、专门的责任链?
因为二步转储真正提供的不是"多一次过账",而是"一个可以被观测和干预的时间窗口"。
一步转储的哲学是"结果导向":只要最终库存对,中间过程不重要。这在同工厂、短距离、低风险的场景下完全成立,甚至是更优解——少一次操作就少一次出错机会。但它把风险藏起来了,一旦运输途中出问题,系统里没有任何痕迹可查,只能靠事后盘亏倒推。
二步转储的哲学是"过程可见":它承认物理世界存在运输时间,承认这段时间里货物处于一种模糊状态,然后把这种模糊状态显式建模。在途库存、账龄、MB5T 报表、315 收货确认,全都是围绕这个窗口长出来的。
这个取舍可以推广到整个系统的设计思路:凡是存在物理延迟、责任转移、风险敞口的环节,都值得在系统里留一个显式的中间态。反过来,凡是瞬时的、同主体的、低风险的动作,压缩成一步反而更好。判断标准不是"哪种更规范",而是"这段过程需不需要有人负责"。
再看 309 和 301 的设计,也是同一个逻辑的不同侧面。309 之所以"不建议采用",不是因为它技术上有缺陷,而是因为它把价值差异这个副作用暴露给了操作者,而这个副作用本应由定价或成本核算去处理,不该由调拨动作承担。301 之所以不建议用于 MRP 相关物料,是因为它绕过了需求留痕,让计划系统失去了输入。
这些取舍背后有一条共同的线:系统设计者把"业务语义"拆成了移动类型,用三位数字编码了"这是什么性质的移动、涉不涉及价值、涉不涉及需求、要不要留痕"。你在 MB1B 里敲的那个数字,其实是在选择一整套后续行为。
从那以后我每次做库存调拨方案,都会强制走一遍三个问题的自查:这段过程有没有物理延迟?有没有责任转移?会不会进入 MRP 视野?三个问题里只要有一个是"是",就老老实实走转储订单加二步,别图省事用 301 裸奔。图省事省下来的那点操作时间,迟早会在某次对账或者某次缺料事故里加倍还回去。希望帮到你。
本文还有配套的精品资源,点击获取