简介:围绕SAP库存调拨与发货流程整理的docx文档,面向SAP顾问、关键用户及库存管理实施人员,帮助梳理一步转储、二步转储、工厂间转储、物料到物料和物料状态转变等场景,并理解转储订单、在途库存与MRP运算的关联。压缩包仅含1个docx文件,约2.25MB,内容以流程说明、事务代码示例与后台配置要点为主,便于按主题查阅。已有1522人学习,在库存调拨入门与实操参考方面具有一定关注度。文档结合MB1B中311、313/315、301、303/305等操作,说明库存地与工厂之间调拨的差异,并补充MMBE、MB52查看在途库存的思路;后台部分涉及采购订单凭证类型分配、装运数据、一步转储设置、转储单类型及不生成出货单等配置,可帮助读者建立业务操作与后台参数的对应关系,定位关键节点和配置检查方向。
1. 一个上线前夜翻车的库存调拨
上线前一周,某开发者在测试客户端里用 MB1B 做了一笔 313,发货过账提示成功,回头 MMBE 一查,A 库存地少了 100 个,B 库存地一个没多,当场以为库存被系统吞了。数其实没丢,它正躺在“在途”里——313 只完成了转出,收货得再用 315 补一步。库存调拨最容易翻车的地方就在这:过账成功不等于账平,移动类型选错一次,后面要拿 311、315、MIGO 一点点倒推才能把账拉回来。
凡是上了 MM 模块的团队都会碰这套东西,但能把 311 和 313/315、301 和 303/305 的差别讲清楚的人不多。这篇笔记按我自己的习惯来:先把客户端、权限、库存地这些前置条件摆清楚,再一步步落到 MB1B 各移动类型的操作与后台配置,最后给一套自己能跑一遍的验证方法。
2. 动 MB1B 之前先盘环境:客户端、权限、库存地三件事
库存调拨的功能本身不复杂,麻烦全在“前置条件没齐”。我见过太多情况是事务码打得开、界面也填得进去,一回车弹个红框,然后开始怀疑是不是系统有玄学。多数时候不是玄学,是权限对象少了一个值,或者目标库存地在物料主数据里压根没扩展。这一章把动手前的三件事一次性摊开,照着核一遍,后面能省掉一大半排查时间。
2.1 客户端与事务码:MB1B 和 MIGO 该用哪个
先说版本差异,这个直接影响你笔记里记的操作路径。ECC 6.0 时代,MB1B 就是库存转储的绝对主力,一个事务码覆盖 311、313、315、301、303、305、309、344、343 全部场景;到了 S/4HANA,MB1B 作为兼容事务码还留着,日常操作没被强制切断,但新项目一般会往 MIGO 上引,尤其是带采购订单/转储订单的场景,MIGO 的凭证关联更完整。我的做法是:纯库存地之间的转储用 MB1B,手快、字段少;凡是挂了转储订单的发货和收货,走 MIGO,免得后面查凭证链的时候两头找不到。
还有两个容易忽略的环境项。一是客户端,转储测试千万别在定制客户端里做,物料凭证一过账就是真实数据,虽然可以用 MBST 冲销,但冲销凭证会留在凭证流里,给后面查账的人添堵;我一般在测试客户端(Customizing 之外的那个)跑完整流程。二是登录语言,MB1B 的字段标签在不同语言下差别不小,“收货库存地”“转储中”这些词在中文和英文界面对不上,你跟同事沟通时用词不一致,很容易鸡同鸭讲。
事务码本身在 S/4 里还有一个变化值得记一笔:报表层 MMBE、MB52、MB5T 都还在,但 Fiori 里对应的是“库存总览”“物料库存”这类应用,字段口径不完全一样。如果团队已经在用 Fiori,验证环节要按 Fiori 的报表再核一遍,别只信 GUI 的截图。
2.2 权限对象:报“没有授权”而不是“数据不存在”
MB1B 的几个典型报错里,最容易误判的就是权限问题。它有时候不直接说没权限,而是表现为“物料不存在”或者干脆进不去某个工厂,让人往主数据方向查半天。核心权限对象是这几个,让 BASIS 按下面的范围开:
| 权限对象 | 作用范围 | 常见取值 |
|---|---|---|
| M_MSEG_BWA | 物料凭证的移动类型/事务码 | 活动 01/02,移动类型 311、313、315、301、303、305 |
| M_MSEG_WWA | 物料凭证的工厂/库存地 | 工厂 A、B,库存地允许 * |
| M_MSEG_WMB | 物料凭证的物料类型 | 按物料类型或 * |
| M_BEST_WRK | 采购订单的工厂 | 转储订单场景必开 |
| M_BEST_EKO | 采购订单的凭证类型 | UB、NB |
只开 M_MSEG_BWA 不开 M_MSEG_WWA 是最常见的组合失误:311 能进界面,一发货就报“工厂未授权”,而界面上提示的错误文本往往指向后一行字段,很容易被带偏。我一般会让 BASIS 直接跑 SU53 抓一次失败记录,比对着报错猜快得多。
2.3 物料主数据与库存地:目标库存地必须先有档案
这条是血泪经验。MB1B 311 报“物料在库存地中不存在”,八成不是物料没建,而是接收库存地在物料主数据里没有扩展存储地点数据。库存地本身要在配置里定义(OX09,或 SPRO 里按工厂维护库存地清单),但光定义不够,物料还得用 MMSC 把存储地点视图扩出来,否则系统不认这个库存地能放这个物料。
下面这段 ABAP 可以放在 SE38 里自建,用来在动手前把物料、工厂、库存地三层条件一次核完,比一个个 SE16N 查表快:
REPORT zmm_stock_transfer_check. PARAMETERS: p_matnr TYPE matnr, p_werks TYPE werks_d, p_lgort TYPE lgort_d. START-OF-SELECTION. " 1. 工厂层是否有该物料档案(MARC) SELECT SINGLE matnr, meins, mtart, umlme FROM marc INTO @DATA(ls_marc) WHERE matnr = @p_matnr AND werks = @p_werks. IF sy-subrc <> 0. WRITE: / '物料在工厂层没有档案,MB1B 一定过不了账'. RETURN. ENDIF. " 2. 存储地点数据是否已建立(MARD) SELECT SINGLE lgort, labst, insme, speme, umlme, umlmc FROM mard INTO @DATA(ls_mard) WHERE matnr = @p_matnr AND werks = @p_werks AND lgort = @p_lgort. IF sy-subrc <> 0. WRITE: / '该存储地点还没有库存记录,先用 MMSC 扩展'. ELSE. WRITE: / |非限制: { ls_mard-labst } 质检: { ls_mard-insme } 冻结: { ls_mard-speme }|. WRITE: / |厂内在途(MARD-UMLMC): { ls_mard-umlmc } 跨厂在途(MARC-UMLME): { ls_marc-umlme }|. ENDIF.逻辑不复杂,但三个字段值得单独说。MARC-UMLME是跨工厂转储产生的在途库存,做 303 发货之后这个值会变;MARD-UMLMC是同工厂内部库存地之间二步转储的在途量,313 发货后它才动。最后一个MARD-LABST是非限制使用库存,311 转出时这里减,接收方库存地加。很多人排查时只看 MMBE 的合计,不看这两个在途字段,就会得出“数丢了”的结论。字段中文标签各系统可能不同,以你们环境里 SE16N 显示的为准。
3. 库存地之间怎么转:311 一步与 313/315 二步
环境核完就可以动手了。这一章只处理“同一个工厂内部,A 库存地到 B 库存地”这种最常见的调拨,一步和二步各走一遍,边做边看库存字段怎么变。二步这套东西是后面跨工厂转储的地基,这里的在途概念没吃透,第 4 章的 303/305 会更糊。
3.1 311 一步转移过账:库存和实物同时动
311 是转移过账,缺点是“账上动了,货还在路上”。物流实际没搬完,系统里已经认为库存到位了,盘点的时候就会出现账面有、货架没有的情况。所以 311 只适合那种物理位置紧挨着、或者本身就是同一片仓储区域内部调整的场景。
操作路径是 MB1B,输入移动类型 311,然后回车填字段。核心字段只有几个:物料、数量、工厂、发出库存地(转出)、接收库存地(转入,字段名一般是“接收库存地”或 Storage Location)、批次(如果物料启用了批次管理,必填)、凭证抬头文本(建议写清调拨原因和工单号,后期查账全靠它)。
事务码:MB1B 移动类型:311 物料:MAT-xxxxx 数量:100 工厂:1000 发出库存地:0001 接收库存地:0002 批次:(批次管理物料必填)过账之后,MB1B 会返回一个物料凭证号。这个号码要立刻记下来,后面查 MB51、做冲销、或者跟仓库对账都用它。验证只需两步:MMBE 输入物料和工厂,看 0001 减了 100、0002 加了 100;或者 MB51 输入凭证号,看凭证行项目里两行一正一负。
提示:311 没有在途环节,一旦过账库存立刻归属接收方。如果两个库存地不在同一栋楼,别用 311。
3.2 313/315 二步:在途库存是这么长出来的
二步转储拆成两笔凭证:313 是转出(发货),315 是转入(收货)。中间这段时间,库存不属于任何一个库存地,而是挂在“在途库存”里。这就是二步的真正价值——账面能反映货物在路上的事实。
第一步,MB1B 输入 313,字段和 311 几乎一样,除了接收库存地可以不填(真正的去向在 315 时确定)。过账后系统返回一个物料凭证号,这个号码是收货时的关键,必须记下来。此时 MMBE 查该物料,A 库存地少 90 个,同时在库存总览里能看到“在途”一栏有 90(原文场景里是 100 发货、90 在途、10 另有归属,具体以你实际数量为准)。
第二步,收货。有两条路:MB1B 输入 315,填物料、工厂、接收库存地、数量,然后在“物料凭证”字段填第一步那张 313 凭证的号码和年度;或者走 MIGO,操作选“收货”,参照选“物料凭证”,把 313 的号码带进来,系统自动把待收数量、物料、批次带出,只填接收库存地即可。后者更稳,字段不容易填错,我一般推荐新手用 MIGO。
第一步(转出) 事务码:MB1B 移动类型:313 物料 / 数量 / 工厂 / 发出库存地 -> 记录返回的物料凭证号,如 4900012345 / 2024 第二步(转入) 事务码:MB1B 移动类型:315 物料凭证:4900012345 年度:2024 接收库存地:0002 数量:90315 收货时最容易出的问题是数量对不上。313 发了 100,315 只能收 100 以内,多收系统直接拒绝;少收的部分会一直挂在在途里。这几笔在途如果没人清,月结的时候就会被拎出来问。我一般的做法是每周跑一次在途清单,超过三天的在途单独列出来找仓库确认,是货没到还是收货忘了录。
3.3 MMBE、MB52、MB5T 三张报表的分工
这三张报表都跟库存有关,但看的维度不一样,混着用会得出矛盾结论。下面这张对照表是我自己贴在工位上的:
| 报表 | 主要维度 | 适合看什么 | 在途支持 |
|---|---|---|---|
| MMBE | 物料 + 工厂 + 库存地 | 单个物料在某个工厂各库存地的明细,含在途列 | 支持,同工厂内的在途显示在该物料下 |
| MB52 | 工厂 + 库存地 + 物料清单 | 一批物料在某库存地的库存,或全工厂库存分布 | 不显示在途 |
| MB5T | 物料 + 跨工厂 | 不同工厂之间的在途库存 | 支持,专看跨厂在途 |
常用组合是:调拨完成先 MMBE 看单个物料的账,数量对得上再用 MB52 看整批物料的分布,确认没有别的库存地被误改。MB5T 平时用不到,一旦做了跨工厂二步转储,它就是唯一能说清在途的去处,第 4 章会再提。
顺带说一句 MB51。它不查库存,查的是物料凭证,输入物料或凭证号,能看到每一笔转储的移动类型、数量、库存地、过账时间、操作人。跟仓库吵架的时候,MB51 比 MMBE 有说服力得多,因为它是流水。
4. 跨工厂转储:301、303/305 与转储订单 UB
工厂间调拨和库存地之间调拨,操作上看着只差一个字段,实际差别很大:一是价值可能变(不同工厂同一物料的价格可能不同),二是 MRP 会介入。这一章先把两种转储方式走通,再落到后台配置,最后给一个我实际用得最多的方案——转储订单。
4.1 301 一步跨工厂:快,但 MRP 不认
MB1B 301 是工厂间一步转储,填物料、数量、发出工厂、接收工厂,过账后两个工厂的库存同时变,接收工厂立刻有可用库存。操作上确实爽,测试环境里三分钟能跑完。
问题在于需求传递。301 只是库存搬运,不产生采购申请、不产生转储订单,MRP 在跑的时候看不到“这批货本来要从 A 工厂来”,接收工厂可能重新算出一笔采购需求,转出工厂那边又可能算出过剩。数量一多,MRP 结果就会失真。所以工厂间转储我基本不用 301 做正式业务,只在紧急调拨、或者两个工厂其实是同一套 MRP 区域的情况下才用。
如果非要走一步,原文给的路径是 MB1B 351 做发货(这一步是针对转储订单的发货移动类型,不是 301)。这里面有一个细节:系统没有给这笔转储单分配号码范围,凭证编号落到了 4500 段,看起来不像标准的转储单凭证。这个现象本身就说明——这笔业务没走转储订单流程,系统只是按普通物料凭证处理了。
4.2 303/305 二步跨工厂:在途要去 MB5T 看
二步跨工厂是 303(转出工厂发货)+ 305(接收工厂收货)。操作方式跟 313/315 一样,第一步记凭证号,第二步用 MIGO 或 MB1B 305 参照收货。区别在验证:这里产生的在途是跨工厂在途,MMBE 在单个工厂下不一定能完整看出来,要去 MB5T 输入物料和两个工厂查。
第一步(转出工厂发货) MB1B 移动类型:303 物料 / 数量 / 发出工厂 1000 / 发出库存地 第二步(接收工厂收货) MIGO 操作:收货 参照:物料凭证 填 303 的凭证号 + 年度,接收工厂 2000 / 接收库存地305 收货的时候要特别留意接收工厂的库存地有没有扩展。跨工厂场景下,很多团队在 A 工厂建了全套库存地,B 工厂只建了常用的两三个,收货时随手一填就报错。这个坑我在第 5 章单独写。
4.3 后台配置:分配凭证类型与工厂装运数据
转储订单要跑起来,后台得先配两处。路径按 ECC 的 SPRO 结构写,S/4 里节点名称略有差异,用搜索功能按关键字找更快。
第一处,分配凭证类型。路径是 SPRO → 物料管理 → 采购 → 采购订单 → 设置库存调拨订单 → 分配凭证类型。这里按工厂指定转储订单用哪个采购凭证类型,常见取值是 UB(公司内部库存转储订单)或 NB(标准采购订单)。配好之后,ME21N 里选凭证类型 UB,系统才知道这是一张转储订单而不是对外采购。
| 配置项 | 路径关键节点 | 常见取值 | 影响 |
|---|---|---|---|
| 分配凭证类型 | 设置库存调拨订单 → 分配凭证类型 | UB / NB | 决定 ME21N 里能用哪种凭证类型建转储单 |
| 定义工厂的装运数据 | 设置库存调拨订单 → 定义工厂的装运数据 | 工厂客户、供货工厂、一步转储标识 | 决定走 MM 还是 SD、一步还是二步 |
| 转储单类型 | 同上 | NB | 收货工厂向供货工厂下转储单时使用的类型 |
第二处,定义工厂的装运数据,这是整套配置里最容易配错的一处。里面有三个关键字段:工厂客户(Customer)、供货工厂(Supplying Plant)、以及一个“是否采用一步转储”的勾选项。勾上,系统按一步方式处理,发货即入库;不勾,走二步,发货后收货前存在跨厂在途。工厂客户这个字段更是分水岭——留空,走 MM 方式,不生成出货单;填了,走 SD 方式,发货环节会生成出货单,还得配 SD 那边的装运点和路线。
原文的结论很清楚:UB 场景下不采用 SD 方式,不生成出货单,工厂客户留空,正确配置就到此为止;一旦在这里填了工厂客户,系统就会按 SD 逻辑生成出货单,后续的处理链完全不同。所以这一栏,配之前先跟业务确认到底走哪条路,不要凭感觉填。
4.4 用 UB 转储订单走标准流程
配置齐了之后,一次完整的跨工厂转储是这样走的:
1) ME21N 建转储订单,凭证类型 UB - 供货工厂:1000 接收工厂:2000 - 物料、数量、交货日期 2) MB1B 351 发货(或 VL10 走 SD 方式) - 参照转储订单号,从供货工厂发出 3) MIGO 收货 - 参照转储订单或物料凭证,在接收工厂入库第一步建单时,转储订单里的“供货工厂”和“接收工厂”填反是最常见的错误,填反了 MRP 需求方向就是反的,跑出来的计划订单全错。第二步 351 发货需要权限对象 M_BEST_EKO 放开 UB,否则连单都带不进来。第三步收货,如果前面配的是一步转储,发货即入库,收货这一步可以省;二步的话必须收,不收就一直挂着跨厂在途,MB5T 里能查到。
至于物料到物料方式(309),原文的建议是不建议采用,理由很实在:不同仓库或不同工厂的同一物料,移动平均价可能不同,309 转过去会产生价值差异,差异进哪个科目要跟财务对。物料状态转变(344 非限制转冻结、343 冻结转非限制)也是 MB1B,但它不涉及库存地搬运,属于状态调整,别跟转储混在一起看。
5. 排查与避坑:MB1B 最常撞上的五件事
这一章的每条都是照着“现象 → 原因 → 解决”写的,顺序按我遇到的频率排。
第一件,311 过账报“物料在库存地中不存在”。现象是物料明明有库存,接收库存地一填就红。原因是该库存地在物料主数据里没有扩展存储地点视图,工厂层有档案、库存地层没有。解决是用 MMSC 把接收库存地扩出来,再回 MB1B 重做。注意别用 MM01 重建物料,那是会覆盖已有视图的昏招。
第二件,313 发货成功,MMBE 里哪儿都找不到这 90 个。原因是看错字段了,厂内在途在 MARD 的 UMLMC 或者 MMBE 的在途列,不在任何具体库存地的可用数量里。解决是 MMBE 里展开该物料的在途行,或者直接 MB5T 查跨厂在途,确认数量后再做 315。有人在没确认在途的情况下又发了一笔 313,结果在途翻倍,后面要用 315 收两笔才能清,很麻烦。
第三件,315 收货时数量、批次带不出来。原因是 MIGO 里参照选错了,选成了“采购订单”或者“物料凭证”但年度没填。解决是参照类型选“物料凭证”,凭证号填 313 的那张,年度补上,回车后行项目自动带出。批次管理的物料还要确认批次特性已经维护,否则收货时批次字段灰着。这是典型的黑匣子问题,界面上报错不指路。
第四件,转储订单发货后凭证号落在 4500 段,看不出是转储单。原因是这笔业务没有走转储订单的号码分配,系统按普通物料凭证处理了,说明后台“分配凭证类型”那一步没配好,或者发货时没参照转储订单。解决是回头核 SPRO 里的分配凭证类型,确认工厂已分配 UB,然后按 ME21N → 351 的顺序重走一遍。已经过账的凭证用 MBST 冲销,别直接改后台。
第五件,跨厂二步转储后 MB5T 里有在途,但接收工厂说收到了货。原因是收货做成了 311 或者普通 101,没走 305,货进了库存但转储单没关闭。解决是查 MB51 看接收工厂那笔的移动类型,不是 305 的用 MBST 冲销后用 MIGO 参照原转储单重收。这类问题不处理,月末对账时在途和库存会同时对不上,比单纯少库存更难查。
6. 装完怎么验证:一套能跑通的数量平衡自检
配置和操作都走完之后,别急着交给业务,先自己做一轮闭环验证。我的做法是固定一个物料、固定两个库存地、两个工厂,跑 311、313/315、303/305 各一遍,每遍都核三个数:转出方减少量、转入方增加量、在途变化量。三个数加起来必须为零,不为零就是中间有环节漏了。
下面这张表是我验证时必填的,填不满就说明流程没走完:
| 场景 | 转出方变化 | 在途变化 | 转入方变化 | 平衡校验 |
|---|---|---|---|---|
| 311 一步 | -100 | 0 | +100 | 合计为 0 |
| 313 + 315 二步 | -90 | +90 后归 0 | +90 | 收货后在途必须清零 |
| 303 + 305 跨厂 | -100 | +100 后归 0 | +100 | MB5T 在途清零 |
| UB 转储单 351 + 收货 | -80 | 视一步/二步 | +80 | 转储单历史里状态为已收货 |
光看界面不够,最后再用一段报表把底层表核一遍,避免界面显示和实际库存记录不一致:
" 验证指定物料在两个库存地之间的转储是否平衡 SELECT matnr, werks, lgort, labst, umlmc FROM mard INTO TABLE @DATA(lt_mard) WHERE matnr = @p_matnr AND werks = @p_werks AND lgort IN (@p_lgort_from, @p_lgort_to). LOOP AT lt_mard INTO DATA(ls_row). WRITE: / |库存地 { ls_row-lgort } 非限制 { ls_row-labst } 厂内在途 { ls_row-umlmc }|. ENDLOOP. " 跨工厂在途单独看 MARC-UMLME SELECT SINGLE umlme FROM marc INTO @DATA(lv_umlme) WHERE matnr = @p_matnr AND werks = @p_werks. WRITE: / |跨厂在途: { lv_umlme }|.判断标准就一条:LABST的增减必须和凭证上的数量完全一致,UMLMC和UMLME在收货完成后必须回到零。有一项不为零,就回 MB51 按凭证号逐笔对,别在 MMBE 里反复刷新——界面刷新不解决数据问题,只能解决心理问题。
从那以后我每次配完一套库存调拨,都强制走一遍这个小闭环:先 311 验一步,再 313/315 验在途,最后拿一张 UB 转储单验跨厂,三步都过才敢让业务进来操作。这套自检清单和移动类型对照表我整理成了一份速查文档,连同上面那段校验程序放在一起,需要的话可以按文中的路径自己复现一遍,跑通了再往生产上搬。希望帮到你。
本文还有配套的精品资源,点击获取