ARTICLE DETAIL

资讯详情

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

三款ABAP红包程序:干支计算、代码体检与ALV清单导出

三款ABAP红包程序:干支计算、代码体检与ALV清单导出 2026年2月17日是农历丙午年正月初一马年春节。在SAP圈子里泡了这么多年每年春节前我都有个习惯写点ABAP小工具当“代码红包”发给团队和圈子里的朋友。今年马年我整理了三款自己写过、也实际用过的红包程序今天一并送给大家。先说清楚这个“红包”不是转账红包而是三个可以直接在SAP系统里建出来运行的ABAP报表程序——一个算马年倒计时和干支生肖一个做源码体检一个管春节祝福清单的ALV导出。它们既照顾了过年气氛又把ABAP开发里特别常用的日期处理、字符串校验、SORT排序、ALV展示、桌面文件导出这些知识点揉进去了。不管你是SAP开发顾问、运维还是刚学ABAP的初学者把这三个程序搭起来跑一遍收获比抢个几块钱红包实在多了。1. 为什么ABAP开发者会送“代码红包”三款程序的选型思路每年这个时候总有人问我“马年做点什么有意思的ABAP程序好”我今年选了三款不是随手拼的是有意做了分工。第一款是计算工具解决“今年到底是啥年”“离大年初一还有几天”这类春节高频问题。别看问题简单真要用ABAP算干支、生肖、春节日期很多人的第一反应是去网上抄一段农历算法抄完发现系统版本不兼容、性能又差。我给的方案是“靠谱的简化版”生肖和干支用公式算春节日期用一张小内表维护代码短、跑得快和网上的古董代码完全不同。第二款是开发辅助工具灵感来自那几个常年被搜索的ABAP问题怎么判断一个字符串是不是数值、SORT中文是按什么排的、怎么查看用户登录日期。我把这些功能打包成一个“新春代码体检助手”把一段源码粘进去它能帮你检查行长度、硬编码、数值类型、排序写法顺手显示当前用户的最后登录日期。对带新人的团队来说这个工具就是一面镜子能让新人自己发现代码里的毛病。第三款是业务工具做一张马年新春祝福清单。做顾问和项目经理的年底总要群发祝福但联系人多了之后谁发过、谁没发过、按什么顺序发全靠脑子记容易漏。我把它做成了ALV表格支持颜色高亮、自定义排序、一键导出Excel到桌面这就是一个轻量的客户关系管理工具换到其他业务场景也能直接用。三款程序都只依赖标准ABAP功能不装额外组件ECC和S/4 HANA都能跑。我在文中会给核心代码和步骤两杯咖啡的时间就能搭完。红包定位核心知识点适合人群马年倒计时计算器春节趣味计算日期加减、干支生肖公式所有人新春代码体检助手ABAP代码自检SORT、数值判断、代码规范开发、带新人ALV祝福清单群发管理工具ALV、图标颜色、桌面导出顾问、项目经理2. 红包一马年倒计时与干支生肖计算器附核心算法2.1 输入日期输出马年专属数据这款程序我起名叫ZHR_NEWYEAR_2026标准的ALV报表结构选择屏幕就一个参数日期。你输入任意一个公历日期比如2026年2月1日程序会输出三样东西距离2026年春节2月17日还有多少天、当年的天干地支和生肖、以及这天的纳音比如丙午年是天河水算是个彩蛋。界面效果是这样的执行后屏幕直接输出一段文字不用ALV因为数据量就一行用ALV反而显得重。如果日期已经过了春节程序会把倒计时改成“马年春节已过期待明年”然后再输出一个“距离下一年春节还有XX天”的提示。这样即使过了年程序也不会闲置一年四季都能用。2.2 干支、生肖、春节日期的ABAP实现先解决生肖和干支。公式记好这是我在好几个项目里验证过的生肖(年份 - 4) mod 12求余后映射到子丑寅卯……序列0子鼠1丑牛……6午马。天干(年份 - 4) mod 100甲1乙……2丙。地支同生肖的计算方式天干配地支组合得出来的就是完整纪年比如2026年(2026-4) mod 10 2对应丙(2026-4) mod 12 6对应午所以是丙午年。我在代码里用一个内部方法实现简洁也好维护METHOD calc_zodiac. DATA: lv_year TYPE i, lv_g TYPE i, lv_z TYPE i. lv_year i_year. lv_g ( lv_year - 4 ) MOD 10. lv_z ( lv_year - 4 ) MOD 12. 天干字符串按索引取 c_gan 甲乙丙丁戊己庚辛壬癸. c_zhi 子丑寅卯辰巳午未申酉戌亥. r_gan c_ganlv_g(1). r_zhi c_zhilv_z(1). 生肖映射0鼠1牛2虎3兔4龙5蛇6马 DATA: lt_sx TYPE TABLE OF string. APPEND: 鼠 TO lt_sx, 牛 TO lt_sx, 虎 TO lt_sx, 兔 TO lt_sx, 龙 TO lt_sx, 蛇 TO lt_sx, 马 TO lt_sx, 羊 TO lt_sx, 猴 TO lt_sx, 鸡 TO lt_sx, 狗 TO lt_sx, 猪 TO lt_sx. READ TABLE lt_sx INTO r_shengxiao INDEX ( lv_z 1 ). ENDMETHOD.注意一个细节字符串偏移量c_ganlv_g(1)里的lv_g必须是整数如果之前的MOD结果是负数ABAP的MOD在某些老版本里对负数处理不同要先用ABS取绝对值。另外这种方法算的是“公历年份”对应的干支不处理春节分界。严格按农历算的话2026年1月1日到2月16日之间出生的人还属于乙巳蛇年但通用礼俗场景下按公历年份算影响不大代码里提一句边界情况就行。2.3 春节日期维护表与日期差计算农历算法在ABAP里重写一遍太没必要我建议直接用内表维护近十年的春节公历日期。这个表放在程序初始化时填充简单可靠TYPES: BEGIN OF ty_chunjie, year TYPE i, date TYPE d, END OF ty_chunjie. DATA: gt_chunjie TYPE TABLE OF ty_chunjie. INITIALIZATION. APPEND VALUE: #( year 2025 date 20250129 ), #( year 2026 date 20260217 ), #( year 2027 date 20270206 ), #( year 2028 date 20280126 ), #( year 2029 date 20290213 ), #( year 2030 date 20300203 ) TO gt_chunjie.计算倒计时用CL_DAY_ATTRIBUTES或直接做日期减法都行ABAP日期类型本身可以用减法算出天数差DATA: lv_diff TYPE i. lv_diff selected_date - chunjie_date. 正数说明还没到春节这地方有一个容易踩的坑“abap 一年前”这个热词对应的需求很多新手会直接写lv_date sy-datum - 365但这样算闰年会有偏差比如2025年到2024年有366天。算“一年前”更稳妥的写法是用CL_ABAP_CONTEXT_INFO或RP_CALC_DATE_IN_INTERVAL这类函数做年单位加减按自然年处理比固定减365天要准。3. 红包二新春代码体检助手把几个热搜问题装进一个程序3.1 程序形态粘一段代码按一下执行第二个红包程序名叫ZHR_CODE_HEALTH_2026它是我平时给团队做Code Review时的辅助工具进化来的。过年期间我把界面改成了“新春红”主题选屏幕输入一个源码片段执行后输出一份《源码健康报告》报告列了五个体检项每行代码长度是否超过80字符超过给出警告。是否存在硬编码字符串直接写在代码里的值比如IF status X。字符串是否为数值类型。SORT语句的排序方式是否考虑过中文场景。当前用户的最后登录日期和最后一次登录时间。为什么做这五项因为这段时间搜索指数最高的几个ABAP问题全在这里了。新手最容易犯的错也就是这些行太长不换行、魔法数字满天飞、把数字字符串当数字处理导致dump、SORT中文排出来不是想要的顺序、登录日志查不到。与其每次Review都重复说不如给一个工具让他们自己查。3.2 数值类型判断别再用“硬转”了“abap 检查是否为数值类型”这个搜索点本质是很多人不知道ABAP里怎么优雅地判断一个字符串能不能转成数字。常见的错误写法是lv_num lv_string.一旦字符串里有字母程序直接dump。负责任的写法是从ABAP 7.40开始可以直接用类方法但为了兼容老系统我推荐用下面这套TRY CATCH加正则的方案METHOD is_numeric. r_result abap_false. IF i_value IS INITIAL. RETURN. ENDIF. 先做正则预检兼容整数、小数、负数 FIND REGEX ^-?[0-9](\.[0-9])?$ IN i_value. IF sy-subrc 0. RETURN. ENDIF. 再交给TRY CATCH做最终转换验证 TRY. lv_num i_value. r_result abap_true. CATCH cx_sy_conversion_no_number. r_result abap_false. ENDTRY. ENDMETHOD.这套方法的好处是双保险正则过滤掉明显不是数字的TRY CATCH拦截那些正则放过但转换依旧失败的边界情况。ABAP新手容易只看一种解法实际上生产环境里两种配合才是最稳的。3.3 SORT中文排序和登录日期查询关于SORT很多人不知道ABAP默认的SORT是按系统代码页内码排的。英文字母还好说中文如果按内码排和“拼音排序”或者“笔画排序”完全是两个结果。SAP在较新的版本里支持SORT BY 字段 AS TEXT可以按文本排序规则来排中文SORT gt_data BY name AS TEXT.如果你的系统版本不支持AS TEXT还有一个变通方案先把中文转成拼音放到临时字段再按拼音字段SORT。拼音转换函数可以用HR_HK_GET_PINYIN或类似的HR专用函数但注意这些函数不是所有系统都装了用之前先F1确认函数存在。“abap中查看用户登录日期”这个高频问题其实是查两个表USR02用户主数据里的最后登录日期字段TRDAT和最后登录时间字段LTIME。USR41当前正在登录的用户会话信息可以看到在线用户。体检助手在报告末尾查一下当前用户的USR02记录直接输出SELECT SINGLE bname, trdat, ltime FROM usr02 WHERE bname sy-uname INTO DATA(ls_usr).输出结果是最后登录2026-01-15 18:23:45这类格式。这里要提醒一句查别人登录日期属于系统审计范畴建议只在授权排查或安全审计场景下用自己写的工具只查自己的信息最稳妥。4. 红包三ALV马年祝福清单一键导出的群发管理工具4.1 从内表到ALV祝福清单的数据结构设计第三款ZHR_ALV_NEWYEAR_2026是我过年用最多的程序。作为顾问手机通讯录里一拉就是几百个联系人客户、团队成员、合作伙伴、老同事。每年群发祝福最头疼的不是写文案而是管理“发过没发过”“谁要先发”。用Excel管理当然可以但平时就在SAP里工作顺手建一张表、用一个ALV程序展示更符合我的操作习惯。程序允许你从展示屏维护一个内表字段包含姓名关系客户/同事/朋友/家人生肖根据出生年份自动算直接引用红包一的算法优先级P1先发、P2普通、P3后发状态未发/已发祝福语可以针对生肖定制ALV展示时第一列显示一个图标P1显示红灯、P2显示黄灯、P3显示绿灯。状态列已发的显示一个对勾图标未发的留空。这样一屏扫过去哪些人还没发、哪些人是重点客户一目了然。4.2 颜色行、图标和自定义排序的实现这里给一段ALV关键代码字段目录的设置和颜色行处理是我压箱底的经验 设置字段目录 CLEAR gs_fcat. gs_fcat-fieldname ICON. gs_fcat-coltext 状态图标. gs_fcat-outputlen 6. gs_fcat-just C. APPEND gs_fcat TO gt_fcat. gs_fcat-fieldname NAME. gs_fcat-coltext 联系人. gs_fcat-ref_table ZHR_NEWYEAR. gs_fcat-ref_field NAME. APPEND gs_fcat TO gt_fcat. 行颜色将ALV输出结构里加一个隐藏字段 COLOR(4) TYPE c 值格式C710 表示绿色C610 表示黄色C510 表示红色 LOOP AT gt_output ASSIGNING FIELD-SYMBOL(fs). CASE fs-priority. WHEN P1. fs-color C510. 红色重点 WHEN P2. fs-color C610. 黄色普通 WHEN P3. fs-color C710. 绿色可后置 ENDCASE. ENDLOOP. CALL FUNCTION REUSE_ALV_GRID_DISPLAY EXPORTING i_structure_name ZHR_NEWYEAR i_save A TABLES t_outtab gt_output.ALV这里的颜色格式是C颜色编号加权数C510里的5是红色系、1是加重程度C710是绿色系。很多人第一次写的时候会把颜色值塞错字段记住行颜色存哪个字段取决于字段目录里有没有定义过EMPHASIZE通常我会在输出结构里显式放一个COLOR字段然后传I_STRUCTURE_NAME让ALV自动识别。注意如果用I_STRUCTURE_NAME需要在数据字典里建结构如果你不想建结构可以把所有字段手动加进GT_FCAT这时行颜色字段放在输出内表对应位置也能生效。按生肖排序这个需求我用的是SORT gt_data BY shengxiao AS TEXT。按生肖字符串排其实不科学马的优先级和鼠的优先级完全看字符串排序。我更建议按生肖对应的地支序号排先在心里维护一张顺序表子1、丑2……午7再按这个序号SORT这样排出来是固定的生肖规律不会乱七八糟。SORT gt_data BY sx_order. 按生肖顺序号码排4.3 导出Excel桌面路径的正确拿法这是红包三里最有复用价值的部分。群发祝福前我习惯把ALV数据导出成Excel回到手机或邮件里慢慢发。ABAP导出Excel最常见的方法是GUI_DOWNLOAD函数但这里有个大坑很多老代码会写p_path C:\Users\Administrator\Desktop\...这在单机测试没问题放到公司网络环境或虚拟机里就傻了——用户根本不一定叫Administrator路径也不一定存在。正确做法是用CL_GUI_FRONTEND_SERVICESGET_DESKTOP_DIRECTORY获取桌面路径DATA: lv_desktop_path TYPE string. TRY. CALL METHOD CL_GUI_FRONTEND_SERVICESGET_DESKTOP_DIRECTORY CHANGING desktop_directory lv_desktop_path. CATCH cx_root. MESSAGE 无法获取桌面路径请手工输入 TYPE E. ENDTRY. CONCATENATE lv_desktop_path \马年祝福清单_ sy-datum .xls INTO lv_path.拿到桌面路径后用GUI_DOWNLOAD或者生成HTML格式再转Excel都行。实际经验告诉我最省事的是把ALV内容转成TAB分隔的文本文件扩展名写成XLSExcel打开时能自动识别成表格。用函数REUSE_ALV_EXCEL_DOWNLOAD也可以但那个函数在新BSP应用里偶尔有兼容问题老系统反而好使。我的建议是内表转TAB文本用GUI_DOWNLOAD最通用代码最少也不会受Excel版本影响。还要提一个容易翻车的细节CL_GUI_FRONTEND_SERVICES这类前端服务在后台作业里是不能用的因为后台作业没有前端交互。如果你想在SM36定时任务里跑这个程序并导出Excel必须改用应用服务器路径用OPEN DATASET直接写服务器文件目录而不是前端桌面路径。这两个场景的差异是运维经常踩的坑。5. 运行前的检查清单激活、权限、ECC与S/4的兼容性5.1 从零开始建程序的完整步骤很多初学者拿到代码后卡在第一步程序怎么建。这里走一遍完整流程30秒就能建好用SE38进入ABAP编辑器输入程序名比如ZHR_NEWYEAR_2026点创建。程序属性里类型选“可执行程序”状态选“未保存”测试用如果是正式使用建议申请传输请求按公司规范走。把代码完整粘进去点激活CtrlF3。如果系统提示“对象未激活”检查语法错误信息通常都是字段名或表名在当前系统里不存在比如S/4新版本禁用了一些老表。激活成功后直接F8执行输入参数看结果。如果希望“红包”程序可以被团队其他人使用建议把三个程序一起申请一条传输请求Workbench请求打包发到测试和生产系统。这里还有一个SAP顾问必须懂的规范程序名必须以Z开头否则在升级或传输时容易被覆盖这是老生常谈但总有人犯。5.2 ECC和S/4的兼容性差异写这三个红包程序时我有意避开了很多ECC和S/4不兼容的写法但还是要提醒几处S/4 HANA里很多表结构变了比如传统的MARA、MSEG虽然是标准表还能用但一些以T_开头的表如T001、T003等在新版本里逐步被CDS视图替代。所以代码里尽量不要直接SELECT * FROM t001这种写死表名的逻辑建议用视图。曾经的示例表SPFLI和SCARR在S/4 2020之后已经被注释掉了很多教程代码一跑就报“表不存在”。如果你是在S/4系统里测试这三个红包程序没依赖这些示例表放心跑。有人搜abap cm_fv_prod_vers_db_update这个函数是S/4里产品版本更新的内部函数它属于特定业务范围的数据库更新模块别在普通报表里调用它需要特定权限和业务上下文随便CALL会锁表或者更新出脏数据。这类功能函数在有明确的业务需求和权限审批之前不建议在自定义代码里直接引用。5.3 高频FAQ合并答疑FBV3/FB03、DEQUEUE_ALL、ADT环境杂谈每年分享代码后评论区总有几个问题反复被问这里一起回答了。第一个是“abap中fbv3和fb03的区别”。这是一个财务模块的经典问题。FB03是显示已过账凭证也就是正式进入总账、应收账款等模块的财务凭证。FBV3则是显示预制凭证也就是还没正式过账、只是暂时保存的模拟凭证。两者界面几乎一样很多人分不清记住一句话已过账用FB03未过账的预制造凭证用FBV3。用代码做凭证处理时如果业务要求“只能查看未过账凭证”就要严格限制FBV3权限因为未过账数据状态不稳定乱改会影响财务结账。第二个是“abap dequeue_all”。我见过不少开发把它当万能解锁语句在程序末尾一股脑调用DEQUEUE_ALL。这个函数的作用是释放当前工作进程中该程序持有的所有锁对象听起来很安全但问题是如果你的程序调用了某个RFC函数RFC函数内部也ENQUEUE了锁你在主程序里执行DEQUEUE_ALL会把RFC内部加的锁一起释放掉。如果那边正好在更新数据锁被提前释放更新冲突的概率直线上升。正确的做法是按锁对象逐个调用对应的DEQUEUE函数不要一把梭。只有LRFC相关场景明确知道所有锁都不需要保留时才用DEQUEUE_ALL。第三个是关于开发环境。热搜词里“eclipse安装jdk开发abap”这种说法不够准确真正的ABAP开发环境是SAP GUISE38和基于Eclipse的ADTABAP Development Tools。用ADT做ABAP开发时确实需要JDK但我建议不要盲目追最新JDK版本因为SAP NetWeaver版本和ADT插件版本对JDK版本有严格对应关系。我见过有人把JDK升到最新版ADT直接打不开最后又降回老版本。选JDK时先去SAP官方兼容性矩阵查一下匹配列表里的版本装好之后就别频繁升了。最后我个人的一点体会这三款红包看着简单其实每个程序背后都对应着日常工作中真实遇到的痛点日期算不明白、代码格式没人管、祝福名单乱成一锅粥。做ABAP开发越久越发现衡量一个工具好不好用不是看技术多炫而是看你能不能在三分钟之内把它讲清楚、让同事愿意用。我自己每次发“代码红包”最开心的不是被人夸代码写得好而是几个月后听到有人说“那个元旦倒计时程序我改了改现在部门活动都在用”——这就值了。三个程序你可以直接拿去用也可以按自己的场景加功能。代码本来就是拿来改的祝大家马年春节代码一次激活通过传输不报错生产环境稳如老狗。
返回列表