尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

SAP长文本机制全解析:对象模型、存储原理与开发运维实战

SAP长文本机制全解析:对象模型、存储原理与开发运维实战 SAP长文本这东西干配置和开发的几乎天天见但真要说出个门道能把对象模型、存储逻辑、编辑入口、程序读写和坑点一次讲清楚的还真不多。我最早接触它的时候也吃了不少亏以为长文本就是个能多写字的大字段后来被一个带格式的文本在另一个系统里全部变成乱码的问题折腾了两天才老老实实把它的底层机制翻了个底朝天。这篇文章就把我这些年处理SAP长文本编辑的经验做一个完整梳理从它到底是什么到配置顾问怎么维护、开发怎么读写、踩坑怎么排查一条线讲透。1. 长文本到底是什么先弄懂TST01/STXL/STXH的三角关系很多新手最容易犯的错就是把SAP长文本和ABAP里的字符串变量画等号。实际上SAP长文本是一个独立的对象模型它有一套自己的数据库表和标识规则跟普通业务字段完全是两套逻辑。1.1 长文本的对象化存储逻辑长文本在底层不是存成一个大字段而是存在一个抬头Header行项目Body的两层结构里。抬头表是STXH存的是文本对象的元数据比如文本对象名、文本ID、语言、创建者、创建日期这些信息行项目表是STXL真的文本内容按块拆开存在这里。另外还有一张TST01它本身不存文本而是存文本对象的指针和被哪些应用对象引用可以理解成一个索引表。为什么要拆这么碎因为SAP长文本要支持编辑历史、语言切换、片段定位还要能跨模块复用。拆成块存储系统在读取某个长文本时不用把整张大表拖进内存只要按TDNAME文本对象名和TDID文本ID命中STXH拿到指针再去STXL按INST_NO顺序拼原文即可性能上可控得多。这段逻辑直接决定了后续一切操作方式。比如你用SE16去看STXL里的内容会发现一行行的字符串碎片前面还有两个数字标识块号和行号你要是想手动UPDATE这个表基本等于自找麻烦因为文本的格式信息和换行符都是编码后的状态直接改表轻则格式错乱重则整条文本显示不出来。1.2 三个关键标识TDNAME、TDOBJECT、TDID每个长文本都由三个标识唯一确定TDOBJECT文本对象类别通常对应业务场景。物料主数据的文本、订单文本、地址文本各自有独立的Object。常见的有TEXT通用、物料主数据是MATERIAL、客户主数据是KNA1这种前缀对应的对象。TDNAME文本对象的名称相当于这条文本的ID一般直接取业务对象的单据号或主数据编号。比如物料长文本的TDNAME就是物料号。TDID文本ID表示同一对象下不同用途的文本。物料可以同时有基本文本、采购文本、销售文本靠TDID区分。这三个标识合在一起再加上语言TDSPRAS才算完整锁定一份长文本。我见过不少配置顾问在学习阶段搞混TDNAME和TDID结果在某个界面里一直编辑的是另一条文本界面看起来也对但输出到单据上的内容完全是另一份数据。这个坑在文本复制场景里特别常见后面专门展开说。1.3 长文本与短文本的本质差别业务上会同时出现短文本字段和长文本两个入口很多人不理解为什么不能只用其中一个。最典型的场景是物料主数据基本数据视图里有个物料描述短文本字段同时还有个基本文本长文本入口。短文本存的是纯字符串存在业务表里比如MARA表里的MAKTX字段。它被报表、ALV列表、单据打印快速取用不带任何格式也基本不占什么维护成本。长文本存的是格式化文本支持换行、缩进、编号、颜色标记、超链接适合放完整的技术描述、合同条款、发货说明这种多段落内容。理解这个差别你就知道该用哪个凡是需要出现在报表行项目里、要被搜索、要用于做条件判断的用短文本凡是需要人工阅读、有排版意识、可能超过几十行的大段描述用长文本。硬要用长文本达到短文本的效果你会发现报表取数麻烦、搜索困难反过来用短文本硬扛长文本的排版换行和缩进会全部丢失打印出来一团糟。2. 配置与业务端的编辑入口SO10事务代码的正确打开方式SAP里长文本的编辑入口很多物料主数据里有、订单界面上有、质量通知里也有但如果你只是想建立一条通用文本或者想研究长文本本身的功能SO10这个事务代码才是最直接的入口。2.1 SO10的界面结构与标准操作流程SO10的全称是Standard Text Editor它可以维护不绑定特定业务单据的通用文本也能维护带对象关联的文本取决于你输入什么条件。流程上分三步走在初始界面选择文本对象类型和语言输入文本对象名和文本ID。如果不输入对象名相当于维护一个独立的通用文本系统会按内部规则给它命名。进入编辑界面后你会看到一个带工具栏的文本编辑器支持字体设置、对齐方式、项目符号、编号列表、表格插入等操作。这些操作看着简单但它背后的存储格式是SAP自定义的格式编码和Word的docx完全不是一回事。保存后系统会提示该文本被保存到STXH/STXL表并分配给对应的对象。如果文本是绑定某个业务对象的保存时系统会同时记录TST01指针。配置顾问用得最多的是用SO10维护标准文本再通过表单打印或邮件集成去引用。比如在某个销售订单的打印表单里需要一段固定的质量承诺说明正规做法不是每次手工敲而是维护一条标准文本域控里调TEXT对象引用既保证内容一致又避免了改一次要全量变动的尴尬。2.2 把长文本绑到主数据与单据上的常规路径如果你处在一个实施项目里最频繁的操作其实是把长文本绑到物料主数据和客户主数据上。物料主数据的长文本入口通常藏在每个视图的附加数据里选择文本标签页后系统调用的还是同一个长文本编辑器只不过TDNAME自动带出物料号TDID由视图类型决定。客户主数据也类似在销售范围数据里找到客户文本或合作伙伴文本新增一条文本后保存时自动关联到客户主数据。这里有个极容易忽略的点不同视图下的文本ID不同意味着你要在采购视图维护物料长文本和要在销售视图维护界面入口完全不同查询出来的内容也会各自独立。一个物料可以同时有采购描述长文本、销售描述长文本、基本文本长文本三条底层都是独立记录。所以在业务调研阶段就应该把哪类文本放在哪个视图、客户和供应商看到的是哪份文本这类问题问清楚否则三个月后上线你会被各类为什么我改了采购文本销售那边没变的提问淹没。2.3 本地对象传输与请求号管理长文本和表配置一样属于系统里的数据对象。你在开发系统里维护了一条文本要做质量系统、生产系统靠的是请求号传输。实际操作里保存文本时系统会提示文本已保护或者分配了请求号取决于你的传输设置。如果你在SO10里建了标准文本保存时应该会有创建传输请求的选项如果保存后没提示那这条文本就只存在于当前客户端要传输就得手动去SE09创建一个工作台请求把对应的STXH/STXL条目纳入。但是请注意通过请求号传输长文本跟传输表数据不是一回事。STXH表的条目类型如果被定义成自定义数据那你传输的是数据记录必须在传输工具里选择正确的对象类型。很多初学顾问在导入系统里发现长文本不见了多半是这里没选对。另一种常见做法是用SE16直接导出/导入这两张表但那只能用在应急场景正规项目里要走传输请求否则系统间数据一致性没法追溯。3. 程序开发视角READ_TEXT和SAVE_TEXT的正确参数逻辑真正让长文本从能编辑变成能被程序控制的是那一组标准函数模块。凡是做过SAP开发者应该都用过READ_TEXT和SAVE_TEXT。这俩函数看着简单参数却常有歧义尤其传递文本ID和对象名的时候想当然填值很容易翻车。3.1 READ_TEXT回顾文本读取的入参和返回结构READ_TEXT的入参一般是ID文本ID比如物料基本文本的BASIC订单文本的TEXT等取决于你处理的对象。LANGUAGE语言代码默认X登录语言或维护时的语言。NAMETDNAME通常就是物料号、销售订单号。OBJECTTDOBJECT比如MATERIAL、VBRK必须和Name配合使用。返回的表IT_LINES就是TEXT_LINES结构包含TDFORMAT格式标记、TDLINE文本行内容。一个容易被忽略的点如果物料长文本在维护时选的是中文而当前用户登录语言是英文READ_TEXT传LANGUAGEEN拿到的结果可能是空。别怀疑是自己代码写错先检查语言参数。很多报表里长文本显示空白不是程序取数逻辑挂了是这个多语言匹配没做好。另外长文本支持分段Paragraph Headers读取时除了文本行还能取到格式控制行。如果你想在ALV里原样显示文本格式只拼TDLINE是不行的段落头的缩进、编号规则都在TDFORMAT里。这时候要么自己解析格式标志要么老老实实用编辑控件显示原格式文本。3.2 SAVE_TEXT创建与修改时别漏掉的字段SAVE_TEXT的参数里除了ID/LANGUAGE/NAME/OBJECT之外还有个比较容易被忽略的字段STXL和STXH的内部结构不少新人都不知道要先把文本内容装到TEXT_LINES返回表格里再传进去。正确顺序是这样先根据业务逻辑准备好TEXT_LINES表格每一行代表长文本的一行。函数内部会按最大行字节数对长行做自动切割但要注意你传进来的行要有明确的换行语义空行也要保留。调用SAVE_TEXT后系统返回一个报文或直接报错细看功能代码是否有覆盖权限是否有文本已存在但未设置覆盖的提示。SAVE_TEXT最常见的失败原因是文本被锁或者没有更新权限。它会检查当前会话是否持有锁对象如果靠并发程序更新同一物料的长文本没有做加锁处理两条任务会互相覆盖。解决方式是通过ENQUEUE_EZ_TEXTLOCK去显式锁文本对象更新完再DEQUEUE多程序并发写同一个文本必须有这个步骤。3.3 动态文本处理在程序里拼接长文本内容实际开发里常常不是从屏幕录入而是程序自动生成。比如从外部系统接到一批数据需要把多行字段拼成一个长文本保存。这里就涉及拼接规则每个业务字段用一行TDLINE承载字段内部不要手动塞换行符否则换行符会被编码成特殊字符再编辑会看到莫名的^Z之类的记号。要做小标题、编号段落时用TDFORMAT字段指示段落类型。比较常用的是*表示项目符号、数字编号等格式具体格式代码以当前SAP版本的文字处理文档为准不同版本对格式代码支持有细微差异。如果文本中需要留空行千万不要省略行。你可以插入一行仅含空格的TDLINE或者按标准格式控制行来创建空段落。我自己吃过一个亏需要拼一份产品规格包装要求运输说明长文本为了偷懒每个字段间都加了CHR(13)换行符。后台上传成功但用户一打开编辑界面满屏黑块因为换行符被编辑器当成了格式控制字符。后面改成每字段一行、行间不需要空行就直接下一行、需要留白就补空段落问题才解决。所以务必记住长文本的行本身就是换行单位不要再往行内容里手输换行符。3.4 用标准函数在ALV和打印输出里展示长文本实际交付时用户不止要能编辑还要在报表、邮件、打印输出里看到它。ALV展示长文本时直接在字段目录里用REF_TABLE和REF_FIELD指向文本行表通常是不可靠的因为ALV单元格不能直接渲染多行自由文本。通常做法有二一是把长文本拼成一个字符串塞进单个单元格但这会丢失换行二是用一个子屏幕或弹出窗口点击查看时调用整段文本控件。打印输出场景更讲究WORD接口能对接长文本格式但前提是你在表单里正确引用了文本对象。Smart Forms里可以通过TEXT元素绑定标准文本或业务长文本引用时同样要指定名称、对象和ID。配置顾问如果发现打印下来的长文本缺少段落编号、没有缩进九成是在Form里没有选择带格式输出选项而选了按纯文本输出。4. 长文本维护与开发中反复踩到的坑一次完整的排查过程长文本这东西大部分时间是安静的一旦出问题往往是数据看起来还在但编辑、传输、显示总有一个环节不对劲。我挑几个高频问题把完整排查链路写出来你们遇到同款可以直接照着走。4.1 文本在开发系统维护好了传输后目标系统却读不到这个现象最高发原因是保存文本时没有把它纳入传输请求或者传输对象类型选错了。排查链路走一遍用SE38或SE16N查目标系统的STXH确认这条文本的条目是否真的存在。如果不存在说明它根本就没传过去。回到源系统在SE03里查这条对象是否在某个请求里。如果连请求号都没有说明保存时系统认为它是本地对象此时需要检查客户端设置和传输域配置。如果有请求号再看传输类型。长文本的传输经常被误当成流数据或表数据实际要选字符串或对应数据类型的对象。传输完成后还要检查目标系统是否执行了导入后处理。数据到了但程序读不到查语言。源系统维护的是中文目标系统用户登录英文READ_TEXT按登录语言取文本自然取不到。在STXL里能看到行数据但按LANGUAGE查为空就是这个原因。这里能救命的技巧是上线前做一次长文本传输演练每个文本对象类型都挑一条测试数据走完整个请求传输流程确认目标系统里按业务场景能正确读取。这个环节省了上线后就是大面积投诉。4.2 物料长文本错乱编辑一个视图另一个视图也跟着变有人反馈我在物料主数据销售视图里改了长文本结果采购视图的文本也变了。先别急着怀疑系统有Bug大概率是这两处入口指向的是同一个TDID和TDOBJECT组合。比如某些物料主数据模板里多个视图共用基本文本你从哪个视图进去看到的内容都是同一条记录。系统本来就是这个设计问题出在业务侧对同一物料是否允许不同视图有不同文本的需求没理清楚。解决办法有两种路径如果业务确实要求销售视图和采购视图内容不同那就要更改文本ID的分配关系让每个入口绑定独立的文本ID最好由开发人员调整功能模块或视图开发设置。如果业务只是不希望互相污染却仍然想要每处不同的入口那就只能是人为约定维护销售文本只在销售视图入口采购文本只在采购视图入口并且不去改另一个入口的其他字段。这个坑很隐蔽因为短文本字段在不同视图里本身就是重复的字段改一个另一个也会变所以很多人默认长文本也一样。面对这种问题不要急着改程序先把三个标识符组合查出来确认到底是共用还是独立错配了再定方案。4.3 程序UPDATE了STXL但界面打开还是旧文本有时图省事有人直接拿ABAP UPDATE语句往STXL表里写行数据结果界面打开发现文本没变或者变成空白。原因在于SAP长文本有自身的行缓冲和格式化缓存。直接改表不会刷新业务对象那里的文本缓存甚至会导致文本对象头和内容行数据不一致最后表现为显示异常。正规做法永远是调函数READ_TEXT/SAVE_TEXT这套标准函数自带锁检查、缓存刷新、格式校验。就算想批量更新也只能用函数循环处理不能在UPDATE语句层面绕过去。这个排查过程我印象很深某团队做物料描述批量清洗用UPDATE直接改STXL的TDLINE部分物料显示正常部分物料打开就是空白。一查空白的都是因为文本被分到多个块多个数据页UPDATE只更新了第一块剩下的旧块继续留着编辑器一拼起来就丢内容。这种问题极难收敛最后只能全量重新用SAVE_TEXT落一遍数据。4.4 长文本的权限控制能读到内容但不让编辑不少项目会提一个需求某些工序的人只能读长文本不能改另一些人可以改但不能创建新的。长文本的权限控制配置上走的是授权对象一个比较常用的权限对象是和文本维护相关的字段包括活动、文本ID、文本对象等。你可以通过角色分配给部分用户创建/更改权限其他用户只给显示权限。但要注意长文本编辑的权限往往不是单一维度控制的有些业务对象自带前置权限检查。比如销售订单里的长文本还要看销售订单的类型和文档类型没有对应权限的用户在编辑按钮上就会置灰。这种复合权限逻辑很烦上线前最好把关键业务对象的长文本使用矩阵列出来逐项做权限测试。4.5 多语言环境下默认语言文本丢了其他语言文本还在全球部署项目里经常遇到中文主数据正常但切换到其他语言时打印报表上本来中文的内容变成了四个句号或者直接空白。这个问题的根子在多语言文本的优先级机制。系统在取文本时会按用户语言匹配取不到就回退到默认语言或者源语言取决于文本对象本身的属性设置。如果你在客户主数据里只维护了中文文本而某个销售单据被要求以英文输出文本读取就会触发回退逻辑。如果该文本对象设置了必须在用户语言下维护而没有设置回退那么读出来的结果就是空白。解决方式是在文本维护界面把默认语言和源语言标记都选上同时提醒业务人员正式单据语言切换前必须检查对应语言的文本是否存在。5. 长文本编辑器增强与批量维护现代项目中绕不开的两个话题基础的维护和开发讲完之后再聊两个实施项目中常被点名的增强需求。一个是编辑器界面的功能扩展另一个是大批量数据迁移时的文本搬移。5.1 编辑器增强附加工具栏按钮和自定义校验SAP标准的长文本编辑器功能其实相当朴素对样式的支持没有现代文档编辑器那么顺手。有些企业希望增加一键上传图片、自动检查敏感词、禁止粘贴外部格式这类功能这就落在增强开发范围里。可行途径通常有两条。一条是沿用标准编辑器通过前后台增强点拦截保存事件在保存前做校验或格式处理另一条是把长文本编辑界面替换成自定义子屏幕用第三方富文本控件比如内嵌网页型编辑器来编辑HTML然后在保存时把HTML转成SAP的文本格式。我个人建议如果不是非必要不要轻易换编辑器方案。长文本最终是要交回给系统其他模块展示的如果你把内容存成HTML格式那所有标准功能ALV展示、表单打印、传输机制全都得自己重写。相比之下通过增强点校正格式、自动补全段落头、自动翻译触发性价比高得多。这类需求做之前一定要先想清楚内容消费端在哪里消费端不只在你自己的报表里可能还有物料主数据界面、销售订单界面、旧系统接口。5.2 批量迁移与导入长文本伴随主数据一起搬系统迁移项目里除了BAPI/MASS批量导入主数据文本也要跟着走。很多初入行的人以为调个BAPI传入长文本就行实际没那么简单。正确思路是先通过BAPI创建/更新主数据让系统生成对象标识然后在长文本函数里复用这些标识逐条写入。比如物料创建用BAPI_MATERIAL_SAVEDATA长文本不要试图塞进这个BAPI的扩展里而是先拿到物料号再循环调SAVE_TEXT写入对应视图文本。批量导入长文本有个特别要命的点是编码和换行。源系统如果是从Excel过来的单元格内换行是CHAR(10)传到中间件后会被当成普通字符导入程序里如果不做转换保存后编辑界面会出现大量奇怪的换行符文本行数量也对不上。我建议的标准化清洗步骤是源数据落地后用工具统一把CRLF、LF、CR全部规整成换行标记。按每行长度是否超过长文本行最大长度做预切分不要完全依赖SAVE_TEXT内部切分太长的行切分点可能落在多字节字符中间造成乱码。每一条文本导入完成后做一次READ_TEXT回读对比行数和关键内容匹配后再继续下一条。多语言文本在导入循环里对每种语言各跑一次而不是指望一次调用写多种语言。批量导入不能图快关键是每个文本对象都要做回读校验。我自己做过的某次物料主数据迁移里就是因为跳过了回读结果有上千条物料的长文本对象名和物料号对不上后面全靠二次脚本去修复非常痛苦。5.3 长文本相关的疑难杂症排查工具箱再分享几个排查长文本问题时经常用到的工具和事务代码都是实战中出现频率极高的SE16N / SE17直接查看STXH、STXL、TST01表数据确认对象标识和数据是否存在。SO10操作标准文本分辨文本对象命名规则。SE75维护文本ID和对象类别定义当提示文本对象类型不合法或找不到时先来这里看。SAT / ST05长文本读取性能出问题时用SQL跟踪看STXL表访问是否走了索引对象名过长或者查询条件不完整时全表扫描会拖慢整个单据创建流程。调试器断点在READ_TEXT里如果想知道某个界面读取长文本时到底传了什么入参直接在函数入口下断点看NAME、ID、OBJECT、LANGUAGE四个值。这四个值基本能定位绝大多数读取问题。其中ST05在某次顺延性能案件里帮了大忙用户反馈销售订单创建很慢跟踪出来是每创建一张订单都要求读取10条长文本其中有几条的对象名是空的。空对象名导致系统没走索引全表扫了一遍单据创建从3秒变成30秒。这种问题不看SQL跟踪根本猜不到。6. 从功能到性能到运维长文本全生命周期的几个实践建议这篇写到最后把我在多个项目里总结的长文本实施要点做一个集中输出。没什么空话都是实际操作层面值得写进项目检查表的东西。6.1 项目初始化阶段就该做的文本对象盘点项目一开始就该把所有业务场景里涉及的长文本对象梳理成清单。物料、客户、供应商、销售订单、采购订单、生产订单、质量通知、服务通知每个场景都记录TDOBJECT、TDID、入口位置、对应语言策略、权限矩阵。这份清单的价值会在三件事上显现出来一是权限配置阶段不用临时拍脑袋二是传输策略阶段知道哪些文本要纳入请求、哪些是纯本地数据三是测试阶段所有文本相关的功能测试用例都有了依据。不要等上线了才让用户去试用户一旦发现销售订单里能挂文本采购订单里挂了看不到你的项目口碑就回不来了。6.2 统一的维护规范行内容、换行符、语言、权限一个都不能少整理一份简短但对内的长文本维护规范真的能减少很多隐性返工。行内容里不得包含换行符需要用换行时另起一行。段落格式控制在编辑器里用标准按钮操作不要复制粘贴外部文本。每条业务长文本建议统一维护默认语言再日常使用语言按需维护。文本ID和短文本字段的职责边界写清楚避免业务人员两边都填然后又问哪个为准。这些规范看起来很简单但反例我见得太多了。文本里被粘贴进Word的制表符、自动编号导致打印输出完全错位业务人员为了看起来好看在短文本字段里加各种特殊符号导致打印格式崩掉——都是因为没规矩。6.3 性能与监控别让长文本成了单据创建和打印的隐形杀手最后提一条长期运维层面的建议。长文本的性能问题往往不是一开始就爆发而是数据量上去之后才出现。物料数量从十万涨到百万长文本表STXL的体量会涨得非常快。如果你在订单创建流程里每次都无条件读取长文本即便只读一次累计起来的开销也不能小觑。解决方向上可以在数据模型设计阶段就明确哪些对象必须有文本、哪些文本可以被延迟读取、哪些文本可以直接拼在打印模块里。ABAP代码层面尽量一个会话里只读一次并缓存到会话内存读取长文本的函数调用尽量放在显示阶段不要放在保存链路里。监控方面定期检查STXL表的增长趋势对大表按对象类型做归档策略归档没问题但别过期不归。6.4 我对长文本的总体印象它是个结构简单但行为复杂的系统对象说了一大堆其实我对SAP长文本的总体评价是入门门槛低精通全靠踩坑。它有清晰的表结构、标准的函数模块、完整的编辑界面但它跨模块的复用机制、格式编码规则、多语言回退逻辑、权限复合校验再加上传输和缓存机制任何一个环节没弄明白都会在某个夜深人静的加班晚上给你惊喜。我个人的工作习惯是只要碰到长文本相关的需求先花十分钟把涉及到的对象标识和调用链路画一遍再动手写代码或者调配置。尤其是在跨系统、跨模块的场景里多确认一次TDID和语言策略绝对比事后回溯要轻松十倍。如果你正准备处理长文本相关的实施或开发希望这篇里的内容能帮你少走点弯路。有过类似经历的朋友也欢迎交流你们遇到的文本坑。
返回列表