ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SAP BP屏幕增强页签实战:BAdI BUPA_ITEMS_EXTENSION

SAP BP屏幕增强页签实战:BAdI BUPA_ITEMS_EXTENSION 1. 先想明白SAP BP 屏幕增强加页签到底在解决什么问题做过 SAP 项目的人基本都有过这种体验——业务部门跑过来提需求说标准的事务代码 BP 里字段不够用要在业务伙伴主数据上再挂一块自己的内容最好还像标准那样分个页签点进去能填、能存、能校验。这就是 SAP BP 屏幕增强页签这个需求最原始的样子。它不是什么高深的技术但它是那种看起来简单、做起来全是细节的活儿。BP 屏幕增强页签本质上是两件事的组合一是在业务伙伴维护界面事务码 BP上凭空多出一个页签按钮二是这个页签点开后是一个你自己画的子屏幕屏幕里的字段能读能写能存到数据库。适合谁看适合正在做 S/4HANA 或 ECC 上 BP 主数据扩展的 ABAP 顾问、模块顾问以及必须自己动手改增强的乙方开发。它的技术底座并不复杂核心就是 BAdIBUPA_ITEMS_EXTENSION加上一个自定义的函数组和屏幕再叠加一个数据落地的地方Append 到BUT000或者自建透明表。但这里面的坑极多页签不出来、出来了点不动、能填但存不进去、传输到生产就报错、改完之后标准页签全乱了……任何一个没踩过的人第一次做大概率要反复调两三天。我先说结论这套增强的难点不在写代码而在注册和数据流。BAdI 负责把页签注册到标准程序里函数组屏幕负责展示两边通过内存和参数传值。为什么很多人做不出来就是因为没搞清楚 SAP 标准程序在什么时候调你的 BAdI、什么时候调你的屏幕、数据应该在哪一步落库。想明白这条链路剩下的都是体力活。还有一点得提前提醒BP 把客户、供应商、联系人全统一了所以你在 BP 上做的页签增强会同时出现在 FLCU00、FLVN00、FLVN01 等各种角色视图里。到底给哪些角色显示、哪些隐藏这是要在配置层解决的不是靠代码硬判断。下面我按实操顺序一层一层拆开讲。2. 动手前必须先定下来的技术选型2.1 数据落地的两条路Append 到 BUT000 还是自建表在写任何一行 ABAP 之前第一个决策是我这些自定义字段存到哪。绝大多数情况下有两种主流选择选错了后面返工代价非常大。第一种是把字段直接 Append 到标准表BUT000业务伙伴主数据主表。做法是 SE11 打开BUT000创建一个 Append Structure把自定义字段加进去。好处非常明显跟 BP 主数据同生共死读的时候不用额外 JOINBAdI 里直接操作BUT000的工作区就能带出数据逻辑简单直接。坏处也很明显你动了标准表结构虽然 Append 是 SAP 允许的扩展方式但在升级、某些归档、以及和其他增强冲突的时候还是会牵一发动全身。而且如果字段很多BUT000会越来越臃肿维护起来心里不踏实。第二种是自建一张透明表比如ZBP_EXT_CREDIT主键就用业务伙伴编号PARTNER。字段全部放自己表里干净隔离BUT000一根毛都不碰。读的时候用PARTNER关联查一次即可性能上完全不是问题因为 BP 维护界面一次只处理一个业务伙伴。坏处是要多写一套读写逻辑而且如果业务要求这个字段参与标准搜索、标准列表输出那还得额外处理。我的经验是字段少比如就三五个且确定只在这个页签里用Append 到BUT000最省事字段多、逻辑复杂、或者以后可能被别的模块引用果断自建表。别为了省那一两个小时的写表时间给自己埋一个升级时爆炸的雷。对比项Append 到 BUT000自建透明表开发速度快直接操作标准工作区稍慢要单独写读写隔离性差动了标准表好完全独立升级风险较高低参与标准搜索需要额外配置不直接支持适合场景字段少、仅页签使用字段多、逻辑复杂、多模块引用2.2 界面增强相关的几个 BAdI千万别选错BP 的增强 BAdI 有好几个名字长得还都挺像我第一次接触的时候也懵过。这里必须分清楚因为选错了要么页签出不来要么根本走不到你的代码。核心的那个是BUPA_ITEMS_EXTENSION接口是IF_EX_BUPA_ITEMS_EXTENSION。这个 BAdI 专门管往 BP 界面上加条目条目可以是页签也可以是子标题Subheader。你要做页签就靠它。它里面有四个方法要重点关注GET_ITEMS_TABLE用来告诉标准程序我要加一个页签标题叫什么GET_DETAILS用来真正调用你的子屏幕SET_DATA在用户在 BP 里按保存时被触发你把数据落到库里CHECK_DATA用来做保存前校验比如必输检查、格式校验。另外还有BUPA_HEADER_EXTENSION这个管的是 BP 顶部抬头区域比如姓名、地址那种头部信息区的增强BUPA_CENTRAL_DATA_EXTENSION管的是中央数据区。这两个跟页签不是一回事别拿它们来硬做页签否则做出来的东西在布局上会很别扭。注意BBP 不同版本ECC 和 S/4HANA里 BAdI 的实现细节略有差异但BUPA_ITEMS_EXTENSION这条链路在 S/4HANA 里依然可用。动手前务必用 SE18 打开这个 BAdI把接口IF_EX_BUPA_ITEMS_EXTENSION的所有方法参数看一遍参数名和类型以你系统里实际的为准不要照抄网上的老版本代码。2.3 一份可落地的实现清单为了避免做着做着漏东西我习惯开工前先把清单列出来做一项勾一项。做 BP 页签增强完整清单大概是这样确定字段清单和数据类型先跟业务确认死别做一半又加字段。决定数据落地方式Append 或自建表。建数据元素、域、必要的搜索帮助。建或改表结构激活。建 Function Group函数组专门放屏幕和逻辑。在函数组里建 Screen比如 0100画好字段写 PBO/PAI。SE19 创建BUPA_ITEMS_EXTENSION的实现写四个方法。用 SPRO 里的 BP 屏幕布局配置把新页签分配到对应角色视图。测试创建 BP、切页签、填值、保存、重进验证。做传输请求登记增强实现和函数组。我见过很多人第 8 步直接跳过结果代码全对页签死活不出来查了一下午。记住BAdI 只是申请加页签真正决定这个页签在哪显示、给谁显示是屏幕布局配置干的活。3. 数据层准备字段和表怎么建才不返工3.1 用 Append 扩展 BUT000 的完整步骤先讲 Append 这条路。SE11 输入BUT000点显示然后菜单里选转到 → 附加 → 创建或者直接点工具条上的 Append Structure 按钮。系统会新建一个 Append Structure名字一般以Z开头比如ZABUT000。在这个结构里加上你的字段字段必须带数据元素不能裸用类型这是 SE11 的硬要求。建完字段后激活 Append Structure再激活BUT000主表。这一步很多人卡在为什么BUT000激活报错多数是因为 Append 里的字段用了没激活的数据元素或者数据类型跟标准表某个字段冲突。我的习惯是先把数据元素单独建好激活再去建 Append这样一路下来基本不会报错。还有一个细节Append 进去的字段在标准屏幕上是不会自动显示的你需要自己画屏幕或者把它塞进你自己的子屏幕里。所以 Append 只解决存哪不解决怎么显示。这两个是分开的别混。实操心得Append Structure 的字段顺序建议按业务逻辑排好不要随便插。因为将来你如果要写升级或者做数据迁移字段顺序乱会让人很难查。另外Append 的名字最好起得有意义比如跟业务模块挂钩不要一堆ZAPPEND01、ZAPPEND02半年后自己都认不出来。3.2 自建透明表的建法与主键设计自建表这条路主键设计是第一个要拍板的事。绝大多数情况下用MANDT客户端加PARTNER业务伙伴编号做复合主键就够了因为一个业务伙伴就一份扩展数据。如果业务上允许一个 BP 有多条记录比如多条备注那就要再加一个序号字段做主键。建表的时候我强烈建议把MANDT作为第一个主键字段这是 SAP 透明表的基本规范别偷懒省略否则在跨客户端环境里会出各种奇怪的问题。字段尽量引用已存在的数据元素比如BU_PARTNER就是标准的业务伙伴编号数据元素直接拿来用省得自己定义还容易和标准类型对不上。表建好之后如果只在你自己的页签里读写用 Open SQL 的SELECT SINGLE、INSERT、UPDATE就够了不需要生成维护视图。但如果你希望业务也能直接用 SM30 维护可以生成表格维护生成器不过对 BP 页签场景来说这不是必需的。3.3 数据元素、域与搜索帮助的细节不管走哪条路数据元素都要先建。这里的坑在于域的维护域决定了字段的长度和取值范围。你要提前想清楚每个字段多长、是不是带固定值列表。比如信用评级这种字段用CHAR两位、配一个固定值域A/B/C/D比让用户随便填一堆乱码要靠谱得多。搜索帮助也是类似如果字段是引用某个标准表比如国家代码直接挂个标准搜索帮助就行。自定义的搜索帮助用 SE11 建然后挂到数据元素上这样在屏幕上 F4 就能用。注意数据元素、域、搜索帮助这些东西一旦激活并用到了表结构里改起来就麻烦要重新激活一整条链路。所以字段定义阶段多花十分钟跟业务对齐能省后面两小时的返工。4. 页面层实现Function Group 与子屏幕4.1 为什么要单独建一个函数组BP 的子屏幕必须用一个独立的 Function Group 来承载不能随便找个程序往里塞屏幕。原因是标准程序要在它的 Dynpro 里通过CALL SUBSCREEN调用你的屏幕而这个屏幕必须属于一个能被标准程序看到的函数组SAP 才能在运行时把你的屏幕嵌进去。我一般的做法是建一个专用函数组比如ZBP_EXT里面只放 BP 扩展相关的东西。函数组的好处是它有一块全局数据区Top Include屏幕的 PBO/PAI 和函数模块都能访问这些全局变量数据传递特别方便。这一块区域就是我后面做数据搬运的中转站。函数组的命名也建议规范点别用ZTEST、Z001这种。因为一旦投入生产这个函数组会长期存在好名字对后面维护的人很可能是你自己是一种善意。4.2 Screen 0100 的布局与流逻辑在函数组里新建屏幕编号我从0100开始这是惯例别用太奇怪的号。屏幕属性里屏幕类型选子屏幕Subscreen——这是关键普通屏幕嵌不进去。屏幕大小按你字段的多少来定宽 100、高 30 是常见的起点。布局上我建议用引导型字段按钮的排法左边放字段标签右边放输入框一行一个字段清晰好读。别搞得太花哨BP 界面本身就很拥挤你的页签干净最重要。字段的输入输出属性Input/Output按需求勾只读的字段就别勾输入了。流程逻辑Flow Logic里PBO 和 PAI 的写法后面单独讲。这里重点提醒屏幕里的字段名和数据元素要对上别出现引用了不存在的数据元素的屏幕否则激活就报错。画完屏幕记得激活SAP 的屏幕不激活等于没建。4.3 PBO/PAI 里的数据搬运代码屏幕的 PBOProcess Before Output负责在屏幕显示前把数据从全局变量搬到屏幕字段PAIProcess After Input负责在用户操作后把屏幕字段的值搬回全局变量。这个全局变量就是你函数组 Top Include 里定义的变量。一个典型的 PBO 是这样的PROCESS BEFORE OUTPUT. MODULE status_0100. MODULE move_data_to_screen.对应的模块MODULE move_data_to_screen OUTPUT. 假设全局变量是 gs_ext屏幕字段同名 zbp_cr_rating gs_ext-cr_rating. zbp_cr_limit gs_ext-cr_limit. zbp_remark gs_ext-remark. ENDMODULE.PAI 里再反过来MODULE move_screen_to_data INPUT. gs_ext-cr_rating zbp_cr_rating. gs_ext-cr_limit zbp_cr_limit. gs_ext-remark zbp_remark. ENDMODULE.看起来简单但这里有个非常容易忽略的点PBO 和 PAI 的执行顺序和你想象的未必一致。尤其是当用户直接点保存、没触发 PAI 的时候屏幕上的值可能还没搬回全局变量。所以真正落库的数据要以你在SET_DATA里读到的为准不能想当然。实操心得不要在屏幕字段上直接做逻辑判断所有校验都放到CHECK_DATA方法或者独立的校验函数里。屏幕只负责显示和采集业务逻辑集中在 BAdI 那边这样代码干净排查问题也容易。我踩过的坑就是校验逻辑散在屏幕 PAI 里后来业务规则一变改得满天飞。5. BAdI BUPA_ITEMS_EXTENSION 的落地5.1 用 SE18/SE19 找到并创建实现打开 SE18输入 BAdI 名称BUPA_ITEMS_EXTENSION进入后能看到它的接口IF_EX_BUPA_ITEMS_EXTENSION。用 SE19 创建实现实现的名字用Z开头比如ZBP_ITEMS_EXT。创建的时候会让你选实现类一般选基于类的实现系统会生成一个实现类你在里面写四个方法。创建好实现后别忘了勾选激活或者通过对象激活。BAdI 实现不激活代码等于白写。这一步我见过不止一个人忘了然后对着屏幕发呆。5.2 GET_ITEMS_TABLE把页签挂上去GET_ITEMS_TABLE是第一个被调用的方法它的任务就是告诉标准程序我要加一个页签页签的标识是什么、显示文字是什么。逻辑大致是这样METHOD if_ex_bupa_items_extension~get_items_table. DATA: ls_item TYPE bup_bus_item. 结构名以SE18实际为准 ls_item-partner i_partner. ls_item-item ZCR. 页签内部标识自己定 ls_item-text 信用扩展. 页签显示文字 APPEND ls_item TO et_item. ENDMETHOD.这里的关键是item和text。item是你这个页签的内部标识后面GET_DETAILS、SET_DATA都会拿到它用来区分是哪个页签因为一个 BAdI 实现里你可以加多个页签。text是用户看到的文字最好用文本元素维护方便多语言。如果页签在某些角色下不想显示可以在这个方法里做判断比如根据传入的角色参数决定要不要 APPEND。但更规范的做法是在屏幕布局配置里控制代码里少写判断配置里多点开关。5.3 GET_DETAILS把屏幕接上去GET_DETAILS是真正让子屏幕显示出来的方法。当用户点击你那个页签时标准程序会调这个方法你在里面调用你的屏幕相关逻辑。核心是把函数组的屏幕接进来。常见做法是在这个方法里调用一个自定义函数模块把数据从数据库读出来放进函数组全局变量然后标准程序负责CALL SUBSCREEN把你的屏幕嵌进去METHOD if_ex_bupa_items_extension~get_details. CALL FUNCTION ZBP_EXT_GET_DETAIL EXPORTING i_partner i_partner i_item i_item i_activity i_activity. ENDMETHOD.函数模块ZBP_EXT_GET_DETAIL里做两件事根据i_partner读数据库Append 就 readBUT000自建表就SELECT自己的表把结果塞进函数组全局变量gs_ext。这样当屏幕 PBO 执行时数据就能显示出来。注意GET_DETAILS会在每次用户切换页签时都被调用所以里面的数据库读取要注意效率。BP 维护界面一次只处理一个伙伴读一行数据性能完全没问题但也别在里面写大范围循环查询。5.4 SET_DATA 与 CHECK_DATA保存与校验用户在 BP 界面上修改完点保存SET_DATA被触发。这是你唯一应该往数据库写数据的地方。在这里你需要从函数组全局变量里取出屏幕采集到的值然后落库METHOD if_ex_bupa_items_extension~set_data. CLEAR: ls_ext. ls_ext-partner i_partner. ls_ext-cr_rating gs_ext-cr_rating. ls_ext-cr_limit gs_ext-cr_limit. ls_ext-remark gs_ext-remark. MODIFY zbp_ext_credit FROM ls_ext. IF sy-subrc 0. COMMIT WORK AND WAIT. ENDIF. ENDMETHOD.CHECK_DATA用于保存前校验比如检查必输、检查金额格式。校验不通过时要返回消息让用户改METHOD if_ex_bupa_items_extension~check_data. IF gs_ext-cr_rating IS INITIAL. MESSAGE 信用评级必须填写 TYPE E. ENDIF. ENDMETHOD.这里有个坑SET_DATA和CHECK_DATA的调用时机标准程序是先CHECK_DATA再SET_DATA但如果业务逻辑复杂你不要在这个链路里做太重的操作否则影响 BP 整体保存的流畅度。5.5 屏幕布局配置让页签出现在正确的位置代码写完了页签不一定看得见还得去配置。路径是 SPRO → 跨应用组件 → SAP 业务伙伴 → 业务伙伴界面 → 业务伙伴数据 → 配置业务伙伴的屏幕布局不同版本菜单文字略有差异按你系统里的为准。在这里找到你扩展的页签条目把它分配到对应的角色比如 FLCU00 客户财务、FLVN00 供应商财务并设定显示顺序。这一步是很多人失败的原因BAdI 返回了页签但配置里没分配标准程序就认为这个页签不需要显示直接忽略。我一般都把配置分配写在实现清单里做完代码立刻去配配完再测试。6. 踩坑实录与常见问题速查6.1 页签死活不出来的几种原因页签不出来我总结下来八成是这几个原因。第一BAdI 实现没激活代码根本没生效。第二GET_ITEMS_TABLE里结构字段填错比如partner没填或者item为空标准程序没法识别。第三屏幕布局配置没分配页签被过滤掉了。第四函数组或屏幕没激活CALL SUBSCREEN找不到屏幕。第五BAdI 实现挂错了对象比如挂到了别的 BP 事务上。排查顺序我一般是先 SE19 确认实现激活状态再 SE18 检查 BAdI 定义有没有被某个过滤条件挡住再看配置分配最后用/h调试跟一下GET_ITEMS_TABLE有没有被调用。调试是最快的定位方式别靠猜。6.2 数据能显示但存不进去这种情况通常是数据流断在某一环。要么是SET_DATA里读的全局变量还是旧值屏幕 PAI 没触发值没搬回全局要么是写库时主键没对PARTNER传成了空要么是MODIFY之后没有COMMIT WORK。还有一种隐蔽情况数据其实写进去了但因为页面缓存或者没重新进 BP看起来像没存。我一般会在SET_DATA里加一个断点把准备落库的数据结构打印出来看一眼就能定位是哪一环丢了值。这个方法比看日志快得多。6.3 传输请求与增强注册的坑开发完了要传传输。函数组、屏幕、数据元素、表结构、BAdI 实现这些都要进同一个请求否则到了测试机就是一半存在一半不存在的诡异状态。特别提醒BAdI 实现SE19产生的对象要确认已经加入请求很多人只在 SE11/SE80 里挂了对象忘了 BAdI 实现结果传输后实现丢失。另外BP 屏幕布局配置属于定制请求Customizing Request要跟开发请求分开。传输顺序上先传开发对象表结构、函数组、BAdI 实现再传定制配置。顺序反了配置会找不到对象而报错。6.4 常见问题速查表现象可能原因排查动作页签完全不显示BAdI 未激活 / 配置未分配SE19 查激活状态SPRO 查布局分配页签显示点开空白屏幕未激活 / SUBSCREEN 号写错SE80 检查函数组屏幕激活状态字段无数据GET_DETAILS 读库失败 / 全局变量未赋值断点跟 GET_DETAILS保存后数据丢失SET_DATA 未落库 / 未 COMMIT断点跟 SET_DATA检查主键传输后报语法错数据元素未随请求传输检查请求对象清单完整性某些角色下不显示角色视图未分配该页签SPRO 屏幕布局按角色重新分配实操心得这套增强做完之后建议在两个地方留个文档一是函数组 Top Include 顶部注释写清楚这个增强对应的业务需求和关键参数二是 BAdI 实现类的方法注释写清楚每个方法在什么时机被调、数据流向哪里。半年后业务要改字段你翻注释比翻代码快十倍。这套 BP 屏幕增强加页签的东西说到底就是数据层 屏幕层 BAdI 注册层三块拼起来。数据层决定存哪屏幕层决定长什么样BAdI 层决定什么时候被标准程序看到。三块各自都不难难的是它们之间的时序和数据传递而这恰恰是文档里很少讲清楚的部分。我自己的体会是第一次做的时候别急着写业务逻辑先做一个只有两个字段的最小版本把页签能出来、能存、能读这条链路跑通再往上堆字段和校验。链路跑通了剩下的都是加法。
返回列表