SAP批量导入实战:BDC与LSMW选型、配置与避坑指南

发布时间:2026/10/29 18:55:36
SAP批量导入实战:BDC与LSMW选型、配置与避坑指南

简介:这份文档面向SAP顾问、运维人员及数据迁移实施者,系统讲解BDC与LSMW两种批处理工具的使用方法,帮助解决系统内批量数据处理与旧系统数据迁移的实际问题。资源包共1个docx文件,大小约2.49MB,内容以图文并茂的操作说明为主,涵盖SHDB录屏、脚本导出与邮件合并生成批量脚本、前台与后台执行模式,以及LSMW从对象创建、数据文件定义、源与目标结构映射到数据转换规则和传输的完整流程。文中结合公司代码逐月打开物料账期等实例,展示如何通过一次录像加多次执行完成重复操作,并对比两种工具在轻量级批处理与大规模数据迁移场景下的适用差异。目前已有1748人学习,适合希望掌握SAP批处理实操、提升数据迁移效率的读者参考。

1. 批量导入这件事,BDC 和 LSMW 到底该怎么选

SAP 里做批处理导入,绕不开两个名字:BDC 和 LSMW。很多做 SAP MM、SAP 出入库自学教程的同行,第一次遇到「几千条物料主数据要一次性建进去」这种活,第一反应是找 BAPI,结果发现字段对不上、校验过不去,最后还是回到这两个老工具上。BDC 本质是「录制屏幕操作再回放」,走的是和人工敲 T-code 完全一样的路径,所以校验逻辑、增强出口、权限检查一个都不会少;LSMW 则是「把数据映射到标准导入对象或录屏,再批量跑」,它自带数据读取、字段映射、转换规则这几层,适合字段多、来源杂、还要反复跑的场景。

这篇文章不讲概念史,只讲我实际交付时怎么选、怎么配、怎么排错。适合两类人:一类是刚接手数据迁移任务、手里只有 Excel 和 SAP GUI 的顾问或关键用户;另一类是写过 BDC 但总在「会话没跑完」「字段被截断」上翻车的开发。看完你应该能自己判断一个需求该用哪个工具,并且把最小可跑流程搭出来。

2. BDC 会话录制与调用:从 SHDB 到 CALL TRANSACTION

2.1 为什么 BDC 的可靠性来自「和人工操作同一条路」

BDC 的核心是「录屏」。你在 SHDB 里开一个录制,然后像正常操作一样走一遍事务码,系统把你每一步的屏幕号、字段名、输入值、回车行为全部记下来,生成一段可回放的会话。回放时 SAP 用 CALL TRANSACTION 或「会话方法」把这段操作重新执行一遍,所以它天然继承了所有前台校验:必输检查、外键检查、用户出口、BADI、甚至某些屏幕上的动态隐藏逻辑。

这也是它和 BAPI 最大的区别。BAPI 是绕过屏幕直接调函数,快、干净,但很多业务校验根本没走;BDC 慢、啰嗦,可它「所见即所得」。我一般这么判断:如果目标事务码有成熟的 BAPI 且字段能一一对应,优先 BAPI;如果字段对不上、或者业务方要求「必须和手工做出来一模一样」,那就 BDC。SAP 采购订单含税价格这类涉及条件技术的场景,BDC 往往比硬凑 BAPI 更省心。

录制时有个习惯要养成:用真实数据录,不要用 1、2、3 这种占位值。因为录屏记录的是字段的屏幕位置和值,占位值容易让你在后续映射时看不出哪个字段对应哪个业务含义。录完在 SHDB 里点「程序」,能看到生成的 ABAP 代码骨架,这段骨架就是后面批量调用的模板。

2.2 用 SHDB 录一段最小会话并读懂生成的代码

假设要批量创建物料主数据(MM01),先录一段。进入 SHDB,新建录制,输入事务码 MM01,走完整个屏幕流程,保存退出。系统会生成类似下面的结构(简化后):

* 录制生成的 BDC 数据表结构(示意) DATA: BEGIN OF bdcdata OCCURS 0. INCLUDE STRUCTURE bdcdata. DATA: END OF bdcdata. * 每个屏幕一段:DYNBEGIN 标记新屏幕,FNAM 是字段名,FVAL 是值 PERFORM bdc_field USING 'BDC_CURSOR' 'MARA-MATNR'. PERFORM bdc_field USING 'BDC_OKCODE' '/00'. PERFORM bdc_field USING 'MARA-MATNR' 'MAT-0001'. PERFORM bdc_field USING 'RMMG1-MBRSH' 'M'. PERFORM bdc_field USING 'RMMG1-MTART' 'FERT'.

这段代码里三个东西必须看懂:BDC_OKCODE是回车/保存动作,/00是回车,/11是保存;BDC_CURSOR告诉系统光标停在哪,某些屏幕不设会报「光标位置无效」;其余FNAM就是屏幕字段的技术名。批量时你把FVAL换成变量,循环填充bdcdata内表即可。

调用方式有两种。第一种是CALL TRANSACTION,同步执行,适合数据量小、要立刻知道成功失败:

CALL TRANSACTION 'MM01' USING bdcdata MODE 'N' " N=不显示屏幕,E=出错才显示,A=全显示 UPDATE 'S' " S=同步更新,A=异步 MESSAGES INTO messtab.

MODE参数是排错关键:调试阶段用'A'把屏幕显示出来,肉眼跟着走;生产跑批用'N'。UPDATE 'S'表示同步,程序会等数据库提交完再返回,这样messtab里能拿到真实的消息;用'A'异步的话,程序跑完了数据库可能还没写完,你查消息会扑空。

第二种是「会话方法」(Session Method),把数据生成一个后台会话,再用 SM35 去跑。它适合超大批量,因为可以分批、可以监控、失败了能单条重跑。代价是多一层会话管理,SM35 里会话状态、日志都得会看。

2.3 批量填充与消息收集的完整骨架

把上面拼成一个可复用的子程序结构:

FORM bdc_field USING fnam fval. IF fval IS NOT INITIAL. CLEAR bdcdata. bdcdata-fnam = fnam. bdcdata-fval = fval. APPEND bdcdata. ENDIF. ENDFORM. * 主循环:每条业务数据走一遍屏幕流程 LOOP AT gt_input INTO gs_input. REFRESH bdcdata. PERFORM bdc_field USING 'BDC_OKCODE' '/00'. PERFORM bdc_field USING 'MARA-MATNR' gs_input-matnr. PERFORM bdc_field USING 'RMMG1-MTART' gs_input-mtart. " ... 其余屏幕字段 CALL TRANSACTION 'MM01' USING bdcdata MODE 'N' UPDATE 'S' MESSAGES INTO messtab. " 收集结果 LOOP AT messtab WHERE msgtyp CA 'EA'. " 记录失败行与消息 ENDLOOP. ENDLOOP.

逻辑说明:bdc_field里加IF fval IS NOT INITIAL是为了跳过空值,避免把空字符串硬塞进屏幕导致「字段被清空」;MESSAGES INTO把每条消息收进内表,msgtyp为E(错误)或A(终止)的就是失败行。参数上,MODE和UPDATE按前面说的场景切换,messtab的结构是标准bdcmsgcoll,字段msgid/msgno/msgv1~msgv4拼起来才是完整消息文本,别只看msgv1。

3. LSMW 四步走:从录屏到批量导入的完整链路

3.1 LSMW 的四个层级,以及它比 BDC 多出来的那层价值

LSMW 全称 Legacy System Migration Workbench,事务码 LSMW。它把导入拆成四块:Maintain Object Attributes(对象属性)→ Maintain Source Structures(源结构)→ Maintain Source Fields(源字段)→ Maintain Structure Relations(结构关系)→ Maintain Field Mapping and Conversion Rules(字段映射与转换)→ Specify Files(指定文件)→ Assign Files(分配文件)→ Read Data(读数据)→ Display Read Data(显示)→ Convert Data(转换)→ Display Converted Data(显示转换)→ Create Batch Input Session(创建会话)→ Run Batch Input Session(跑会话)。

看着步骤多,其实核心就三件事:定义源文件长什么样、定义目标 SAP 对象长什么样、写两者的映射规则。它比纯 BDC 多出来的价值在于:转换规则层。你可以在映射里写 ABAP 代码做数据清洗,比如把外部系统的日期20240115转成 SAP 的20240115、把物料单位从「个」映射成「PC」、把含税价拆成净价加条件。SAP BOM 物料单位转换、SAP 物料分类视图和 BOM 这类字段结构复杂的场景,LSMW 的映射层能省掉大量手工预处理。

LSMW 支持多种「导入技术」:Batch Input Recording(录屏,等价于 BDC)、IDoc、BAPI、Direct Input。选哪种取决于目标对象有没有标准 Direct Input 程序。物料主数据、客户主数据、供应商主数据这些经典对象都有 Direct Input,走它最快最稳;没有标准对象的,就退回录屏。

3.2 用录屏方式建一个 LSMW 项目并跑通物料导入

第一步,LSMW 初始屏幕点「新建项目」,输入项目名、子项目名、对象名,回车。然后进「Maintain Object Attributes」,在「Import Method」里选Batch Input Recording,点「Recording Overview」新建一个录屏——这里和 SHDB 录屏是同一套东西,录一遍 MM01。

第二步,定义源结构。进「Maintain Source Structures」,建一个层级,比如MATERIAL_HEAD。再进「Maintain Source Fields」,把 Excel 里每一列的名字填进去,比如MATNR、MTART、MEINS、MATKL。字段类型和长度按实际给,长度给短了读文件时会截断,这是血泪经验。

第三步,结构关系。进「Maintain Structure Relations」,把源结构和录屏生成的目标结构关联起来。录屏方式下目标结构就是录屏的屏幕字段集合。

第四步,字段映射。进「Maintain Field Mapping and Conversion Rules」,把源字段拖到目标字段上。需要转换的,在目标字段上写 ABAP 代码:

* 目标字段 MATNR 的转换规则示例 MATNR = |{ MATNR ALPHA = IN }|. " 外部物料号补前导零 * 目标字段 MEINS 的转换规则 CASE MEINS. WHEN '个'. MEINS = 'PC'. WHEN '箱'. MEINS = 'CAR'. WHEN OTHERS. MEINS = MEINS. ENDCASE.

逻辑说明:ALPHA = IN是 SAP 里处理前导零的标准写法,外部系统给的物料号往往不带前导零,直接导进去会报「物料不存在」;单位映射用CASE是因为外部单位描述和 SAP 内部单位码不是一回事。参数上,转换规则里能用的就是标准 ABAP,但要注意它在 LSMW 的运行时环境里跑,别调用需要 GUI 的东西。

第五步,指定文件。进「Specify Files」,给源文件一个逻辑文件名,指定物理路径(前台跑就是本地路径,后台跑要放应用服务器)。进「Assign Files」把逻辑名和物理文件绑上。文件格式选「Tab Delimited」还是「Fixed Width」按你的文件来,Excel 另存为制表符分隔的 txt 最省事。

第六步,读数据、转换、建会话。依次点「Read Data」「Display Read Data」确认读进来的行数和内容对;点「Convert Data」「Display Converted Data」确认转换后的值对;点「Create Batch Input Session」生成会话;最后 SM35 里选中会话点「Process」。SM35 里能看到每条的成功失败,失败的可以只重跑那几条。

3.3 参数与文件格式的几个硬约束

LSMW 读文件对格式很挑。制表符分隔的文件,字段里不能含制表符;定长文件,每列宽度必须和源字段定义严格一致,差一位整列错位。日期格式默认按用户主数据里的日期格式解析,如果外部文件是YYYYMMDD而用户主数据是DD.MM.YYYY,读进来会全变空——这个坑我在 SAP 会计科目、SAP 冲销物料凭证的 BAPI 相关迁移里都见过,解决方法是读数据时在「File Format」里显式指定日期格式,或者在转换规则里自己拼。

还有一点:LSMW 项目本身是跨客户端的,传输时要连项目定义、源结构、映射规则一起传,只传一部分到生产会报「对象不存在」。SAP 请求(传输请求)里 LSMW 的对象类型是LSMW,别漏。

4. BDC 与 LSMW 的避坑与排查清单

4.1 会话跑完但数据没进去

现象:SM35 里会话状态显示「已处理」,但目标表里查不到数据。原因通常是UPDATE参数用了异步('A'),程序返回时会话还没真正提交,或者录屏时漏了最后的保存动作(BDC_OKCODE = '/11')。解决:把UPDATE改成'S'同步;检查录屏最后一步是不是真的按了保存,SHDB 里回放一遍看最后有没有「已保存」提示。

4.2 字段被截断或前导零丢失

现象:物料号000000000100000001导进去变成100000001,或者长文本被砍掉一半。原因:源字段长度定义短了,或者没做ALPHA = IN转换。解决:源字段长度按外部文件实际最大长度给,宁长勿短;所有 SAP 内部带前导零的字段(物料号、客户号、供应商号、会计科目号)在映射里统一加ALPHA = IN。

4.3 屏幕字段名对不上导致「字段未找到」

现象:回放时报「字段 XXX 在屏幕 YYY 上不存在」。原因:录屏时用的字段名和实际屏幕字段名不一致,常见于同一事务码在不同配置下屏幕布局不同,或者录屏时跳过了某个屏幕。解决:用 SHDB 重新录一遍,录的时候把每个屏幕都走全;或者用「屏幕字段帮助」确认技术名。SAP MD04 怎么看、SAP MD07 这类查询事务码本身不涉及导入,但如果你录的是带选择屏幕的事务码,选择屏幕字段名尤其容易录错。

4.4 LSMW 读文件读进来是空行或乱码

现象:Read Data 后行数对但内容全空,或者中文变问号。原因:文件编码不是 UTF-8 或 SAP 代码页不匹配,或者分隔符选错。解决:Excel 另存为「Unicode 文本」或 UTF-8 的 txt;LSMW 里文件格式的分隔符和实际文件严格一致;中文环境注意代码页,必要时在转换规则里做字符转换。

4.5 大批量跑一半卡死或超时

现象:几万条数据跑到一半程序 dump 或长时间无响应。原因:CALL TRANSACTION同步模式逐条提交,数据量大时数据库压力大;或者内表没及时清理导致内存膨胀。解决:改用会话方法分批生成,每批几千条,SM35 里分批跑;循环里REFRESH内表;必要时用COMMIT WORK控制提交节奏。SAP 出入库自学教程里那种「一次性导几万条物料凭证」的需求,基本都得走会话方法。

5. 进阶:把 LSMW 录屏和 BDC 会话组合起来用

真正做项目时,纯 BDC 和纯 LSMW 往往都不够用,我一般会组合。思路是:用 LSMW 做数据读取、清洗、映射,用 BDC 会话做最终执行。因为 LSMW 的映射层写 ABAP 比在 BDC 程序里硬编码灵活得多,而 BDC 会话在 SM35 里的可监控性又比 LSMW 直接跑强。

具体做法:LSMW 走到「Create Batch Input Session」这一步,生成的会话其实就是一个标准 BDC 会话,存在BDCDATA相关的会话表里。你可以在 LSMW 里只做到「Convert Data」,然后用自己写的程序读转换后的数据,自己拼bdcdata内表,自己CALL TRANSACTION或生成会话。这样映射规则复用 LSMW 的,执行控制权在自己手里。

验证方法上,我习惯做「三对照」:源文件行数、LSMW 读进来的行数、SM35 里会话的成功行数,三个数必须能对上,对不上就逐层查。再抽 3 到 5 条,手工在 SAP 里做一遍,和导入结果逐字段比对。SAP 序列号状态 edel 更新逻辑、SAP 物料变更底表这类涉及后续状态流转的场景,导入完还要查底表确认状态字段真的写对了,不能只看会话成功。

一个具体技巧:LSMW 的转换规则里可以调用CONVERSION_EXIT_ALPHA_INPUT这类标准转换出口,比手写ALPHA = IN更稳,因为它处理了各种边界。还有,录屏时如果遇到弹出窗口(比如「是否覆盖」确认框),一定要把确认动作也录进去,否则回放时会卡在弹窗上,SM35 里表现为会话「未处理完」。

我自己踩过最深的一次坑,是录屏时用了一个带用户默认值的字段,测试环境默认值和生产不一样,结果生产跑出来全错。从那以后我录屏一律用显式赋值,不依赖任何用户默认。希望帮到你。

本文还有配套的精品资源,点击获取