对于刚接触SAP物料主数据批导的人来说,BDC这个词听起来总有一种“上古秘术”的感觉。尤其当你打开一个录好的“创建物料”批处理会话,看到一连串的字段名和值散落在屏幕上,物料的短文本、长文本、基本计量单位、物料组等字段挤在一起,很容易一头雾水。实际上,BDC(Batch Data Communication,即批处理数据通信)就是通过模拟用户在SAP GUI中的屏幕操作,把事务代码对应的全流程自动跑一遍。它不挑接口、不挑权限、只要你的账号能手工操作这个事务,它就能用会话方式批量执行。而我今天想专门聊的,是在这条技术路线上最容易被忽略、也最容易翻车的一环——文本格式。物料主数据里的“文本”,不光是那个短描述,还包括物料长文本、采购文本、销售文本等不同对象类型的文本,这些字段在BDC传参和屏幕捕捉时的格式、长度、换行、特殊字符处理,都有不少坑。这篇文章适合正在做物料批导、被MM01录屏折磨过、或者打算从零搭建物料自动化创建方案的读者,我会从概念一直讲到实操,尽量把那些没人写进文档的经验都摊开说。
1. BDC与物料主数据创建的对应关系梳理
1.1 BDC到底是什么类型的“批处理”
很多新人会把BDC和BAPI搞混。BAPI是面向业务流程的接口,比如用BAPI_MATERIAL_SAVEDATA传一个结构化的物料数据进来,参数的字段名清晰、对应关系明确,几乎是“干干净净”的直传方式。但BDC走的是另一条路,它更像“屏幕机器人”。你先手工跑一遍MM01事务,系统会把你在每个屏幕上的所有输入记录成一组“动作序列”,包括哪个程序、哪个屏幕、哪个字段、输了多少值、按了什么按钮、回车还是保存。然后你再把这组动作序列放到批处理会话(SM35)里执行,它就能按同样的顺序把几百上千条物料全部创建出来。
1.2 什么时候必须用BDC而不是BAPI
最典型的场景是:物料主数据里的很多增强字段是自定义的,直接挂在某个屏幕的子屏幕或标签页里,BAPI的标准参数根本不会包含他们。如果你用了某些行业解决方案或者公司内部加了大量自定义字段(比如行业特定属性、质量等级、放行状态),BAPI的映射表里找不到这些字段,硬传往往会被忽略或者报错。而BDC录屏是“所见即所得”,只要你能在屏幕上输入这些字段,它就能录进去、传进去。哪怕物料主数据的屏幕结构很复杂、视图很多(基本数据、工厂数据、会计视图、采购视图、MRP视图等),BDC照样一屏一屏地“按顺序点过去”,完全不受接口字段范围的限制。
但BDC也不是万能的。它的本质是模拟用户输入,所以它的运行效率和稳定性高度依赖屏幕顺序、操作习惯、字段变化。一旦某个屏幕因为增强、配置调整而多了一个必输字段,或者某个字段在版本升级后改了位置,BDC会话就可能卡住、报错、甚至中途终止。这也是我这些年做物料批导时最痛的地方——没有“标准答案”,只有“跟随版本不断维护”的命。
1.3 物料主数据创建的典型视图与文本字段分布
物料主数据不是一个只有一个屏幕的简单录入界面。创建物料(MM01)时,通常要经历一个视图选择界面(比如勾选基本数据1、基本数据2、销售数据、采购数据、MRP等),然后进入每个视图对应的屏幕。文本字段分布在不同视图里:
- 基本数据1视图:物料描述(也就是短文本),字段名MAKTX,长度通常为40字符。
- 基本数据1视图:基本计量单位(MEINS),它也有文本属性,但在BDC里是单位值,不是文本描述。
- 基本数据2视图:物料长文本区域,里面可以录入任意长度的多行文本,存储到MACKO/MACKT表。
- 采购视图:采购长文本,通常是供应商相关的文本信息。
- 销售视图:销售长文本,用于销售凭证打印时自动带出的文本。
- 质量和MRP视图里也有少量文本说明字段。
从BDC处理的角度,这些文本字段分为两类:一类是普通的字段值输入,直接填到屏幕字段;另一类是“文本编辑器”操作,需要调用SAP的文本编辑控件,在长文本框中输入内容并回车。后者在录屏时比较复杂,因为文本编辑器不是简单的单行输入框,它有内部格式、换行标记、页面布局等信息,直接往BDC的F-Table里塞一个字符串往往是不会成功的。
2. 文本格式在BDC中的处理原理
2.1 为什么要专门讲“文本格式”
做物料批导时,很多人的第一个版本只会传短文本,因为长文本搞不定。原因就在于,物料的长文本在SAP内部存储时不是普通字符串,而是带格式的多行数据。你用BDC录制的过程中,如果直接在“物料长文本”标签页输入文本并点“保存”,录屏结果里会捕捉到一次对文本编辑器的操作。这个操作的内部结构,通常包含了一个“开始编辑”的调用,以及后续的一系列按键和鼠标行为。简单粗暴的做法是直接给这些字段传值,结果发现值虽然传进去了,但换行符全部丢失、中文乱码、或者文本直接被截断到第一行。
2.2 长文本对象类型与存储逻辑
在SAP中,长文本不是存在某个普通字段里,而是存在独立的文本对象中。物料的短文本(MAKTX)是直接存在MAKT表里,但长文本存储在STXL表(以及STXH头表)里,每个文本都有一条“文本对象头”。对象类型通常是“MATERIAL”或“MAT�TEXT”等,再用一个唯一ID(物料号+工厂+语言等)来标识。BDC要往长文本里写内容,标准做法是通过函数模块(如CREATE_TEXT或SAVE_TEXT)来实现,但BDC本身不能直接调用函数模块,它只能模拟屏幕操作。所以BDC录屏得到的文本编辑器操作,执行时会触发SAP内部的文本编辑器事件,系统再调用对应的函数模块把内容写入文本对象。这也就解释了为什么仅仅把一段带换行符的文本塞到屏幕字段里,执行时会报“文本格式不正确”之类的错——因为文本编辑器的内部交互方式和普通字段完全不同。
2.3 文本格式的核心:换行、缩进与语言
物料长文本的换行符在SAP内部是以十六进制进行标记的。在BDC批处理会话中,你不能直接输入“\n”或“\r\n”,也不建议直接把ASCII码塞进去。正确做法是在录屏时记录用户“回车键”的动作,也就是说BDC的F-Table里会有一条以CH类回车方式进行的字段填充(或者在文本编辑器的初始行输入完整文本后,通过回车操作结束)。而且长文本里的换行是通过文本对象内部的“TDFORMAT”字段控制的,当我们看到一段文本在显示时有空行,它的内部可能是被一个空行分隔的多个段落,段落之间用特定格式符号标记。
语言也是一个必须处理的点。物料短文本是按语言分开存储的,创建时选择了语言KEY(比如中文是ZH),短文本只能在对应语言下维护。录屏时如果在登录语言是中文的情况下录入中文短文本,那BDC批处理会话执行时,也会以中文语言写入。但如果你在其他语言环境下执行这个会话,某些字段可能因为语言KEY不匹配导致短文本没有显示或写不进去。长文本更是如此,每个长文本对象都有语言属性,所以你在录屏时必须在会话内部先明确语言,再写文本。
3. BDC实现物料主数据文本创建的实操路径
3.1 录屏准备与事务代码选择
你需要在SAP GUI里打开录制功能,一般用事务代码SHDB或者菜单路径“系统-服务-批处理会话-录制”。录制的对象是事务代码MM01,并且在初始屏幕输入物料号(可以先用一个测试物料,比如ZTEST01)、行业领域(通常是“机械”或“标准”)、物料类型(比如ROH原物料)等。接着点击“选择视图”,把所有要创建的视图勾上(一般至少勾选“基本数据1”“基本数据2”“采购”“MRP”等)。录屏的操作顺序最好固定下来,我个人的习惯是:
- 输入物料号、行业、类型,回车。
- 在确认视图选择屏幕,勾选需要的视图,回车。
- 在“基本数据1”屏幕,输入物料描述(短文本)、基本计量单位、物料组、旧物料号等。
- 切到“基本数据2”屏幕,把文本编辑器的内容填好并回车。
- 依次进入采购视图、MRP视图等,填值并保存。
- 最后点击保存,并在提示“物料已创建”时回车。
整个过程要一气呵成,中间不要做多余的点击,不要弹额外的弹窗,否则录制出来的BDC记录会包含不必要的动作,后续执行时容易多出一些无谓的屏幕操作。
3.2 BDC录屏结果中如何识别文本字段
录制结束后,在SHDB里找到这条录屏记录,双击进去就能看到一行一行的“字段名 + 字段值”。文本相关的字段有几个明显标识:
- 短文本字段:一般出现在程序SAPLMGD1,屏幕0300左右,字段名是MAKTX,值就是物料的描述。
- 基本计量单位:字段名MEINS。
- 长文本相关:录屏时进入长文本编辑器的操作往往被记录为一个特殊的“CALL”或“EDITOR”动作。有些版本的SAP会把它录成“BDC_EDITOR_CALL”之类的内部格式,也可能只是普通BDC块里的字段填充动作,但对应字段名可能是“TDFORMAT”“TDLINE”等。
如果你想直接从录屏结果中手工整理BDC程序,那么你需要把每一行的程序名、屏幕号、字段名、字段值都记下来,然后在ABAP程序里按照这个顺序写入BDC_TABLE。一般结构是:
DATA: BEGIN OF bdc_tab OCCURS 0, prog TYPE bdc_prog, dynpro TYPE bdc_dynpro, dynbegin TYPE c, fnam TYPE fnam____, fval TYPE fval____, END OF bdc_tab.其中DYNBEGIN行用于标记新屏幕的开始,FNAM和FVAL用于填充字段。
3.3 在ABAP程序中构造物料短文本字段
最常见的做法是使用“BATCH INPUT”函数组里的动态程序。假设你有内表存储物料主数据(物料号、描述、计量单位、物料组等),代码大致如下:
DATA: t_bdc LIKE bdcdata OCCURS 0 WITH HEADER LINE. " 清空BDC表 REFRESH t_bdc. " 开始第一个屏幕 t_bdc-program = 'SAPLMGMM'. t_bdc-dynpro = '0060'. t_bdc-dynbegin = 'X'. APPEND t_bdc. " 输入物料号 t_bdc-fnam = 'MATNR'. t_bdc-fval = lv_matnr. APPEND t_bdc. " 输入物料类型等 t_bdc-fnam = 'MTART'. t_bdc-fval = 'ROH'. APPEND t_bdc. t_bdc-fnam = 'BISM'. t_bdc-fval = ' '. APPEND t_bdc. " 回车,进入视图选择层 t_bdc-fnam = 'BDC_OKCODE'. t_bdc-fval = '/00'. " Enter APPEND t_bdc. " 后续屏幕类似...短文本字段在“基本数据1”屏幕(通常是SAPLMGD1的0105屏幕)输入时,字段名是MAKTX。注意在传入这个字段时,一定要把文本格式规范化,不能有前导空格、不能有换行符,长度不能超过40个字符。如果你的物料描述来自Excel或上游系统,可先用FunctionModule(比如CONVERSION_EXIT_MATN1_INPUT)处理物料号,再用标准函数去掉前后空格和换行,或者用字符串拼接处理。
3.4 长文本字段在BDC里的三种传递方式
方式一:不录长文本,通过BDC会话只创建物料主数据基本字段,然后在后续通过ABAP程序直接写文本对象(调用SAVE_TEXT)。这种方式BDC只管主数据的普通字段,文本另行处理。很多集成项目都是这么干的,因为它把BDC和文本问题剥离,稳定性最高。
方式二:在录屏时把长文本录入动作录进去,然后在使用录屏得到的BDC表时,把长文本内容预留为可替换的占位符,执行时用动态值替换。这种方式能一步到位,但对录屏要求很高,而且一旦文本编辑器版本不同,替换的字段名不一定正确。
方式三:物料的短文本和长文本都在BDC里处理,但长文本的每行数据使用BDC的一个字段“TDLINE”逐行传入。这种方式在特定SAP版本是可行的,但要注意每传完一行必须调用一次回车或确认操作,否则后续行会覆盖前一行。
我自己在实战中最推荐方式一。因为长文本的内容和格式管控(比如单位换算文本、检验说明等)更适合在程序层做清晰的控制,而不是去跟文本编辑器搏斗。如果你的项目里非得在BDC里传长文本,那么我建议至少把长文本的内容放到一个输入参数里(比如内存或内表),然后在BDC动作序列里用企业内部增强功能把长文本内容写入文本对象,这本质上也是方式一的变体,只是“时机”被放在了批处理过程中而已。
3.5 文本格式规范化处理:编码、大小写与回车符
对于短文本,最稳妥的预处理是:
- 去除两端空白。
- 把内部多个空格合并为一个空格。
- 禁止包含回车换行。
- 如果SAP系统配置了“大小写敏感”的物料描述,就按原始大小写传入;如果没有,则建议统一转大写(中文不受影响)。
- 注意不要用全角空格,容易导致字段长度看似符合但实际占用过多。
长文本的行数据在保存前,要注意每个段落的格式。SAP长文本支持段落格式,比如缩进、对齐等。如果文本内容没有复杂格式,最简单的是每行代表一个段落,行与行之间用空行表示段落间隔。换行符在长文本内部不直接以LF或CRLF存储,而是以宽度控制符表示,所以你传输给文本对象的每一行,长度不能超过那行规定的列宽(通常在屏幕上显示为132字符以下)。超过的会自动换行,但这就会导致你看上去的“行”和你期望的不一致。所以我建议先把文本按实际需要适当折行后再传。
另外,SAP支持从外部文件导入长文本的格式处理,可以读取一个本地的.txt或.rtf文件,然后解析为长文本行。但那是BAPI或程序内实现的方案,和BDC会话无关。在BDC录制时,如果你手动输入长文本并按回车,录屏结果中会捕捉到内部格式,执行批处理会话时能复现。但如果你想通过程序动态生成BDC数据,长文本的格式处理就变成“以行断句,逐行发送”的问题了。下面的示例展示了如何构造一个“长文本编辑器”的BDC数据:
" 假设lt_text是长文本内容内表,每行一行 LOOP AT lt_text INTO lv_line. CLEAR t_bdc. t_bdc-fnam = 'TDLINE'. t_bdc-fval = lv_line. APPEND t_bdc. ENDLOOP. " 结束长文本编辑操作 CLEAR t_bdc. t_bdc-fnam = 'BDC_OKCODE'. t_bdc-fval = 'EDIT'. APPEND t_bdc.但是这种写法并不能保证所有版本都有效。有些版本中长文本编辑器的字段名不是TDLINE,而是“TEXT_LINE”或“TDFORMAT”,而且需要先发一个进入编辑器的动作。所以,录屏之后直接检查生成的BDC记录,比盲猜字段名靠谱得多。
4. 文本格式处理的常见坑与排查方法
4.1 短文本“看似有值,保存后变成空白”的典型原因
这是物料批导新手最常碰到的诡异现象:BDC会话执行后,物料确实创建了,但打开物料主数据,短文本是空的,或者只是部分内容丢掉了。排查方法:
- 确认字段名是否写成了MKATX或MAKT,这属于手误,系统不会报错,但字段接收不到值。
- 确认语言Key。如果物料创建时的默认语言是EN或ZH,而短文本以另一语言存储,界面切换语言后看到的就是空的。
- 检查值长度,超过40字符会被后台静默截断,截掉的部分看不到。
- 检查填充的字段值是否含有“\n”之类的控制字符,SAP GUI在接收时会拒绝某些非法字符,表现为字段未更新。
4.2 长文本在批处理会话中报“文本对象不存在”或“格式不正确”
多半是因为BDC数据里缺少了创建文本对象的前置动作。长文本写入前,系统要先调用“创建/修改文本对象”的动作,比如按按钮“长文本”或“新建”,然后才进入文本编辑。如果你的BDC记录里只有TDLINE字段填充,没有这个前置动作,系统就不知道要把文本写到哪个对象头里。还有一种情况是物料号还没有保存,文本对象标识中的物料号还没生成,写文本时找不到标识,也会报错。所以处理顺序很重要:先保存物料主数据(产生物料号),再写长文本。
4.3 中文乱码与字符集问题
物料描述和长文本在存储时,默认是多字节字符集(Unicode),但BDC的数据传参依赖于SAP GUI的代码页。如果你的程序运行服务器与SAP系统使用不同语言环境,或者你在程序中直接拼接字符串时没有正确转码,就可能导致乱码。排查办法是先执行一个只传短文本的测试,如果乱码,说明编码转换有问题;如果正常,问题出在长文本编辑器对特殊字符的处理。
对于长文本,建议使用国际码(Unicode)的转换函数,例如SCP03,或者在调用BDC前把字符串先转换成SAP内部格式。注意不要用SQL直接UPDATE表,这样绕过了文本处理逻辑,容易出现不可预知的错误。
4.4 字段溢出与屏幕修饰符引起的失败
物料主数据有些字段(比如物料描述)在屏幕上是有输入帮助和自动补全的,BDC传入时可能会触发搜索帮助查找到多条记录,导致屏幕报错。因此,BDC值的传入往往需要额外的“WITH AUTHORITY-CHECK”或屏幕修饰符。简单说,你在录制时看到某个字段带有F4帮助按钮,执行批处理时可能因为默认的搜索帮助弹窗而没有结果,所以要在BDC编码中关闭搜索帮助(通过循环参数或设置“SKIP FIRST SCREEN”等方式),或给这些字段赋一个合法的完整值,避免二次查询。
4.5 如何高效排查BDC执行中的屏幕卡壳
执行批处理会话时,如果会话停在一个屏幕上显示红色报错,可以用SM35去看错误信息,点开详细日志能看到是哪个程序、哪个屏幕、哪个字段、什么消息。最常见的是两个:
- “输入物料类型不正确”或“物料号已存在”这类字段级错误,说明BDC表里那个字段的值不对。
- “屏幕不变量不可用”或“程序异常终止”,可能是录屏的增强或自定义控件在批处理时不支持。
实际项目中,我会做一个“逐行断言”的检查程序,把每条BDC记录按顺序回放,若某条字段的填值位置发生在当前屏幕上不存在,则自动跳过并记录下来。对长文本更是如此,因为不同视图顺序会导致文本编辑器的屏幕位置可能变化,所以最好在录制阶段就把屏幕顺序固定下來,然后程序中只替换物料号和相关值,避免结构变异。
5. 一个完整可复用的物料创建BDC程序片段
下面给出一个带“文本格式预处理”的示例代码,这个程序是从一个实际项目里精简出来的骨架。它负责读取物料主数据的内表(这里用自定义表ZMM_MASTER模拟),逐行生成BDC数据,并调用“CALL TRANSACTION”来更新物料主数据。代码本身不依赖任何外部公司和项目名,可以直接套在自己的系统里改字段。
5.1 数据结构与内表定义
TYPES: BEGIN OF ty_mat, matnr TYPE mara-matnr, " 物料号 maktx TYPE makt-maktx, " 短文本 meins TYPE mara-meins, " 单位 mtart TYPE mara-mtart, " 物料类型 matkl TYPE mara-matkl, " 物料组 END OF ty_mat. DATA: lt_mat TYPE TABLE OF ty_mat, ls_mat LIKE LINE OF lt_mat.实际使用时,你可以从文件、ALE/IDoc或者其他系统读取。需要注意的是输入物料号直接作为字符串处理时,要保证它是外部格式(前面可能有前导零)。建议使用转换例程“MATN1_INPUT”把外部物料号转成内部10位。
5.2 文本格式规范化的函数
FORM f_normalize_maktx USING iv_maktx TYPE string CHANGING cv_maktx TYPE makt-maktx. DATA: lv_len TYPE i. " 去掉回车换行 REPLACE ALL OCCURRENCES OF cl_abap_char_uc=>crlf IN iv_maktx WITH ''. " 去掉首尾空格 CONDENSE iv_maktx NO-GAPS. " 合并内部多个空格 WHILE iv_maktx CS ' '. REPLACE ALL OCCURRENCES OF ' ' IN iv_maktx WITH ' '. ENDWHILE. " 限制长度 lv_len = strlen( iv_maktx ). IF lv_len > 40. cv_maktx = iv_maktx(40). ELSE. cv_maktx = iv_maktx. ENDIF. ENDFORM.注意,CONDENSE ... NO-GAPS会去掉所有空格,这显然不对。你如果只想去掉两端空格,直接用CONDENSE(不指定NO-GAPS)即可。上面的写法是一个示例,实际上应该先CONDENSE去掉多余空格(保留内部单个空格),或者用SHIFT删除首尾。
正确写法:
CONDENSE iv_maktx. " 去掉多余空格,只保留单个空格这样就足够了。
5.3 生成BDC并调用事务
核心的BDC数据填充逻辑:
FORM build_bdc USING ls_mat TYPE ty_mat CHANGING lt_bdc TYPE TABLE OF bdcdata. DATA: ls_bdc LIKE LINE OF lt_bdc. " 屏幕1:初始屏幕,输入物料类型和行业等 ls_bdc-program = 'SAPLMGMM'. ls_bdc-dynpro = '0060'. ls_bdc-dynbegin = 'X'. APPEND ls_bdc TO lt_bdc. CLEAR ls_bdc. ls_bdc-fnam = 'MATNR'. ls_bdc-fval = ls_mat-matnr. APPEND ls_bdc TO lt_bdc. CLEAR ls_bdc. ls_bdc-fnam = 'MTART'. ls_bdc-fval = ls_mat-mtart. APPEND ls_bdc TO lt_bdc. CLEAR ls_bdc. ls_bdc-fnam = 'BISM'. ls_bdc-fval = ' '. APPEND ls_bdc TO lt_bdc. " 回车 CLEAR ls_bdc. ls_bdc-fnam = 'BDC_OKCODE'. ls_bdc-fval = '/00'. APPEND ls_bdc TO lt_bdc. " 屏幕:视图选择,直接回车进入基本数据1 CLEAR ls_bdc. ls_bdc-program = 'SAPLMGMM'. ls_bdc-dynpro = '0100'. ls_bdc-dynbegin = 'X'. APPEND ls_bdc TO lt_bdc. CLEAR ls_bdc. ls_bdc-fnam = 'BDC_OKCODE'. ls_bdc-fval = '=ENTR'. APPEND ls_bdc TO lt_bdc. " 屏幕:基本数据1 CLEAR ls_bdc. ls_bdc-program = 'SAPLMGD1'. ls_bdc-dynpro = '0105'. ls_bdc-dynbegin = 'X'. APPEND ls_bdc TO lt_bdc. " 短文本 CLEAR ls_bdc. ls_bdc-fnam = 'MAKTX'. ls_bdc-fval = ls_mat-maktx. APPEND ls_bdc TO lt_bdc. " 基本计量单位 CLEAR ls_bdc. ls_bdc-fnam = 'MEINS'. ls_bdc-fval = ls_mat-meins. APPEND ls_bdc TO lt_bdc. " 物料组 CLEAR ls_bdc. ls_bdc-fnam = 'MATKL'. ls_bdc-fval = ls_mat-matkl. APPEND ls_bdc TO lt_bdc. " 保存 CLEAR ls_bdc. ls_bdc-fnam = 'BDC_OKCODE'. ls_bdc-fval = '=BU'. APPEND ls_bdc TO lt_bdc. ENDFORM.然后执行:
DATA: lt_bdc TYPE TABLE OF bdcdata. DATA: lv_mode TYPE cmode VALUE 'A'. " A: 显示所有屏幕, N: 不显示 PERFORM build_bdc USING ls_mat CHANGING lt_bdc. CALL TRANSACTION 'MM01' USING lt_bdc MODE lv_mode UPDATE 'S' MESSAGES INTO lt_msg.注意,CALL TRANSACTION的MODE如果设成‘N’,执行过程不会显示屏幕,但错误信息要记录到内表里。这里UPDATE‘S’表示同步更新,保证物料当场创建。
5.4 一个让长文本也能正确进入BDC的补丁方式
很多项目最终采取的不是“录屏长文本”,而是在生成物料主数据之前/之后直接调用维护长文本的函数。具体做法:
- 先通过BDC创建物料主数据(不包含长文本字段)。
- 调用BAPI_MATERIAL_SAVEDATA或直接用函数UPDATE_TEXT把物料长文本写到对应对象。
DATA: lt_lines TYPE tline_tab, ls_line LIKE LINE OF lt_lines. ls_line-tdformat = '*'. ls_line-tdline = '第一行文本'. APPEND ls_line TO lt_lines.然后调用:
CALL FUNCTION 'SAVE_TEXT' EXPORTING template_id = 'MATERIAL' template_name = lv_matnr langu = 'ZH' save_directly = 'X' TABLES lines = lt_lines EXCEPTIONS OTHERS = 1.这样既绕开了BDC长文本的折磨,又保证了文本格式的完全可控。
6. 实操中值得记录的教训与心得
6.1 录屏时尽量选“最简视图组合”
如果你不需要在创建时输入所有视图,就不要把全部视图勾上。多一个视图就多一堆屏幕和字段,对BDC来说就是多一堆风险点,而且这些屏幕之间有些字段会联动(比如输入基本计量单位后,采购视图的某些字段会自动带出主数据),如果在执行时顺序不对,某些字段可能被系统忽略或报错。我习惯只录“基本数据1 + 基本数据2 + 采购 + MRP”必要视图,库存视图和会计视图要么用默认值,要么后续用BAPI再补充,因为它们的自定义字段往往最多。
6.2 测试前先拿临时物料号试跑
在所有环境(开发、测试、生产)都先跑一个不存在的物料号,不要一上来就使用正式编码段。因为物料类型和批量范围在后台配置不同,你录屏时的行业领域、物料类型和正式环境不一致的话,屏幕顺序会变。试跑能一次性暴露所有字段缺失和顺序问题。
6.3 文本格式的核心不是“写进去”,而是“读出来”
物料主数据的文本之所以难处理,还因为它在业务下游会被大量“读取”——打印、报表、接口传输。如果你只在创建阶段解决了“写”的问题,没有解决“读”的格式一致性问题,后面还是会出现单据打印时文本里带乱码、接口里带HTML标签等怪事。所以我在项目中通常把文本的展示规范与应用规则(比如是否保留行首空格、是否限制长文本行数)直接固化到共享的格式规范文档里,而不是每次创建时临时拍脑袋。
6.4 别用Excel拼接长文本
很多开发人员喜欢把Excel里的多行文本用CHAR(10)拼接,然后直接塞到BDC字段里,这是最不可靠的。Excel单元格文本的换行可能是CRLF(\r\n),也可能是LF(\n),跟SAP文本编辑器完全不是一回事。正确做法是:在ABAP中按行存入内表,或者把Excel提供的数据先按行拆分到数据库临时表,再逐行读取成“TDLINE”行,这样每一行都是独立的数据单元,处理后提交给文本对象。
6.5 批处理会话(SM35)模式下文本字段的注释
如果你用SM35手工处理批处理会话,一旦文本字段失败,会话会停在错误屏幕上,你可以在“维护会话”里手动修改字段值再重新处理。但如果你是程序调用CALL TRANSACTION,就享受不到这个“人工干预”的机会。所以要么用会话模式(SM35),要么在程序中捕获MESSAGES并判断错误字段后决定是否回滚。我的经验是当文本字段比较复杂时,优先用会话模式做“半自动”处理,第一轮让程序把物料主数据全部创建好,第二轮人工批量处理文本错误,效率会高很多,也避免整批失败。
6.6 别忘了测试“重复创建”场景
物料号重复在BDC执行时非常常见。因为物料主数据创建事务一旦发现物料已存在,就会跳到“修改”模式,屏幕结构完全不同,BDC里的许多屏幕步骤会失配。所以你要在程序里提前用“READ TABLE”或者查表判断物料是否存在,存在就跳过或者改为MM02,而不是让BDC硬跑。
7. 收尾前再补充一个关于文本格式的实用技巧
我个人做物料批量导入,最喜欢的方法是:将BDC和“文本接口函数”结合使用。BDC只负责创建主数据骨架(物料号、类型、单位、物料组、视图),文本内容(短文本和长文本)全部通过函数模块在程序里同步维护。短文本我用BAPI_MATERIAL_SAVEDATA里的扩展结构更新,长文本直接用SAVE_TEXT更新。这样做的原因很简单:文本内容的格式逻辑独立于屏幕操作,业务人员可以随时在配置表中修改文本模板,程序不用重录屏。同时,文本对象写入顺序在物料号生成之后,永远不会出现因为主数据未保存而写不进文本的尴尬。
如果你非要在BDC里传长文本,那我的最后建议是:录屏时先在“基本数据2”的长文本框里输入一段非常简单的“TEST”,然后保存。再到SHDB里查看这段录屏的内容,把它和你的程序里的BDC表结构对照。很多系统版本会把长文本录入拆成好几个BDC步骤:先是一个“='TEXT'”的OkCode或按钮动作,然后是一组“TDFORMAT/TDLINE”字段值,最后是一个“='EDIT'”的OkCode。照着这个结构去填,把你的每行文本映射到TDLINE即可。这样虽然麻烦一点,但至少比盲猜字段名可靠。
当然,如果你不是SAP开发出身,而是负责业务数据维护,看到BDC可能觉得离自己很远。实际呢,哪怕你是在SM35里手工录入一批物料,文本格式的规则也一样适用:短文本不要带换行,长文本一行一行录,语言栏目别选错,这些常识是跨技术方案的。项目做久了,你会发现物料主数据的所有问题,最后都会追溯到“描述不一致、文本乱码、单位不对”这些最基础的事情上。BDC只是手段,真正要管理的是主数据的质量和格式规范。如果能把“文本格式”这颗雷提前排掉,后面的路就会顺畅很多。