ABAP中不使用API如何从内表日期字段计算服务时长的年数和月数
问题原因
你当前直接对年份做减法的逻辑没有校验「当前月日是否已经过了当年的入职周年日」,所以会出现未到周年就多算1年的问题。另外你现有代码有两处需要先修正的定义问题:
- 你定义的
s_empdetails结构中姓名字段为fname,但后续赋值时写的是name,会报字段不存在错误 s_details结构中serv_yrs定义为dats(日期类型)不合理,需要修改为数值类型存储服务时长
调整方案
第一步:修正结构定义
TYPES : BEGIN OF s_empdetails, empid TYPE n, fname(20) TYPE c, doj TYPE dats, END OF s_empdetails. TYPES : BEGIN OF s_details, empid TYPE n, fname(20) TYPE c, " 补充姓名字段 serv_yrs TYPE i, " 存储服务年数(整数) serv_mons TYPE i, " 存储服务剩余月数(可选,不需要可以去掉) END OF s_details.
第二步:修改服务时长计算逻辑
推荐使用SAP标准函数计算,无需自行处理闰年、大小月等边界场景,准确率更高:
LOOP AT gt_result ASSIGNING FIELD-SYMBOL(<gwa_result>). READ TABLE gt_header ASSIGNING <gwa_header> WITH KEY empid = <gwa_result>-empid. IF sy-subrc = 0. DATA: lv_total_months TYPE i. " 标准函数计算两个日期之间的总月数 CALL FUNCTION 'HR_99S_MONTHS_BETWEEN_DATES' EXPORTING im_date_low = <gwa_header>-doj im_date_high = gv_date IMPORTING ex_months = lv_total_months. " 总月数整除12得到完整年数,取余得到不足1年的月数 <gwa_result>-serv_yrs = lv_total_months DIV 12. <gwa_result>-serv_mons = lv_total_months MOD 12. ENDIF. ENDLOOP.
如果不想调用标准函数,也可以用手动判断逻辑实现:
LOOP AT gt_result ASSIGNING FIELD-SYMBOL(<gwa_result>). READ TABLE gt_header ASSIGNING <gwa_header> WITH KEY empid = <gwa_result>-empid. IF sy-subrc = 0. DATA(lv_curr_md) = gv_date+4(4). " 当前日期的月日拼接值,比如20240205取0205 DATA(lv_doj_md) = <gwa_header>-doj+4(4). " 入职日期的月日拼接值 " 先计算年份差,未到周年日则减1 <gwa_result>-serv_yrs = gv_date+0(4) - <gwa_header>-doj+0(4). IF lv_curr_md < lv_doj_md. <gwa_result>-serv_yrs = <gwa_result>-serv_yrs - 1. ENDIF. " 计算月数(不需要可以去掉这段) DATA: lv_curr_month = gv_date+4(2), lv_curr_day = gv_date+6(2), lv_doj_month = <gwa_header>-doj+4(2), lv_doj_day = <gwa_header>-doj+6(2). IF lv_curr_month >= lv_doj_month. <gwa_result>-serv_mons = lv_curr_month - lv_doj_month. ELSE. <gwa_result>-serv_mons = 12 + lv_curr_month - lv_doj_month. ENDIF. IF lv_curr_day < lv_doj_day. <gwa_result>-serv_mons = COND #( WHEN <gwa_result>-serv_mons - 1 < 0 THEN 11 ELSE <gwa_result>-serv_mons - 1 ). ENDIF. ENDIF. ENDLOOP.
内容的提问来源于stack exchange,提问作者sumedh patil
相关产品推荐
相关产品推荐

