程序环境:RFC server 接口模式
今天接到一个需求,是物料主数据接口一次发送数据过多的场景就会比较慢,需要在接口上分批次发出。参考了原来原厂顾问的代码,发现比较精炼,虽然感觉有点怪怪的,还是按这个逻辑改完。
自己再加了一个进度条,提示用户体验:
简单的例子如下:
DATA n TYPE i.
DATA per TYPE i.
n = lines( s_m ). "取内表
per = n / 10. "确定份数
LOOP AT s_m[] INTO DATA(gs_m).
APPEND gs_m to lt_small.
IF ( sy-tabix MOD per ) EQ 0.
"todo lt_small
write:/ 'goto:...................'.
LOOP AT lt_small INTO DATA(GS_temp).
write:/ GS_temp-LOW.
ENDLOOP.
REFRESH lt_small.
ENDIF.
ENDLOOP.
IF lt_small[] IS NOT INITIAL.
"todo lt_small
write:/ 'goto:...................'.
LOOP AT lt_small INTO GS_temp.
write:/ GS_temp-LOW.
ENDLOOP.
ENDIF.
全部代码如下:
FORM frm_send_data .
DATA:
lv_lines TYPE char10,
lv_rfcdest TYPE rfcdest,
ls_data TYPE zspd0010_alv,
ls_bigout TYPE zspd0010_material_rfc,
lt_bigout TYPE TABLE OF zspd0010_material_rfc, "james_lx 2021.12.24
ls_out TYPE zspd0010_material_rfc,
lt_out TYPE TABLE OF zspd0010_material_rfc,
lt_esb_com TYPE zsca_esb_com_tab.
CALL METHOD go_app_log->block_begin( TEXT-002 ).
IF p_batch IS INITIAL.
LOOP AT gt_data INTO ls_data WHERE sel = 'X'.
MOVE-CORRESPONDING ls_data TO ls_bigout.
APPEND ls_bigout TO lt_bigout.
MESSAGE s000 WITH TEXT-003 ls_data-matnr INTO gv_message.
CALL METHOD go_app_log->log_msg_add.
ENDLOOP.
ELSE.
* Background process
LOOP AT gt_data INTO ls_data.
MOVE-CORRESPONDING ls_data TO ls_bigout.
APPEND ls_bigout TO lt_bigout.
MESSAGE s000 WITH TEXT-003 ls_data-matnr INTO gv_message.
CALL METHOD go_app_log->log_msg_add.
ENDLOOP.
ENDIF.
IF sy-subrc = 0.
lv_lines = lines( lt_bigout ).
MESSAGE s057 WITH lv_lines INTO gv_message.
CALL METHOD go_app_log->log_msg_add.
ELSE.
MESSAGE e056.
ENDIF.
"上面原来程序代码 准备好lt_bigout表,和把表的物料号,表总数 记录到日志中
"下面代码,分批发送
DATA lv_this TYPE I VALUE 0.
LOOP AT lt_bigout into ls_bigout.
APPEND ls_bigout TO lt_out.
lv_this = lv_this + 1.
IF ( sy-tabix MOD p_rows ) EQ 0. "满足100行,todo
"生成流水号
CALL METHOD zcl_ca_tools=>set_serno_for_table
CHANGING
ct_data = lt_out.
lv_rfcdest = zcl_ca_tools=>get_rfcdest( ).
CALL METHOD go_app_log->record_esb_com_out
CHANGING
ct_data = lt_esb_com.
"Added by Naitian 20181218: Handle MATNR conversion issue
CALL METHOD zcl_ca_tools=>handle_if_matnr_before_out
CHANGING
ct_data = lt_out.
CALL FUNCTION 'ZSAP_PD_MATERIAL_OUT' DESTINATION lv_rfcdest
TABLES
tt_esb_com = lt_esb_com
et_out = lt_out
EXCEPTIONS
system_failure = 1
communication_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE e038 WITH sy-subrc INTO gv_message.
CALL METHOD go_app_log->log_msg_add.
ELSE.
MESSAGE s000 WITH '已经发送条数:' && lv_this INTO gv_message .
CALL METHOD go_app_log->log_msg_add.
"进度条提示
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
percentage = lv_this / lv_lines * 100 “注意这里sy-tabix早已经改变,所以只有用自己的计数器
text = '已经发送条数:' && lv_this . "提示文本
ENDIF.
REFRESH lt_out.
REFRESH lt_esb_com.
ENDIF.
"完成LOOP前,不够整发的数据会积累到lt_out
ENDLOOP.
"完成LOOP后,把剩下的数据发一次。 感觉函数出现两次,主要是原来代码加日志太多了,只能这样了
IF lt_out IS NOT INITIAL.
lv_lines = lines( lt_bigout ).
"生成流水号
CALL METHOD zcl_ca_tools=>set_serno_for_table
CHANGING
ct_data = lt_out.
lv_rfcdest = zcl_ca_tools=>get_rfcdest( ).
CALL METHOD go_app_log->record_esb_com_out
CHANGING
ct_data = lt_esb_com.
"Added by Naitian 20181218: Handle MATNR conversion issue
CALL METHOD zcl_ca_tools=>handle_if_matnr_before_out
CHANGING
ct_data = lt_out.
CALL FUNCTION 'ZSAP_PD_MATERIAL_OUT' DESTINATION lv_rfcdest
TABLES
tt_esb_com = lt_esb_com
et_out = lt_out
EXCEPTIONS
system_failure = 1
communication_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE e038 WITH sy-subrc INTO gv_message.
CALL METHOD go_app_log->log_msg_add.
ELSE.
MESSAGE s000 WITH '最后发送条数:' lv_lines INTO gv_message.
CALL METHOD go_app_log->log_msg_add.
ENDIF.
REFRESH lt_out.
REFRESH lt_esb_com.
ENDIF.
CALL METHOD go_app_log->block_end( TEXT-002 ).
CALL METHOD go_app_log->log_save.
IF p_batch IS INITIAL.
CALL METHOD go_app_log->log_display('X').
ENDIF.
*->2019/02/18 新增mail发送 - Start
IF p_mail = 'X'.
PERFORM frm_mail_data.
ENDIF.
*->2019/02/18 新增mail发送 - End
ENDFORM.
---------2023.2.23新增一粒---------------
"下面代码,分批发送
DATA:
lt_esb_com TYPE zsca_esb_com_tab,
lt_response TYPE STANDARD TABLE OF zsca_esb_return_common,
lt_out TYPE STANDARD TABLE OF zspp_pr2dfsk,
gv_message TYPE string, "#EC NEEDED
lv_lines TYPE char10,
lv_rfcdest TYPE rfcdest,
ls_rfc TYPE ZSPP_PR2DFSK,
p_rows TYPE i VALUE 200.
DATA lv_indicator_line TYPE I VALUE 0.
lv_lines = lines( gt_rfc ).
LOOP AT gt_rfc into ls_rfc.
APPEND ls_rfc TO lt_out.
lv_indicator_line = lv_indicator_line + 1.
IF ( sy-tabix MOD p_rows ) EQ 0. "满足200行,todo
lv_rfcdest = zcl_ca_tools=>get_rfcdest( ).
CALL FUNCTION 'ZSAP_PP_JKSCM_PR_OUT' DESTINATION lv_rfcdest
TABLES
tt_esb_com = lt_esb_com
et_response = lt_response
et_data = lt_out
EXCEPTIONS
system_failure = 1
communication_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE e038 WITH sy-subrc INTO gv_message.
ELSE.
MESSAGE s000 WITH '已经发送条数:' && lv_indicator_line INTO gv_message .
ENDIF.
"进度条提示
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
percentage = lv_indicator_line / lv_lines * 100 " 注意这里sy-tabix早已经改变,所以只有用自己的计数器
text = '已经发送条数:' && lv_indicator_line . "提示文本
WRITE:/ '已经发送条数:' && lv_indicator_line .
REFRESH: lt_out,lt_out[],lt_esb_com,lt_esb_com[].
ENDIF.
"完成LOOP前,不够整发的数据会积累到lt_out
ENDLOOP.
"完成LOOP后,把剩下的数据发一次。 感觉函数出现两次,主要是原来代码加日志太多了,只能这样了
IF lt_out IS NOT INITIAL.
lv_lines = lines( lt_out ).
lv_rfcdest = zcl_ca_tools=>get_rfcdest( ).
CALL FUNCTION 'ZSAP_PP_JKSCM_PR_OUT' DESTINATION lv_rfcdest
TABLES
tt_esb_com = lt_esb_com
et_response = lt_response
et_data = lt_out
EXCEPTIONS
system_failure = 1
communication_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE e038 WITH sy-subrc INTO gv_message.
ELSE.
MESSAGE s000 WITH '最后发送条数:' lv_lines INTO gv_message.
ENDIF.
WRITE: / '最后发送条数:' && lv_lines.
REFRESH: lt_out,lt_out[],lt_esb_com,lt_esb_com[].
ENDIF.
REFRESH: GT_RFC, GT_RFC[].
clear: lv_id,lv_itemid.