保存数据至后台表-供大数据平台使用-JOB程序
*&---------------------------------------------------------------------*
*&程序名称 :ZBD_JOB_001
*&程序描述 : 保存数据至后台表-供大数据平台使用-JOB程序
*&---------------------------------------------------------------------*
*&Date Developer ReqNo Descriptions *
*& ========== ================== ========== ========================*
*& 2024.06.24 创建 *
*&---------------------------------------------------------------------*
REPORT zbd_job_001.
*--------数据定义 ------------------------------------------------------*
TABLES:sscrfields.
DATA:gs_001 TYPE ztbd_001,
gt_001 TYPE TABLE OF ztbd_001,
gv_xh TYPE i,
tc1 TYPE c LENGTH 15. "开始时间戳文本
DATA: functxt TYPE smp_dyntxt.
FIELD-SYMBOLS: <fs_tab> TYPE STANDARD TABLE.
*----------选择屏幕 ----------------------------------------------------*
SELECTION-SCREEN: FUNCTION KEY 1."在屏幕定义功能码
SELECTION-SCREEN BEGIN OF BLOCK a1 WITH FRAME TITLE TEXT-001.
PARAMETERS:p_rname TYPE ztbd_001-zrname,
p_report TYPE ztbd_001-zreport,
p_var TYPE ztbd_001-variant,
p_del TYPE c AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK a1.
*-------初始化----------------------------------------------------------*
INITIALIZATION.
* functxt-icon_id = icon_table_settings.
* functxt-quickinfo = TEXT-007.
* functxt-icon_text = TEXT-007.
* sscrfields-functxt_01 = functxt.
*------屏幕事件---------------------------------------------------------*
AT SELECTION-SCREEN.
CASE sscrfields-ucomm.
WHEN 'FC01'.
IF p_rname IS NOT INITIAL.
DELETE FROM ztbd_status WHERE zrname = p_rname AND zdate = sy-datum.
IF sy-subrc EQ 0.
MESSAGE '状态表删除成功' TYPE 'S'.
ELSE.
MESSAGE '状态表删除失败' TYPE 'S'.
ENDIF.
ELSE.
MESSAGE '请输入需求名称' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
WHEN OTHERS.
ENDCASE.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_rname."需求名称 F4
PERFORM frm_f4_p_rname.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_report."执行报表 F4
PERFORM frm_f4_p_report.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_var."变式 F4
PERFORM frm_f4_p_var.
AT SELECTION-SCREEN OUTPUT.
PERFORM frm_set_required."屏幕必输设置
START-OF-SELECTION.
IF p_rname IS INITIAL."需求名称 必输 检查
MESSAGE TEXT-002 TYPE 'S' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF.
IF p_report IS INITIAL."执行报表名称 必输 检查
MESSAGE TEXT-003 TYPE 'S' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF.
IF p_var IS INITIAL."变式 必输 检查
MESSAGE TEXT-005 TYPE 'S' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF.
PERFORM frm_exe."执行程序
END-OF-SELECTION.
INCLUDE zbd_job_001_f01.
ZBD_JOB_001_F01
*----------------------------------------------------------------------*
***INCLUDE ZBD_JOB_001_F01.
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form FRM_F4_P_RNAME
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_f4_p_rname .
TYPES: BEGIN OF ty_rname,
zrname TYPE ztbd_001-zrname,
END OF ty_rname.
DATA: lt_rname TYPE TABLE OF ty_rname .
SELECT zrname FROM ztbd_001 INTO CORRESPONDING FIELDS OF TABLE lt_rname WHERE zactivate = 'X'.
IF sy-subrc EQ 0.
SORT lt_rname BY zrname.
DELETE ADJACENT DUPLICATES FROM lt_rname COMPARING zrname.
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = 'ZRNAME'
dynpprog = sy-repid
dynpnr = sy-dynnr
dynprofield = 'P_RNAME'
value_org = 'S'
TABLES
value_tab = lt_rname.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_F4_P_REPORT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_f4_p_report .
TYPES: BEGIN OF ty_report,
zrname TYPE ztbd_001-zrname,
zreport TYPE ztbd_001-zreport,
ztable TYPE ztbd_001-ztable,
variant TYPE ztbd_001-variant,
END OF ty_report.
DATA: lt_report TYPE TABLE OF ty_report .
DATA:lt_fields TYPE TABLE OF dynpread,
ls_fields TYPE dynpread.
CLEAR:lt_fields,ls_fields.
* 获取屏幕上字段输入的值:此字段还没有更新到对应的内表或工作区中
ls_fields-fieldname = 'P_RNAME'.
APPEND ls_fields TO lt_fields.
"获取屏幕值
CALL FUNCTION 'DYNP_VALUES_READ'
EXPORTING
dyname = sy-cprog
dynumb = sy-dynnr
TABLES
dynpfields = lt_fields
EXCEPTIONS
invalid_abapworkarea = 1
invalid_dynprofield = 2
invalid_dynproname = 3
invalid_dynpronummer = 4
invalid_request = 5
no_fielddescription = 6
invalid_parameter = 7
undefind_error = 8
double_conversion = 9
stepl_not_found = 10
OTHERS = 11.
IF sy-subrc EQ 0.
CLEAR:ls_fields.
READ TABLE lt_fields INTO ls_fields WITH KEY fieldname = 'P_RNAME' .
IF sy-subrc = 0.
p_rname = ls_fields-fieldvalue.
ENDIF.
ENDIF.
IF p_rname IS NOT INITIAL.
SELECT * FROM ztbd_001 INTO CORRESPONDING FIELDS OF TABLE lt_report
WHERE zrname EQ p_rname.
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = 'ZREPORT'
dynpprog = sy-repid
dynpnr = sy-dynnr
dynprofield = 'P_REPORT'
value_org = 'S'
TABLES
value_tab = lt_report.
ELSE.
MESSAGE TEXT-004 TYPE 'S' DISPLAY LIKE 'W'.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_REQUIRED
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_set_required .
LOOP AT SCREEN.
IF screen-name = 'P_RNAME' OR screen-name = 'P_REPORT' OR screen-name = 'P_VAR'.
screen-required = '2'.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_GET_REPORT_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_get_report_data CHANGING pv_error TYPE c.
DATA:ls_data TYPE REF TO data,
ls_target TYPE REF TO data,
lo_table TYPE REF TO data,
dny_line TYPE REF TO data,
descr_ref TYPE REF TO cl_abap_structdescr,
gt_dfies TYPE ddfields,
gw_dfies TYPE dfies,
iv_tabname TYPE tabname.
FIELD-SYMBOLS: <fs_target> TYPE any,
<dny_wa> TYPE any,
<fs_value_sour> TYPE any,
<fs_value_tar> TYPE any,
<lt_data> TYPE STANDARD TABLE,
<ls_data> TYPE any.
UNASSIGN:<lt_data>,<ls_data>,<fs_target>.
CLEAR:iv_tabname.
cl_salv_bs_runtime_info=>set( display = '' metadata = '' data = 'X' ).
"根据配置信息获取报表数据
IF gs_001-sub_variant IS NOT INITIAL.
SUBMIT (gs_001-zreport) USING SELECTION-SET gs_001-sub_variant AND RETURN.
ELSE.
SUBMIT (gs_001-zreport) USING SELECTION-SET gs_001-variant AND RETURN.
ENDIF.
"组装返回的报表数据
CREATE DATA ls_target TYPE TABLE OF (gs_001-ztable). " 创建动态结构
ASSIGN ls_target->* TO <fs_target>. " 将动态结构赋给字段符号
iv_tabname = gs_001-ztable.
CALL METHOD zcl_hcm_public_service=>hrpa_dynamic_itab
EXPORTING
iv_tabname = iv_tabname
IMPORTING
* eo_data_struc = lo_struc
eo_data_table = lo_table.
ASSIGN lo_table->* TO <fs_tab>.
CREATE DATA dny_line LIKE LINE OF <fs_tab>.
ASSIGN dny_line->* TO <dny_wa>.
descr_ref ?= cl_abap_typedescr=>describe_by_name( gs_001-ztable ).
CALL METHOD cl_salv_data_descr=>read_structdescr
EXPORTING
r_structdescr = descr_ref
RECEIVING
t_dfies = gt_dfies[].
TRY.
cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = ls_data ).
ASSIGN ls_data->* TO <lt_data>.
IF <lt_data> IS ASSIGNED.
"锁底表
PERFORM frm_lock_table CHANGING pv_error.
IF pv_error IS INITIAL. "锁表成功,组装数据
IF p_del NE 'X'."获取底表最大序号值
SELECT MAX( zxh ) INTO gv_xh FROM (gs_001-ztable) WHERE zcdate = sy-datum.
IF sy-subrc EQ 0.
gv_xh = gv_xh + 1.
ENDIF.
ENDIF.
LOOP AT <lt_data> ASSIGNING <ls_data>.
LOOP AT gt_dfies INTO gw_dfies.
UNASSIGN:<fs_value_tar>,<fs_value_sour>.
ASSIGN COMPONENT gw_dfies-fieldname OF STRUCTURE <dny_wa> TO <fs_value_tar>. " 将目标结构的值赋给动态结构-底表
ASSIGN COMPONENT gw_dfies-fieldname OF STRUCTURE <ls_data> TO <fs_value_sour>. " 将原始结构的值赋给动态结构-报表alv结构
IF <fs_value_tar> IS ASSIGNED AND <fs_value_sour> IS ASSIGNED.
<fs_value_tar> = <fs_value_sour>.
ENDIF.
IF gs_001-zcus_fm IS NOT INITIAL AND <fs_value_tar> IS ASSIGNED.
TRY.
CALL FUNCTION gs_001-zcus_fm
EXPORTING
i_value = <ls_data>
i_name = gw_dfies-fieldname
CHANGING
o_value = <dny_wa>.
CATCH cx_no_flight_found .
ENDTRY.
ENDIF.
ENDLOOP.
UNASSIGN:<fs_value_tar>.
ASSIGN COMPONENT 'ZRNAME' OF STRUCTURE <dny_wa> TO <fs_value_tar>. " 需求名称
IF <fs_value_tar> IS ASSIGNED .
<fs_value_tar> = p_rname.
ENDIF.
UNASSIGN:<fs_value_tar>.
ASSIGN COMPONENT 'ZXH' OF STRUCTURE <dny_wa> TO <fs_value_tar>. " 序号
IF <fs_value_tar> IS ASSIGNED .
<fs_value_tar> = gv_xh.
gv_xh = gv_xh + 1.
ENDIF.
UNASSIGN:<fs_value_tar>.
ASSIGN COMPONENT 'ZCDATE' OF STRUCTURE <dny_wa> TO <fs_value_tar>. " 序号
IF <fs_value_tar> IS ASSIGNED .
<fs_value_tar> = sy-datum.
ENDIF.
APPEND <dny_wa> TO <fs_tab>.
ENDLOOP.
ENDIF.
ENDIF.
CATCH cx_salv_bs_sc_runtime_info.
MESSAGE '执行报表没有数据返回' TYPE 'E'.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SAVE_TABLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_save_table .
DATA:lv_error TYPE c,
tc2 TYPE c LENGTH 15, "结束时间戳文本
td1 TYPE d, "开始时间:日期
td2 TYPE d, "结束时间:日期
th1 TYPE i, "开始时间:时
th2 TYPE i, "结束时间:时
tm1 TYPE i, "开始时间:分
tm2 TYPE i, "结束时间:分
ts1 TYPE p , "开始时间:秒
ts2 TYPE p . "结束时间:秒.
CLEAR:lv_error.
"全量更新,先删除数据.
IF <fs_tab> IS NOT INITIAL AND p_del = 'X' AND gs_001-sub_variant IS INITIAL.
SELECT COUNT(*) FROM (gs_001-ztable) WHERE zrname = p_rname.
IF sy-subrc EQ 0.
DELETE FROM (gs_001-ztable) WHERE zrname = p_rname.
IF sy-subrc NE 0.
MESSAGE '删除数据失败' TYPE 'E'.
ENDIF.
ENDIF.
ENDIF.
"保存数据
IF <fs_tab>[] IS NOT INITIAL.
MODIFY (gs_001-ztable) FROM TABLE <fs_tab>.
IF sy-subrc NE 0.
MESSAGE '保存数据失败' TYPE 'S' DISPLAY LIKE 'E'.
ELSE.
MESSAGE '保存数据成功' TYPE 'S' .
ENDIF.
ELSE.
MESSAGE '没有需要保存的数据' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
PERFORM frm_lock_status_table CHANGING lv_error."锁状态表
IF lv_error IS INITIAL.
"再次获取执行日期,避免在执行期间内有其他job重复执行 以至于重复计算已执行job总数 ZTBD_STATUS-ZRNUM.
SELECT SINGLE zexe_date INTO gs_001-zexe_date FROM ztbd_001
WHERE zrname = gs_001-zrname AND zactivate = 'X' AND variant = gs_001-variant AND sub_variant = gs_001-sub_variant AND zreport = gs_001-zreport.
CLEAR:tc2,td1,td2,th1,th2,tm1,tm2,ts1,ts2.
td1 = tc1+0(8).
th1 = tc1+8(2).
tm1 = tc1+10(2).
ts1 = tc1+12(2).
tc2 = sy-datum && sy-uzeit.
td2 = tc2+0(8).
th2 = tc2+8(2).
tm2 = tc2+10(2).
ts2 = tc2+12(2).
gs_001-zrun_time = ( td2 - td1 ) * 24 * 3600 + ( th2 - th1 ) * 3600 + ( tm2 - tm1 ) * 60 + ( ts2 - ts1 ).
IF gs_001-zexe_date NE sy-datum.
gs_001-zexe_date = sy-datum.
gs_001-zexe_time = sy-uzeit.
PERFORM frm_update_status. "更新状态表
ELSE.
gs_001-zexe_time = sy-uzeit.
MODIFY ztbd_001 FROM gs_001.
COMMIT WORK AND WAIT.
MESSAGE '当前日期已执行过程序,状态表无需更新' TYPE 'S'.
ENDIF.
PERFORM frm_unlock_status_table."释放锁对象
ELSE.
MESSAGE '锁定状态表失败,状态表未更新' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_LOCK_STATUS_TABLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_lock_status_table CHANGING p_error TYPE c.
DO 30 TIMES.
CALL FUNCTION 'ENQUEUE_EZTBD_STATUS'
EXPORTING
mode_ztbd_status = 'E'
mandt = sy-mandt
zrname = p_rname
zdate = sy-datum
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
WAIT UP TO 1 SECONDS.
p_error = 'X'.
ELSE.
CLEAR:p_error.
EXIT.
ENDIF.
ENDDO.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_UPDATE_STATUS
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_update_status .
"统计当前需求有几个job
SELECT COUNT(*) INTO @DATA(lv_count) FROM ztbd_001 WHERE zrname = @p_rname AND zactivate = 'X'.
"获取当前需求状态
SELECT SINGLE * FROM ztbd_status INTO @DATA(ls_status) WHERE zrname = @p_rname AND zdate = @sy-datum.
IF ls_status IS NOT INITIAL.
ls_status-zrnum = ls_status-zrnum + 1."执行报表数+1
ELSE.
ls_status-zrname = p_rname.
ls_status-zrnum = 1.
ENDIF.
IF ls_status-zrnum = lv_count."报表全执行完
ls_status-zfinish = 'X'."完成标识
ENDIF.
ls_status-zdate = sy-datum.
ls_status-ztime = sy-uzeit.
"保存状态
MODIFY ztbd_status FROM ls_status.
IF sy-subrc EQ 0.
MODIFY ztbd_001 FROM gs_001.
COMMIT WORK AND WAIT.
MESSAGE '更新状态表成功' TYPE 'S'.
ELSE.
MESSAGE '更新状态表失败' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_UNLOCK_STATUS_TABLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_unlock_status_table .
CALL FUNCTION 'DEQUEUE_EZTBD_STATUS'
EXPORTING
mode_ztbd_status = 'E'
mandt = sy-mandt
zrname = p_rname
zdate = sy-datum.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_F4_P_VAR
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_f4_p_var .
TYPES: BEGIN OF ty_var,
report TYPE varid-report,
variant TYPE varid-variant,
ename TYPE varid-ename,
END OF ty_var.
DATA: lt_var TYPE TABLE OF ty_var.
DATA:lt_fields TYPE TABLE OF dynpread,
ls_fields TYPE dynpread.
CLEAR:lt_fields,ls_fields.
* 获取屏幕上字段输入的值:此字段还没有更新到对应的内表或工作区中
ls_fields-fieldname = 'P_REPORT'.
APPEND ls_fields TO lt_fields.
"获取屏幕值
CALL FUNCTION 'DYNP_VALUES_READ'
EXPORTING
dyname = sy-cprog
dynumb = sy-dynnr
TABLES
dynpfields = lt_fields
EXCEPTIONS
invalid_abapworkarea = 1
invalid_dynprofield = 2
invalid_dynproname = 3
invalid_dynpronummer = 4
invalid_request = 5
no_fielddescription = 6
invalid_parameter = 7
undefind_error = 8
double_conversion = 9
stepl_not_found = 10
OTHERS = 11.
IF sy-subrc EQ 0.
CLEAR:ls_fields.
READ TABLE lt_fields INTO ls_fields WITH KEY fieldname = 'P_REPORT' .
IF sy-subrc = 0.
p_report = ls_fields-fieldvalue.
ENDIF.
ENDIF.
IF p_report IS NOT INITIAL.
SELECT * FROM varid INTO CORRESPONDING FIELDS OF TABLE lt_var
WHERE report EQ p_report AND transport NE 'B'.
IF sy-subrc EQ 0.
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = 'VARIANT'
dynpprog = sy-repid
dynpnr = sy-dynnr
dynprofield = 'P_VAR'
value_org = 'S'
TABLES
value_tab = lt_var.
ELSE.
MESSAGE TEXT-006 TYPE 'S' DISPLAY LIKE 'W'.
ENDIF.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_EXE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_exe .
DATA:ls_001 TYPE ztbd_001,
lv_error TYPE c.
CLEAR:gt_001,gs_001,gv_xh,ls_001.
gv_xh = 1.
"获取配置表数据
SELECT * INTO TABLE gt_001 FROM ztbd_001 WHERE zrname = p_rname AND zreport = p_report AND variant = p_var AND zactivate = 'X'.
IF sy-subrc EQ 0.
SORT gt_001 BY sub_variant ztable.
LOOP AT gt_001 INTO gs_001.
CLEAR:lv_error,tc1.
tc1 = sy-datum && sy-uzeit.
IF gs_001-ztable NE ls_001-ztable.
gv_xh = 1.
ENDIF.
"获取报表数据
PERFORM frm_get_report_data CHANGING lv_error.
IF lv_error IS INITIAL.
"保存报表数据 更新状态表
PERFORM frm_save_table.
"释放底表
PERFORM frm_unlock_table.
ENDIF.
ls_001 = gs_001.
CLEAR:gs_001.
ENDLOOP.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_UNLOCK_TABLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_unlock_table.
DATA:lv_name TYPE rstable-tabname.
CLEAR:lv_name.
lv_name = gs_001-ztable.
CALL FUNCTION 'DEQUEUE_E_TABLE'
EXPORTING
mode_rstable = 'E'
tabname = lv_name.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_LOCK_TABLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_lock_table CHANGING p_error TYPE c.
DATA:lv_msg TYPE string,
lv_name TYPE rstable-tabname.
CLEAR:lv_msg,lv_name.
lv_name = gs_001-ztable.
DO 60 TIMES.
CALL FUNCTION 'ENQUEUE_E_TABLE'
EXPORTING
mode_rstable = 'E'
tabname = lv_name
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
WAIT UP TO 1 SECONDS.
p_error = 'X'.
ELSE.
CLEAR:p_error.
EXIT.
ENDIF.
ENDDO.
IF p_error EQ 'X'.
lv_msg = '表' && gs_001-ztable && '锁定失败' .
MESSAGE lv_msg TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ENDFORM.