前几天,公司HR的同事找到我,说他们 最近遇到了比较棘手的事情,背景是集团在搭建任职资格标准,需要对三级序列进行拆分,SAP需
要新增100多个三级序列信息,每个均需配置在200多
个人事范围下,配置量非常非常大,HR顾问在有限时间内无法完成,可能会影响系统上线。然后问我是不是有办法,说甚至已经联系了SAP原厂的人求助了。
我向来喜欢干这种别人觉着棘手的问题(ABAP存在的意义不正在于此吗?
),而且以前也有数次协助顾问做批量配置的经验,对这种事情的解决流程和需要注意的点都比较清楚,于是我就愉快的答应了。
在和HR顾问详细沟通后,得知需要配置诸如社保管理指定管理机构等9个配置项:
每一项的配置都很简单,根据人事范围填入值即可,每个人事范围都有固定的对应值。但是因为每个人事范围/人事子范围都需要双击进去修改,所以虽然配置简单,但是工作量巨大,没有程序辅助还真是一个头疼的事儿。
我挨个看了下9个配置项的后台表,虽然是9个维护视图,但是只有两张表, T001P和
T7CN0P,而且这两个表主键是相同的,这是批量维护这种工作最简单的一种情况,看来一个ALV就搞定了,小菜呀。
解决问题的思路是直接把数据塞到表里面,不再通过SPRO的配置界面,但是这样做有一个前提,就是确认标准配置(SM30)仅仅更改了 T001P和
T7CN0P的对应列的值,而没有做其他的小动作。还有就是因为是直接UPDATA表,系统不会自动记录修改,这就需要使用程序来把更改的项目添加到传输请求里面。
是否悄悄更新了其他表需要通过跟踪表更新来确认并且要模块顾问验证这样配置的数据能否正常使用。表更新的验证比较容易,只要通过ST05跟踪一下就可以了,经过跟踪发现这9个配置项确实是只更新了前面说的两个表,没有做其他的小动作。而且HR顾问那边也验证了这种方法直接塞到表的数据是完全可以正常使用的,既然思路没有问题,那么就开干了。
以前的批量维护做法都是搞上一个ALV或者TableControl界面,变单个维护为批量维护,还是需要顾问在界面上填数据的,但是本例比较特殊,每个人事范围都有固定的值,所以打算更进一步,搞一个配置表,把每个人事范围对应的字段值维护到表里面,这样就可以自动填充了,顾问只需要确认一下,如有特例则手工改一下,没有特例的话直接点一个“保存”就完成配置了。
因为做ALV或者TableControl的维护属于开发的基本操作,没有什么难度,本程序的重点就变成了如何把更改的数据加入到传输请求里面,而且请求里面需要体现出SPRO的配置路径,不能仅仅是一个表或者视图的内容,如下图
闲话少叙,在经过一两次的完善后,程序最终定型了。
运行界面如下:
配置表 结 构 和 程序代码 如下:
*&---------------------------------------------------------------------**& Report ZHR01*&---------------------------------------------------------------------**& Baitianzhen*& 2024.04.26*&---------------------------------------------------------------------*REPORT zt001p NO STANDARD PAGE HEADING.
TYPE-POOLS: slis.TABLES: t001p,t7cn0p.DATA: gt_fldct TYPE lvc_t_fcat, gs_glayt TYPE lvc_s_glay, gs_slayt TYPE lvc_s_layo, gv_repid TYPE sy-repid.
DATA: BEGIN OF gs_out. INCLUDE TYPE t001p.DATA: name1 TYPE t500p-name1, phfac TYPE t7cn0p-phfac, psiau TYPE t7cn0p-psiau, msiau TYPE t7cn0p-msiau, usiau TYPE t7cn0p-usiau, isiau TYPE t7cn0p-isiau, bsiau TYPE t7cn0p-bsiau, taxgp TYPE t7cn0p-taxgp, color TYPE etloghead_color-ct, seled TYPE char1, END OF gs_out.DATA: gt_out LIKE TABLE OF gs_out.DATA: gs_col TYPE lvc_s_scol.DATA: gt_cfg TYPE TABLE OF zt001p WITH HEADER LINE.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE btxt1. SELECT-OPTIONS: s_werks FOR t001p-werks, s_btrtl FOR t001p-btrtl.SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE btxt2. PARAMETERS: p_mozko AS CHECKBOX DEFAULT 'X', p_mosid AS CHECKBOX DEFAULT 'X', p_mofid AS CHECKBOX DEFAULT 'X', p_moabw AS CHECKBOX DEFAULT 'X', p_wktyp AS CHECKBOX DEFAULT 'X', p_trfgb AS CHECKBOX DEFAULT 'X', p_phfac AS CHECKBOX DEFAULT 'X', p_psiau AS CHECKBOX DEFAULT 'X', p_taxgp AS CHECKBOX DEFAULT 'X'.SELECTION-SCREEN END OF BLOCK b2.
SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE btxt3. PARAMETERS: p_all AS CHECKBOX. PARAMETERS: p_chk AS CHECKBOX. PARAMETERS: p_auto AS CHECKBOX DEFAULT 'X'.SELECTION-SCREEN END OF BLOCK b3.AT SELECTION-SCREEN OUTPUT. btxt1 = '数据选择'. btxt2 = '配置项'. btxt3 = '选项'. %_s_werks_%_app_%-text = '人事范围'. %_s_btrtl_%_app_%-text = '人事子范围'. %_p_mozko_%_app_%-text = '用于时间定额的组人员子范围'. %_p_mosid_%_app_%-text = '将工作日程表的人事子范围分组'. %_p_mofid_%_app_%-text = '定义公休日日程表分组'. %_p_moabw_%_app_%-text = '缺勤/出勤的人事子范围分组'. %_p_wktyp_%_app_%-text = '主要工资项的人员子范围'. %_p_trfgb_%_app_%-text = '工资等级结构分配给企业结构'. %_p_phfac_%_app_%-text = '公积金管理机构'. %_p_psiau_%_app_%-text = '社会保险管理机构'. %_p_taxgp_%_app_%-text = '雇主税收组'. %_p_all_%_app_%-text = '显示所有数据'. %_p_chk_%_app_%-text = '检查现有数据'. %_p_auto_%_app_%-text = '根据配置表自动填充'.
AT SELECTION-SCREEN. IF sy-ucomm = 'ONLI'. PERFORM input_check. ENDIF.
START-OF-SELECTION. PERFORM savelog IN PROGRAM zreplog USING sy-repid '' IF FOUND. PERFORM fill_fcat. PERFORM getdata. PERFORM updatelog IN PROGRAM zreplog IF FOUND. PERFORM outdata.
*&---------------------------------------------------------------------**& Form input_check*&---------------------------------------------------------------------*FORM input_check. DATA: lv_ekey TYPE vim_enqkey.
IF p_mozko = '' AND p_mosid = '' AND p_mofid = '' AND p_moabw = '' AND p_wktyp = '' AND p_trfgb = '' AND p_phfac = '' AND p_psiau = '' AND p_taxgp = ''. MESSAGE e000(oo) WITH '至少选择一项更改'. ENDIF.
lv_ekey = sy-mandt. CALL FUNCTION 'ENQUEUE_E_TABLEE' EXPORTING tabname = 'T001P' varkey = lv_ekey EXCEPTIONS foreign_lock = 1 system_failure = 2 OTHERS = 3. IF sy-subrc NE 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. CALL FUNCTION 'ENQUEUE_E_TABLEE' EXPORTING tabname = 'T7CN0P' varkey = lv_ekey EXCEPTIONS foreign_lock = 1 system_failure = 2 OTHERS = 3. IF sy-subrc NE 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF.ENDFORM.*&---------------------------------------------------------------------**& 获取数据,程序执行和刷新的时候调用*&---------------------------------------------------------------------*FORM getdata. SELECT * INTO TABLE gt_cfg FROM zt001p.
SELECT t001p~mandt t001p~werks t500p~name1 t001p~btrtl t001p~btext t001p~mozko t001p~mosid t001p~mofid t001p~moabw t001p~wktyp t001p~molga t001p~trfgb t001p~trfar t7cn0p~phfac t7cn0p~psiau t7cn0p~msiau t7cn0p~usiau t7cn0p~isiau t7cn0p~bsiau t7cn0p~taxgp INTO CORRESPONDING FIELDS OF TABLE gt_out FROM t001p LEFT JOIN t500p ON t500p~persa = t001p~werks LEFT JOIN t7cn0p ON t7cn0p~werks = t001p~werks AND t7cn0p~btrtl = t001p~btrtl WHERE t001p~werks IN s_werks AND t001p~btrtl IN s_btrtl ORDER BY t001p~werks t001p~btrtl. IF gt_out IS INITIAL. MESSAGE s000(oo) WITH '无数据'. ELSE. LOOP AT gt_out INTO gs_out. READ TABLE gt_cfg WITH KEY werks = gs_out-werks.
IF p_mozko = 'X' A...