创建生产订单一般很快的,但是由于加了参数版本的传入,导致每次会校验主数据,造成生成订单过慢,因此启用多线程创建订单,每次启用5条线程,做一次回收,回收的原因是线程中的结果还要进行下一步的动作。例如写日志表
RZ12 可查看当前服务器最多开启线程数。
DATA:g_taskname(10) TYPE c, "task name(同时运行的任务名称必须保持唯一)
g_classname TYPE rzlli_apcl, "Server Group Name
g_applserver TYPE rzllitab-applserver,"RFC Serve Group
excp_flag(1) TYPE c. "Number of RESOURCE_FAILUREs
DATA:snd_jobs TYPE i,
rcv_jobs TYPE i,
fcall(1) TYPE c.
CONSTANTS: done(1) TYPE c VALUE 'X'.
DATA:p_wp TYPE c VALUE 5.
FORM get_gname .
" 获取 RFC Serve Group name Start--*
" 一般系统默认g_classname = 'parallel_generators',但为了通用性按照如下方法获取
CALL 'C_SAPGPARAM' "#EC CI_CCALL
ID 'NAME' FIELD 'rdisp/myname'
ID 'VALUE' FIELD g_applserver.
SELECT SINGLE classname
FROM rzllitab
INTO g_classname "Server Group Name
WHERE applserver = g_applserver
AND grouptype = 'S'. "S:服务器组,空:登陆组
" 获取 RFC Serve Group name End--*
ENDFORM.
IF lt_co_orders[] IS NOT INITIAL.
PERFORM get_gname. "服务器名 多线程要指定服务器
SORT lt_co_orders BY material.
t_lines = LINES( lt_co_orders ).
READ TABLE lt_co_orders INTO last_co_order INDEX t_lines.
CLEAR t_lines.
LOOP AT lt_co_orders INTO ls_orderdata.
WRITE sy-tabix TO g_taskname.
APPEND ls_orderdata TO lt_co_tasks.
CLEAR:ls_orderdata.
AT END OF material.
CONDENSE g_taskname.
CONCATENATE 'Ord' g_taskname INTO g_taskname.
CALL FUNCTION 'ZCOMP_BAPI_ORDER_CREATE'STARTING NEW TASK g_taskname
DESTINATION IN GROUP g_classname
PERFORMING frm_order_done ON END OF TASK "子程序
TABLES
orderdatas = lt_co_tasks.
IF sy-subrc = 0.
snd_jobs = snd_jobs + 1.
ENDIF.
FREE lt_co_tasks.
open_task_num = open_task_num + 1. "记录启动的进程数量
IF open_task_num = p_wp. "p_wp = RZ12中的 Max. requests in queue
" 获取并发进程返回的结果
WAIT UNTIL rcv_jobs >= snd_jobs. "多线程收尾工作 判断是否结束 开始做回收结果 直到5次后进行下一步清空
COMMIT WORK.
CLEAR:open_task_num,rcv_jobs,snd_jobs.
ENDIF.
ENDAT.
ENDLOOP.
WAIT UNTIL fcall EQ 'X' AND rcv_jobs = snd_jobs.
CLEAR:open_task_num,rcv_jobs,snd_jobs,fcall.
FUNCTION zcomp_bapi_order_create.
*"----------------------------------------------------------------------
*"*"Local interface:
*" TABLES
*" ORDERDATAS STRUCTURE ZBAPI_PP_SD_ORDER_CREATE OPTIONAL
*"----------------------------------------------------------------------
DATA:orderdata TYPE zbapi_pp_sd_order_create,
ls_orderdata TYPE bapi_pp_order_create,
return TYPE bapiret2,
order_number TYPE aufnr,
order_type TYPE aufart.
LOOP AT orderdatas INTO orderdata.
MOVE-CORRESPONDING orderdata TO ls_orderdata.
CALL FUNCTION 'COXT_BAPI_ORDER_CREATE'
EXPORTING
is_header = ls_orderdata
i_order_category = '10'
iv_reset = 'X'
iv_commit = ' '
IMPORTING
es_return = return
e_order_number = order_number
e_order_type = order_type
EXCEPTIONS
error_message.
IF return-type <> 'E' AND order_number IS NOT INITIAL.
UPDATE zsd02 SET zlpostat = 'X' zlponum = order_number
zlverid = ls_orderdata-prod_version
zlgstrp = ls_orderdata-basic_start_date
zlgltrp = ls_orderdata-basic_end_date
zlxuhao = ls_orderdata-sequence_number
WHERE vbeln = orderdata-vbeln
AND posnr = orderdata-posnr.
UPDATE ztpp009 SET zlponum = order_number
podat = sy-datum pozet = sy-uzeit ponam = sy-uname
WHERE vbeln = orderdata-vbeln
AND posnr = orderdata-posnr.
orderdata-order_number = order_number.
orderdata-message = return-message.
MODIFY orderdatas FROM orderdata TRANSPORTING order_number message.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ENDIF.
ENDLOOP.
* IF SY-SUBRC NE 0.
* IF RETURN IS INITIAL.
* CALL FUNCTION 'BALW_BAPIRETURN_GET2'
* EXPORTING
* TYPE = SY-MSGTY
* CL = SY-MSGID
* NUMBER = SY-MSGNO
* PAR1 = SY-MSGV1
* PAR2 = SY-MSGV2
* PAR3 = SY-MSGV3
* PAR4 = SY-MSGV4
* IMPORTING
* RETURN = RETURN.
* ENDIF.
* ENDIF.
*
* IF NOT RETURN IS INITIAL.
* CALL FUNCTION 'CO_EXT_ORDER_RESET'.
* ENDIF.
ENDFUNCTION.
FORM frm_order_done USING g_taskname.
DATA: lt_order_tasks TYPE TABLE OF zbapi_pp_sd_order_create WITH HEADER LINE.
FREE lt_order_tasks.
RECEIVE RESULTS FROM FUNCTION'ZCOMP_BAPI_ORDER_CREATE'
TABLES
orderdatas = lt_order_tasks.
LOOP AT lt_order_tasks.
LOOP AT it_alv INTO wa_alv
WHERE vbeln = lt_order_tasks-vbeln AND posnr = lt_order_tasks-posnr.
IF lt_order_tasks-order_number IS NOT INITIAL.
wa_alv-msg = '总装订单创建成功!'.
ls_release_orders-order_number = lt_order_tasks-order_number.
ls_release_orders-material = lt_order_tasks-material.
APPEND ls_release_orders TO lt_release_orders.
CLEAR ls_release_orders.
wa_alv-zlponum = lt_order_tasks-order_number.
wa_alv-zlpostat = 'X'.
it_zpp_vininfo-aufnr = lt_order_tasks-order_number.
it_zpp_vininfo-matnr = wa_alv-matnr.
it_zpp_vininfo-kdauf = wa_alv-vbeln.
it_zpp_vininfo-kdpos = wa_alv-posnr.
it_zpp_vininfo-cdate = sy-datum.
it_zpp_vininfo-ctime = sy-uzeit.
it_zpp_vininfo-cname = sy-uname.
it_zpp_vininfo-mdate = sy-datum.
it_zpp_vininfo-mtime = sy-uzeit.
it_zpp_vininfo-mname = sy-uname.
APPEND it_zpp_vininfo.
CLEAR: it_zpp_vininfo.
ELSE.
IF lt_order_tasks-message IS NOT INITIAL.
wa_alv-msg = lt_order_tasks-message.
ELSE.
wa_alv-msg = '生成失败,请检查生产版本是否正确'.
ENDIF.
ENDIF.
MODIFY it_alv FROM wa_alv TRANSPORTING zlponum zlpostat msg.
CLEAR:wa_alv,lt_order_tasks.
EXIT.
ENDLOOP.
ENDLOOP.
"作用 :确认是否完成
READ TABLE lt_order_tasks WITH KEY vbeln = last_co_order-vbeln
posnr = last_co_order-posnr.
IF sy-subrc EQ 0.
fcall = 'X'.
ENDIF.
rcv_jobs = rcv_jobs + 1.
ENDFORM. " FRM_ORDER_DONE
为解决生产订单创建过程因参数验证导致的效率低下问题,本文介绍了一种利用多线程技术加速订单生成的方法。通过限定并行任务数量,确保系统资源合理分配,同时实现订单创建后的后续操作如日志记录等。文中详细展示了ABAP编程环境下,如何设计并实现多线程任务,包括服务器组的选取、任务调度及结果回收流程。
247

被折叠的 条评论
为什么被折叠?



