SAP Smart Forms中文打印字体重叠:显式设语言版本
简介一份面向SAP ABAP开发与报表实施人员的DOC文档聚焦Smart Forms在英文登录环境中打印中文时出现的字体重叠、乱码及长文本压缩等常见问题。文档从语言环境设置入手说明在Smart Forms对应功能模块中为control_parameters-langu赋值1并借助SSFRT_SET_LANGUAGES确定打印语言版本同时结合SAP Note 808326、908442与1007575梳理Unicode打印预览和亚洲字符压缩的排查线索。压缩包共1个doc文件约28KB篇幅紧凑便于随查随用。已有1087人学习下载适合需要处理跨境系统打印差异的SAP开发与运维人员参考。读者可从中获得从现象定位到参数修改的完整排错思路理解英文环境与中文环境下表单语言版本的差异并掌握通过调试功能模块、核对Note补丁状态来验证解决效果的实践方法。1. SMART 中文 字体重叠login language 写死带来的版本坑SMART 中文 字体重叠这个坑我在 ECC6.4 Unicode 环境里前后踩过两次。第一次的表现很反直觉同一张 Smart Form中文环境login language 1预览时中文按预留宽度自动换行一切正常切到英文环境login language E预览中文业务数据挤成一坨字符叠在一起超出预留空间后打印到纸上重叠的那截又展开跟后面的字段交杂。系统不报错也没有 dump属于典型的“看起来能跑、打出来不能看”。这套环境在做了多年中文报表的系统里很常见适合正在接手老 form、准备上中文打印的 ABAP 开发和运维。装什么版本、参数落在哪、坏了怎么救下面按顺序走一遍。2. 环境先列清ECC6.4、Unicode 与 login language E/1动手改任何一行代码之前先把环境摸清楚。Smart Forms 的中文打印问题十次有八次不是字体问题而是语言版本在背后起作用。系统版本、Unicode 开关、补丁状态这三样没确认后面调参数就是盲调。我一般会先在系统里把下面这份清单过一遍确认每一项的当前值再决定是改代码还是补 note。2.1 版本与前置条件清单这套方案不是所有系统都能直接照搬先对照表格确认自己的环境落在哪一档。ECC6.4 是原文里明确跑通的版本同代 Unicode 系统逻辑一致非 Unicode 系统走的是另一套字符处理路径本文的参数改法不保证适用。检查项要求/常见值说明系统版本ECC6.4 或同代 Unicode 系统原文验证版本低版本需先确认 FM 是否存在Unicode 开关开启非 Unicode 下亚洲字符处理路径不同不要混用本方案打印控制结构SSFCTRLOP%header的类型语言字段为langu关键 FMSSFRT_SET_LANGUAGES决定 form 实际语言版本获取 FM 名SSF_FUNCTION_MODULE_NAME由 form 名反查生成的函数模块名补丁 808326已包含Unicode 打印预览文本格式化问题补丁 908442已包含Unicode 下亚洲文本重叠补丁 1007575需单独确认超过 31 字符的亚洲字符压缩确认补丁状态不用猜常见做法是进 SNOTE 或 SPAM 按 note 号查实施状态看是“已实施”还是“可实施”。ECC6.4 一般已经带上 808326 和 908442但 1007575 不一定这条后面第 5 章会专门讲。2.2 login language 与 form 语言版本不是一回事很多人把“登录语言”和“form 语言版本”当成同一个东西这是第一个容易翻车的地方。login language 是用户登录系统时选的语言直接写入系统字段sy-langu而 Smart Form 打印时实际用哪个语言版本渲染看的是打印控制结构里的%header-langu。两者平时被一段默认逻辑绑在一起如果调用方没有给control_parameters-langu赋值FM 内部就回落到sy-langu。这就解释了一个反直觉现象用户在英文环境登录sy-langu Eform 没有显式指定语言系统就按 E 去找语言版本。可这张 form 只维护了中文版本没有 E 版系统只能把中文版 form 当成 E 版来排版。排版引擎按英文字符宽度计算预留空间中文是双字节宽字符算出来的宽度装不下实际字形于是就重叠。中文环境登录时sy-langu 1正好对上中文版 form宽度算得对自然换行正常。2.3 中文编辑环境的选择还有一个前置选择容易被忽略form 里的中文描述最好在中文环境下编辑。原文里提过一个现象在英文环境编辑时写进去的中文描述到了英文环境打印会变成乱码具体成因当时没有完全定位。我的处理习惯是只要 form 里含中文标签、中文表头就把编辑环境切到中文再动别在英文环境里改完再回中文环境测。这样做不是为了绕开某个 bug而是减少“编辑语言”和“打印语言”两个变量同时变化后面排查时少一个干扰项。如果接手的是别人在英文环境建的老 form先别急着改排版把 form 在中文环境打开检查文本元素有没有已经乱码的有的话先修文本再谈重叠问题。2.4 确认当前 form 实际用的语言版本确认语言版本不用猜debug 一次就清楚。步骤不复杂先在 SE38 或 SE80 里找到调用该 Smart Form 的程序在SSF_FUNCTION_MODULE_NAME之后、实际调用生成的 FM 之前下断点单步进入 FM往下走到 350 行以后的SSFRT_SET_LANGUAGES调用执行完看%header-langu的值。如果英文环境下看到的是E而 form 只有中文版那基本就命中本文说的问题了。这一步的意义在于把“预览重叠”这个表象落到一个具体的字段值上。后面改代码、验证、回归都以这个字段为准不再靠肉眼判断“看起来好没好”。3. 定位语言参数SSFRT_SET_LANGUAGES 里 %header-langu 怎么被赋值环境确认完进入定位阶段。这一章的重点不是背 FM 文档而是把“为什么英文环境会重叠”落到一行赋值逻辑上。定位顺序我一般分三步先排除 note再 debug 到具体 FM最后逐行读参数。3.1 从打印预览异常到 Debug Smart Form 的 FM第一反应通常是查 note这没错。原文作者也是先上 service.sap.com 搜到两条相近的Note 808326SCR: Unicode print preview和 Note 908442Overlapping Asian texts in Unicode system症状描述都对得上。但把 Correction Instructions 里的代码和自己的系统一对比发现 ECC6.4 已经把这两个 note 打过了说明问题不在补丁缺失。排除 note 之后方向转到“是不是自己程序写的有问题”。这一步的做法是 debug Smart Form 对应的生成 FM。Smart Form 保存激活后会生成一个函数模块名字可以通过SSF_FUNCTION_MODULE_NAME拿到。在这个 FM 里往下翻一般在 350 行以后能看到SSFRT_SET_LANGUAGES的调用问题就藏在这段调用和它后面的赋值里。3.2 代码逐行读i_masterlanguage、i_thrulang、i_install_lang把这段典型代码贴出来逐参数看它在干什么 Smart Form 生成的 FM 中350 行以后的典型片段 CALL FUNCTION SSFRT_SET_LANGUAGES EXPORTING i_control_parameters control_parameters 外部传入的打印控制结构类型 SSFCTRLOP i_masterlanguage 1 form 主语言1 表示中文 i_thrulang 直通语言留空表示不指定 i_install_lang 安装语言留空 IMPORTING o_languages %languages. 返回可用语言列表 %header-langu %languages-langu1. 关键决定实际打印的 form 语言版本参数含义拆开看i_control_parameters是调用方传进来的打印控制结构类型是SSFCTRLOP里面带着langu、devtype、no_dialog这些字段i_masterlanguage 1表示这张 form 的主语言是中文这个值是 form 创建时定的一般不随调用方变i_thrulang和i_install_lang留空表示不额外指定直通语言和安装语言o_languages返回一个语言列表langu1是列表里的第一个语言。真正决定命运的是最后一行%header-langu %languages-langu1。这个字段的类型也是SSFCTRLOP里的语言字段它一旦定下来后面排版就按这个语言版本的 form 来走。3.3 赋值逻辑与根因control_parameters 为空时回落到 sy-langu只看i_masterlanguage 1容易误以为“主语言是中文应该没问题”。但SSFRT_SET_LANGUAGES对输出语言的赋值逻辑不是直接拿主语言而是这样一句 FM 内部对输出语言的赋值逻辑伪代码形式 %header-langu control_parameters IS INITIAL ? sy-langu : control_parameters-langu.翻译成日常说法如果调用方没传control_parameters或者传了但没给langu赋值就用当前登录语言sy-langu只有调用方明确给了control_parameters-langu才用调用方指定的值。原文里的 FORM routine 恰恰没有给control_parameters-langu赋值所以英文环境打印时%header-langu sy-langu E。系统拿E去找 form 的语言版本找不到 E 版就把中文版 form 当 E 版处理。排版按英文宽度算中文双字节字符放不下预览里就叠在一起打印到纸上超出预留空间的字符被展开又和后面的内容交杂。根因不是 Unicode bug也不是 note 没打而是语言版本被sy-langu带偏了。中文环境打印之所以正常是因为sy-langu 1正好命中中文版 form宽度计算和换行都按中文来问题自然不出现。这也解释了为什么同一张 form、同一份数据只换登录语言结果完全不同。4. 改代码传参control_parameters-langu 1 的落地改法根因定位到control_parameters-langu没赋值改法本身不复杂难的是改对位置、传对链路、回归到位。这一章按“先赋值、再传参、后回归”的顺序落地每一步都给可抄的代码。4.1 在 FORM routine 里给 control_parameters-langu 赋值改动的第一处是在调用 Smart Form 的 FORM routine 里显式给打印控制结构的语言字段赋值。位置建议放在获取 FM 名之后、实际调用之前保证传给 FM 的结构里已经带上了语言值。 FORM routine 中组装打印控制参数 DATA: ls_control_parameters TYPE ssfctrlop, lv_fm_name TYPE rs38l_fnam. 关键一行显式指定中文避免英文环境下回落到 sy-langu E ls_control_parameters-langu 1. ls_control_parameters-no_dialog X. 不弹打印对话框直接预览/打印 ls_control_parameters-devtype PRINTER. 输出设备类型 由 form 名反查生成的函数模块名 CALL FUNCTION SSF_FUNCTION_MODULE_NAME EXPORTING formname ZSMART_FORM_CN IMPORTING fm_name lv_fm_name EXCEPTIONS no_form 1 no_function_module 2 OTHERS 3.ls_control_parameters-langu 1是这次改动的核心1是中文语言键跟 form 主语言一致。no_dialog X控制是否弹打印对话框调试阶段可以先留空方便看预览devtype PRINTER指定输出到打印机如果只是预览也可以按需调整。SSF_FUNCTION_MODULE_NAME负责把 form 名翻译成 FM 名formname填自己的 formfm_name接返回值。注意langu字段的类型和长度要跟SSFCTRLOP结构一致不要直接塞一个字符常量就不管赋值前确认结构里字段名是langu而不是别的近似拼写。4.2 把 control_parameters 传到 Smart Form 的 FM赋值完之后必须确保这个结构真的传到了生成的 FM 里否则前面那行等于白写。调用生成的 FM 时用EXPORTING control_parameters ls_control_parameters把结构带进去 调用 Smart Form 生成的函数模块把控制参数传进去 CALL FUNCTION lv_fm_name EXPORTING control_parameters ls_control_parameters 带上 langu 1 user_settings EXCEPTIONS formatting_error 1 internal_error 2 send_error 3 user_canceled 4 OTHERS 5.control_parameters是这次传参的关键入口它进到 FM 后会被SSFRT_SET_LANGUAGES读取user_settings一般留空表示不覆盖用户个性化设置。异常列表里的四个错误码按需处理调试阶段至少把formatting_error和internal_error打到日志里不然出问题只能看到一句“打印失败”排查起来很被动。如果 FORM routine 里有多处调用同一个 form每一处都要传control_parameters不能只改主流程那一处。原文提到的“传参到 smart form 的 FM 中”说的就是这一步赋值和传参缺一不可。4.3 改完后的影响面与回归点改完代码不要只看一次预览就收工先想清楚影响面。control_parameters-langu一旦写死为1所有走这个 FORM routine 的打印都会按中文版 form 渲染这对中文报表是预期行为但如果这个 routine 还被其他语言的 form 复用就要评估会不会把原本正常的英文 form 也带成中文版。常见做法是给中文 form 单独拆一个 routine或者按 form 名判断后再赋值不要全局一刀切。回归点至少覆盖四个场景中文环境预览、英文环境预览、长中文文本、含数字和英文混排的字段。中文环境和英文环境都要看是因为这次改动的目的就是让两个环境表现一致长中文文本用来验证换行和宽度数字英文混排用来确认没有把非中文内容排坏。顺带提一句 SAPscript。原文在结尾提到SAPscript 的OPEN_FORM里也有language参数逻辑是相通的打印时限制 form 的语言版本很重要。如果系统里同时有 Smart Forms 和 SAPscript 报表改完一边另一边也照同样思路检查OPEN_FORM有没有显式指定language。 SAPscript 场景OPEN_FORM 显式指定语言 CALL FUNCTION OPEN_FORM EXPORTING form ZSCRIPT_FORM language 1 显式中文避免按 sy-langu 找版本 dialog X EXCEPTIONS OTHERS 1.language 1和 Smart Forms 里的control_parameters-langu 1是同一个道理都是把语言版本从“跟随登录语言”改成“由程序显式决定”。两边都改完才算把这类问题收口。5. 避坑与排查31 字符压缩、补丁顺序和语言环境混用这一章记录的是我在同类环境里踩过的具体坑每条按“现象→原因→解决”写。有些坑不是改一行代码能解决的得联合补丁和编辑习惯一起处理。5.1 现象重叠修好了长中文还是压缩在一起现象control_parameters-langu 1改完预览里短中文正常换行了但业务数据里超过一定长度的中文还是挤成一团字符间距明显不对。原因这是另一个独立问题命中 Note 1007575Compressed Asian characters in the print preview。症状是 Unicode 系统下显示亚洲 Smart Form某一行明明有足够空间系统却把超过 31 个字符的文本压缩显示。原文测试确认确实是超过 31 字符才触发压缩和语言版本赋值不是同一件事。解决去 SNOTE 查 1007575 的实施状态没打就申请打上已经打过还压缩就检查 support package 级别是否包含该修复。打完再测31 字符这个临界值可以作为回归用例固定下来。5.2 现象中文描述在英文环境编辑打印成乱码现象form 里的中文标签、中文表头在英文环境编辑保存后英文环境打印出来是乱码中文环境打印却正常。原因编辑环境和打印环境的语言不一致中文文本在英文环境里的存储或渲染路径出了问题。原文作者当时没有完全定位成因但现象是稳定的英文环境编辑的中文描述英文环境打印乱码。解决含中文的 form 统一在中文环境编辑改完在中文环境保存激活再到英文环境验证打印。如果接手的是英文环境建的老 form先把文本元素在中文环境过一遍发现乱码的先修文本再谈排版。这个习惯不解决底层成因但能把变量收窄避免“重叠”和“乱码”两个问题混在一起查。5.3 现象Notes 808326 和 908442 打了还是重叠现象按症状搜到 808326 和 908442确认已实施重启系统后英文环境预览还是重叠于是怀疑 note 打错了或者系统没生效。原因这两个 note 处理的是 Unicode 系统下打印预览的文本格式化问题包括字符重叠和间距异常但它们不负责“form 语言版本选错”这件事。语言版本由control_parameters-langu决定note 管不到调用方传什么参数。解决把 note 状态确认作为排除项不要当成修复项。确认已实施后直接转去 debug%header-langu看英文环境下这个值是不是E。如果是回到第 4 章改传参不要再在 note 上反复折腾。5.4 现象改了 FORM routine英文环境还是重叠现象ls_control_parameters-langu 1加了代码也激活了英文环境预览还是老样子。原因常见有两种。一是赋值加了但没传参调用生成的 FM 时control_parameters还是用的旧结构或者空结构二是传参链路中间被覆盖某个上层 routine 又给control_parameters-langu赋了sy-langu。解决在SSFRT_SET_LANGUAGES调用之后下断点直接看%header-langu的值。是E就往上追control_parameters从哪来、在哪被改是1但预览还重叠再回头查是不是命中了 5.1 的 31 字符压缩。断点看字段比看代码猜快得多这一步别省。5.5 现象SAPscript 报表也有类似重叠现象Smart Forms 改好了同一个系统里的 SAPscript 报表在英文环境打印中文还是重叠或者错位。原因SAPscript 走OPEN_FORM语言版本由language参数决定不指定时同样会跟随sy-langu和 Smart Forms 是同一类问题。解决在OPEN_FORM里显式写language 1改完按第 6 章的验证方法双环境对照。系统里两种报表技术并存时不要只修一边否则用户切个环境又报另一个报表坏了。6. 验证跑通打印预览与纸张输出的双环境对照改完代码、打完补丁最后一步是验证。这一步最怕“中文环境看一眼没问题就收工”因为这次修的就是环境差异只测一个环境等于没测。我的做法是固定一张含中文业务数据的测试 form分别在中文环境和英文环境各走一遍预览加实际输出按清单逐项对。验证项中文环境1英文环境E预期结果短中文预览正常换行正常换行两个环境表现一致超长中文31 字符不压缩、按宽度换行不压缩、按宽度换行命中 1007575 修复后成立中英数字混排对齐正常对齐正常不出现字符交杂实际打印/转 PDF无重叠无重叠纸上输出与预览一致%header-langu11不再回落到sy-langu验证时不要只看预览截图实际输出至少走一次打印或转 PDF因为原文提到的问题恰恰是“预览重叠打印到纸上重叠部分展开与后面内容交杂”预览和纸张表现不完全一样。转 PDF 检查成本低适合做回归。debug 断点也保留一次确认英文环境下%header-langu已经是1 验证用在 SSFRT_SET_LANGUAGES 调用后检查语言版本 断点位置%header-langu %languages-langu1 这一行之后 英文环境sy-langu E下期望看到 %header-langu 1 - 修复生效 %header-langu E - 传参没到位回到第 4 章检查如果英文环境断点看到%header-langu E先别怀疑补丁回到 4.1 和 4.2 检查赋值和传参是不是都落在同一条调用链上如果看到1但长中文仍压缩按 5.1 查 1007575。两条线分开查比混在一起猜快。血泪经验是这类问题最容易被“中文环境好了”骗过去。我现在的习惯是凡涉及语言版本的打印改动中文环境和英文环境各跑一遍预览加 PDF 各看一次断点确认一次%header-langu三样都过才算收工。从那以后我每次接 Smart Forms 中文报表都先把control_parameters-langu显式写死再谈排版省得后面返工。希望帮到你。本文还有配套的精品资源点击获取