前阵子公司做系统切换,要把一条老的英文Smart Form从原系统原封不动搬到新的SAP环境,最后还要求在目标系统上落地俄语版本。听上去就是“传个对象、再翻译一下”的事,真做起来才知道,Smart Form跨系统传输和多语言翻译这两件事凑在一起,坑比想象中多得多。这篇就把我从对象盘点、传输请求打包、STMS导入,到俄语文本维护、字体修改、调用语言参数这一整套流程的实操过程完整写出来,给后面要干同样活的同事做个参考。
Smart Form这个技术虽然不算新,但在很多企业里仍然承担着发票、订单确认、交货单这些核心打印输出。只要涉及系统升级、分库、海外本地化,基本都会碰到“把表单搬过去”和“把表单翻译成当地语言”这两个需求。这篇文章适合SAP顾问、ABAP开发、Basis运维以及负责海外上线表单支持的人看,读完至少能把“英文表单搬到新系统”和“在目标系统维护俄语版本”这两件事的完整路径搞清楚,少走几趟弯路。
1. 项目概述与需求拆解
1.1 Smart Form跨系统传输到底在传什么
很多人以为Smart Form就是一个“文件”,类似Word文档,复制过去就行。实际完全不是这么回事。在SAP里,Smart Form是一个由多个对象共同组成的复合对象:表单主对象本身、表单依赖的样式(Style)、界面上用到的文本节点、文本符号、图形标志(比如Logo)、以及表单运行所需的函数模块等。
传输的时候,如果把Smart Form当成单一对象加进传输请求,系统一般会自动把主对象打进去,但是样式、图形这类附属对象不一定都会自动带上。尤其是Logo这类存在SE78里的图形,它属于BDS(Business Document Service)对象,很多时候需要手工单独加入传输请求,漏一次就够你喝一壶的。
打个不太严谨的比方,Smart Form像是一个打包好的文件夹,里面有正文、样式模板、素材图片、字体设置清单。你只把文件夹里的某个文件拷走了,其余内容还留在原系统,那到了新系统,这个表单要么打不开,要么打开之后样式全乱、图片显示成红叉。
1.2 为什么英文表单还要另做俄语版本
需求听起来也简单:原系统里有一条现成的英文Smart Form,新系统上线后用户主要用俄语,业务方要求打印出来的单据是俄语版本。很多人第一反应是把英文文本翻译成俄语就行,但实际要考虑的事情远不止“翻译”这一步。
首先,目标系统有没有安装俄语语言包?如果没有,界面上也许还能看,但你在编辑器里输入俄语可能直接显示问号,打印出来就更乱。其次,Smart Form里的字体不一定支持西里尔字母,Arial这类标准字体在非Unicode系统上对俄语支持并不好,需要换成带Cyrillic扩展的字体。再次,俄语单词普遍比英文长,同样一句话翻译成俄语之后,文本节点的高度、宽度可能就不够用了,行高溢出、内容截断、换页问题都会跟着来。
再加上一个最容易被忽略的点:表单翻译好之后,程序调用时如果不把语言参数传进去,SAP还是会按照默认语言或者登录语言去取文本,等于你翻译了半天,打印出来还是英文。这些问题环环相扣,少考虑一个,线上就得多返工一次。
2. 传输前准备与对象盘点
2.1 先把表单的“户口”查清楚
动手传之前,我习惯先在源系统把表单的完整依赖关系盘一遍。用SMARTFORMS事务代码打开表单后,不要急着改东西,先看几个地方。
第一是表单名称和描述,确认你要传的是哪个版本,最好顺带记一下当前激活的版本号。第二是文本节点的数量,尤其是有多少内嵌在页面布局里的硬编码文本,这些是后面翻译的工作量大头。第三是表单有没有挂样式,如果挂了,样式名称是什么,样式里是否定义了特定语言的字符格式。第四是图形引用了哪些Logo,去SE78里查一下这些Logo是否存在。第五是表单里有没有用子表单,子表单对象也要一并纳入传输范围。
这一步不用花太多时间,但能避免后面导入目标系统之后才发现缺这缺那。我把这个检查项整理成了一个小清单,每次跨系统搬表单都用这个套路。
| 检查项 | 查看方式 | 是否影响传输 |
|---|---|---|
| 表单主对象及版本 | SMARTFORMS打开后看属性 | 必传 |
| 样式引用 | 表单属性里查看Style名称 | 必传,独立对象 |
| 文本符号(Text Symbols) | 表单菜单栏的Text Symbols入口 | 随主对象传输 |
| 图形Logo | SE78查询Name/ID | 常需单独加入请求 |
| 子表单引用 | 页面布局里检查Subform节点 | 必传,独立对象 |
| 字体设置 | 文本节点/段落格式里的Font属性 | 不传输,目标系统需本地支持 |
| 调用函数模块名称 | SSF_FUNCTION_MODULE_NAME检查 | 运行期动态获取 |
这个表看起来琐碎,但实际项目里,十次传输至少有两次会因为漏了样式或者Logo出问题,所以前期花十分钟盘一遍,比上线后排查一小时强得多。
2.2 图形、样式、字体这些“后勤”别漏了
传输请求里加上Smart Form主对象之后,很多人就认为完事了。实际上,图形和样式才是最容易出问题的两个点。
图形方面,Smart Form里的Logo通常是通过SE78维护的,这类对象属于BDS,打包进传输请求的方式和普通表单对象不一样。在SE09创建传输请求之后,可以通过“对象列表”手工加入图形对象,或者在SE78里编辑图形时,通过“放置到传输请求”的入口把它加进去。如果忽略这一步,目标系统的表单即使能打开,打印出来的里的位置也是一个空白框或者一个叉号。
样式方面,如果在SMARTFORMS里给表单指定了Style,这个Style是一个独立对象,需要单独加入传输请求。特别是样式里定义了不同语言的段落格式、字符格式时,漏传样式会导致目标系统上的排版整个乱掉,明明源系统看起来好好的,到了新系统却对不齐。
字体这块比较特殊:Smart Form里的字体定义并不会随传输请求一起过去,因为SAP的字体机制依赖的是目标系统本身的字体资源。所以如果俄语显示不正常,你不能靠“传一个字体过去”来解决,而是要在目标系统的表单文本节点里重新设置字体属性,或者在操作系统/SAP GUI层面安装好支持西里尔字母的字体。
3. 跨系统传输完整流程
3.1 把表单装进传输请求的正确姿势
老手都知道一个规律:在SMARTFORMS里保存表单时,如果系统弹出传输请求对话框,那说明你把表单对象顺利放进了某个请求。但很多人不知道,如果保存的时候没有输入请求号,系统会把修改留在当前请求之外,后续你想用SE10补加也不是不行,但容易漏。
我推荐的操作顺序是这样的:
- 打开SMARTFORMS,输入表单名,进入修改模式。
- 不需要真的改动文本,只要对表单做一次“保存+激活”,系统就会判断是否有变更需要传输。
- 保存时在弹出的传输请求对话框中,新建一个请求,或者选择现有的开发请求。
- 保存后立即用SE10查看该请求,确认对象列表里出现了表单主对象。
- 如果表单挂了样式、用了Logo,用SE09/SE10把样式和图形对象也加进同一个请求。
- 和Basis确认该请求已释放,并且已安排STMS传输到目标系统。
这里有一个很关键的习惯:保存之后不要马上释放请求,而是先自己检查一遍对象列表。尤其是当你同时维护了多个开发任务时,很容易把不相干的对象混进同一个请求,导致生产环境导入了一些不该导入的东西。表单类的请求,对象越干净越好。
3.2 目标系统导入与激活验证
传输请求到了目标系统之后,STMS导入日志通常只能告诉你“导入成功”还是“导入失败”。但“成功”并不代表表单就能用。我每次都会在导入完成后,到目标系统用SMARTFORMS把表单打开一次,看两个东西:一是版本号是不是源系统最新版本,二是表单检查(Check)是否通过。
如果检查结果里有红色报错,比如找不到样式、找不到图形、子表单位置异常,那就说明传输不完整,不要试图在目标系统里“补改”数据,因为这样会让目标系统表单和源系统的版本分叉,后面再传一次会更乱。正确做法是回源头检查请求对象,补传缺失的部分,再重新导入。
还有一个细节:实际跑打印任务的时候,SAP会在应用服务器上对Smart Form做编译和缓存。如果导入后第一笔业务打印报错,或者打印出来还是老版本的内容,可以先在SMARTFORMS里手动执行一次激活,让服务器重新生成运行版本。实在不行就让Basis清一下相关缓存,不要一上来就改代码,很多情况根本不是逻辑问题,就是编译缓存没刷新。
4. 目标系统俄语版本落地实操
4.1 在SMARTFORMS里维护多语言文本节点
进入表单的页面布局,双击任一文本节点,打开文本编辑器,你会看到文本内容列表里有一列“语言”或者“原语言”的标识。默认情况下,节点里的文本只存在于表单源语言下。要在目标系统维护俄语版,需要为这个文本节点添加俄语语言行。
具体操作时,在文本编辑器的工具栏里找到“插入语言”或者直接在当前语言行后面增加翻译版本,把语言键设为R(SAP内部俄语语言键,ISO代码是RU),然后输入对应的俄语文案。保存之后,SAP会把这条文本作为该节点的俄语翻译版本存起来。
需要注意的是:SAP的表单文本节点有一个“原语言锁定”机制。如果表单的开发语言是英文,那么英文版本通常会被锁住,不能随便改;其他语言的翻译则可以自由维护。这个机制的本意是保护原始语言内容,但实际操作中经常出现“为什么我翻译不了”的疑问,其实就是因为当前登录语言恰好是原语言,需要在语言列里手动选择别的语言,或者切换登录语言后再维护。
4.2 文本符号(Text Symbols)的翻译处理
除了页面布局里的文本节点,Smart Form里还有一种常见的多语言元素叫文本符号,通常用于存一些短文本,比如“日期”“数量”“总额”这类字段标签。文本符号的维护入口在Smart Form菜单栏的“转到”里,打开后可以看到所有符号变量。
文本符号的多语言处理有一个特点:它在符号定义里可以维护多个语言的值。正常做法是在编辑页面把语言切换到俄语,然后为每个符号输入对应的俄语值。如果符号比较多,也可以通过SE63的事务,把Smart Form的文本符号作为翻译对象一起导出翻译。
这里要留个心眼:有些开发为了省事,会把固定文案写成ABAP代码里死字符串,再用变量传给表单。这种文案不在Smart Form的翻译范围里,在目标系统落地俄语版的时候,程序里的字符串也得一并处理。这已经不是“表单翻译”的问题了,而是“周边代码国际化”的问题,不少人在这里栽跟头。
4.3 俄语字体选择和打印验证
翻译完成后,先别急着发到生产,一定要先做打印预览。俄语和英文在字符形状上差异很大,如果字体不支持西里尔字母,预览出来就是一片空白框或者问号。
在非Unicode系统上,最常见的处理方式是选择Arial Cyr、Times New Roman Cyr这类带Cyrillic扩展的字体。如果在Unicode系统上,一般SAP标准字体组合也能支持,但为了保险起见,建议测试环境中先试打印几份,确认预览和SP01里看到的输出都是正常的俄语字符。
另一个常见问题是行高不够。俄语单词通常比英文长,同样一句“Delivery Note”,俄语可能是很长的一个词,如果文本节点高度固定,内容就会溢出到下一行,甚至被截断。处理方法是:把文本节点的“垂直对齐”和“自动高度”打开,让节点随内容自动扩展。如果表单有严格的版面限制,那就需要针对俄语版本微调字体大小或者节点宽度,这部分只能一条一条节点调,没有捷径。
调用表单时,如果要用俄语输出,必须在运行时传入语言参数。以ABAP代码为例:
DATA: lv_fm_name TYPE rs38l_fnam, ls_control TYPE ssfctrlop. CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME' EXPORTING formname = 'ZSMART_FORM_EN' variant = ' ' direct_call = ' ' IMPORTING fm_name = lv_fm_name EXCEPTIONS no_form = 1 no_function_module = 2 OTHERS = 3. CHECK sy-subrc = 0. ls_control-langu = 'R'. " 俄语 ls_control-nodialog = 'X'. CALL FUNCTION lv_fm_name EXPORTING control_parameters = ls_control * ... EXCEPTIONS formatting_error = 1 internal_error = 2 send_error = 3 user_canceled = 4 OTHERS = 5.注意这里面最关键的就是ls_control-langu = 'R',如果这里不传,表单就会按登录语言或者系统默认语言生成,你维护好的俄语文本压根不会生效。
5. 常见问题与排查技巧
5.1 传输后表单打不开或版本不生效
典型故障是:STMS显示导入成功,但目标系统SMARTFORMS里找不到这个表单,或者打开之后内容还是老版本。
排查思路要分成两步走。先检查SE10/SE09里请求是否已经释放,很多时候开发顾问以为保存进请求就算完事,实际上请求还在“可修改”状态,根本没释放,Basis自然无法传输。再看STMS导入日志,重点看有没有对象报错,有些对象在导入时会因为版本冲突或者系统间对象不一致被跳过。
如果这些都正常,那多半是服务器缓存问题。在SMARTFORMS里打开表单,执行一次“激活”操作,强制重新生成运行版本。还有一招是让Basis重启后台打印相关的Spool进程,也能解决一部分“打印出来还是旧版”的诡异问题。
5.2 俄语内容显示为方块或问号
这个问题一旦出现,用户会立刻认为是系统坏了。实际上原因通常是这几种之一:SAP GUI字体设置不对、表单里指定字体不支持Cyrillic、目标系统语言包缺失。
排查时先分清场景:如果在编辑器里看俄语都是方块,多半是SAP GUI字体问题,修改SAP GUI选项里的字体设置,选择支持西里尔字母的字体即可;如果编辑器里看着正常,打印预览却是方块,问题出在Smart Form的字体属性上,需要替换成Arial Cyr这类字体;如果系统连俄语输入都无法保存,那就是语言包/系统字符集的问题,这个就不是改表单能解决的了,需要Basis层面安装语言包。
5.3 翻译不生效,输出仍是英文
翻译明明维护好了,预览也正常,但通过程序打印出来还是英文,这种情况十有八九是调用程序没传语言参数。对照上一节ABAP示例,检查一下control_parameters-langu的值,确认传的是R而不是空值或者E。
还有一种情况是同一个Smart Form被多个程序调用,有的程序传了俄语,有的程序没传。这时候不要只改一个程序,先用“Where Used List”查一下这个表单被哪些程序调用,把所有入口都评估一遍,最好在程序里统一封装一个获取语言参数的逻辑,避免每个调用点各写各的。
5.4 俄语排版错乱、截断和跨页问题
这是我在实际项目里踩得最深的一个坑。英文版表单页面排得整整齐齐,到了俄语版,几行字变长,文本节点被撑大,后续所有窗口的位置全往下移,第二页甚至会多出大段空白。
当时排查了很久,最后发现根本原因有两个:一是文本节点高度设成了固定值,俄语内容一长就被截断,或者溢出导致页面重排;二是段落格式里的“行距”设置太死,俄语字符带重音符号之后,行与行之间互相压字。
最后的解决方式是:把所有涉及俄语的长文本节点全部设置为自动高度,并且把段落格式中的行距从固定值改为多倍行距,同时针对俄语版本微调了字号。这一步在源系统英文版上看不出区别,但俄语输出就稳定了。所以翻译完了之后,一定不要只看“有没有翻出来”,还要逐页对照打印效果,俄语内容尤其如此。
5.5 一套顺手的验证路径
做完上述所有修改之后,我的习惯是先不走正式打印程序,而是在SMARTFORMS里直接“预览”表单,把输出设备设为本地PDF,快速确认俄语内容、字体、排版都正常。接着再用实际业务程序跑一笔测试单据,到SP01里看打印输出。这两步都通过之后,才让顾问安排业务做最终验收。
强烈建议在测试环境就把这套验证路径固定下来,做成一个简单的测试清单。Smart Form多语言改造这类需求,最怕的就是“翻译完截图看起来没问题,生产上一打印全崩”,提前把验证路径走一遍,能避免很多上线后的救火。
最后说一点个人体会:Smart Form跨系统传输和俄语落地这件事,真正难的不是某个单点技术,而是“对象依赖”和“语言切换”这两条线串起来之后的系统性。传输漏一个对象,翻译漏一个语言参数,字体选错一种,都会让最终效果很差。做之前把对象盘清楚、做之中把语言跑通、做之后把打印验证到位,三步稳扎稳打,基本就能把这类需求顺利拿下。