Do.

[ABAP] 병렬처리 예제 본문

SAP/ABAP

[ABAP] 병렬처리 예제

성공보다는 가치를.. 2023. 1. 3. 13:37
728x90
*&------------------------------------------------------------
*&-- Global Variable
*&------------------------------------------------------------
  "-- Total Process Count
  CONSTANTS: gc_tot_cnt TYPE i VALUE '5'.  "-- 최대 병렬 세션 개수

  "-- 재시도 횟수
  CONSTANTS: gc_retry_comm TYPE i VALUE 5,
             gc_retry_syst TYPE i VALUE 5,
             gc_retry_reso TYPE i VALUE 5.

  "PROCESS COUNT
  DATA: gv_snd_cnt TYPE i, "BOM EXP sent processes
        gv_rcv_cnt TYPE i, "BOM EXP receive processes
        gv_ing_cnt TYPE i. "BOM EXP active processes

  "TASK SUCCESS/FAIL COUNT
  DATA: gv_task_s TYPE i, "BOM Success count
        gv_task_f TYPE i. "BOM Fail Count

  DATA: gv_taskname(20) TYPE n VALUE 0.
*&------------------------------------------------------------
*&-- Logic
*&------------------------------------------------------------
  CLEAR: gv_snd_cnt,
         gv_rcv_cnt,
         gv_ing_cnt.

  DATA:
    lv_sum_t         TYPE i,
    lv_taskcount(20) TYPE n VALUE 0,
    lv_retry_error   TYPE c.

  DATA:
    lv_plnum TYPE plnum,
    lv_psttr TYPE psttr,
    lv_fkday TYPE fkday.

  DATA:
    lv_rtype TYPE char01,
    lv_mesg  TYPE char100.

  CLEAR gv_taskname.

  DO 100 TIMES.

    "-- Process최대치 초과하면 대기(조회화면의 병렬처리 태스크 수보다 크거나 같은 경우)
    IF gv_ing_cnt >= gc_tot_cnt.
      WAIT UNTIL gv_ing_cnt < gc_tot_cnt.
    ENDIF.

    "Total Task Count
    CLEAR lv_retry_error.
    lv_sum_t     = lv_sum_t + 1.
    gv_taskname = lv_taskcount = lv_sum_t.

    PERFORM parallel_planorder_change USING gv_taskname
                                            lv_plnum
                                            lv_psttr
                                            lv_fkday
                                   CHANGING lv_rtype
                                            lv_mesg.
  ENDDO.

  "-- 실행한 Process에 대해 끝날때 까지 대기
  WAIT UNTIL gv_rcv_cnt >= gv_snd_cnt.

*&---------------------------------------------------------------------*
*& Form parallel_planorder_change
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> P_TASKNAME
*&      --> P_PLNUM
*&      --> P_PSTTR
*&      --> P_FKDAY
*&      <-- CV_RTYPE
*&      <-- CV_MESG
*&---------------------------------------------------------------------*
FORM parallel_planorder_change  USING p_taskname
                                      p_plnum
                                      p_psttr
                                      p_fkday
                             CHANGING cv_rtype
                                      cv_mesg.

  DATA:
    lv_retcode      TYPE sysubrc,
    lv_comm_counter TYPE i,
    lv_syst_counter TYPE i,
    lv_reso_counter TYPE i,
    lv_chan         TYPE c.

  DO.
    "FUNCTION CALL
    CALL FUNCTION 'ZPP_CHANGE_PLNORDER_DATE'
      STARTING NEW TASK p_taskname DESTINATION 'NONE'
      PERFORMING plorder_change_return ON END OF TASK
      EXPORTING
        i_plnum               = p_plnum
        i_psttr               = p_psttr
        i_fkday               = p_fkday
        i_test                = abap_true
      EXCEPTIONS
        communication_failure = 1
        system_failure        = 2
        resource_failure      = 3.

    lv_retcode = sy-subrc.

    gv_snd_cnt  = gv_snd_cnt + 1.
    gv_ing_cnt  = gv_ing_cnt + 1.

    IF lv_retcode = 0 .
      cv_rtype = 'S'.
    ELSE.
      "-- 계획오더 &1에 대하여 시작일자(&2) 변경 시 에러가 발생하였습니다.
      MESSAGE s057(zmpp) WITH p_plnum p_psttr INTO cv_mesg.
      cv_rtype = 'E'.
    ENDIF.

    CASE lv_retcode.
      WHEN 0.
        EXIT.
      WHEN 1.
        lv_comm_counter = lv_comm_counter + 1.
      WHEN 2.
        lv_syst_counter = lv_syst_counter + 1.
      WHEN 3.
        lv_reso_counter = lv_reso_counter + 1.
      WHEN OTHERS.
    ENDCASE.

    IF lv_comm_counter > gc_retry_comm OR
       lv_syst_counter > gc_retry_syst OR
       lv_reso_counter > gc_retry_reso.

      EXIT.
    ENDIF.

  ENDDO.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form plorder_change_return
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM plorder_change_return USING p_taskname_receive.

  DATA:
    lv_type TYPE char01,
    lv_mesg TYPE char100.

  RECEIVE RESULTS FROM FUNCTION 'ZPP_CHANGE_PLNORDER_DATE'
   IMPORTING
     ev_rtype         = lv_type
     ev_mesg          = lv_mesg
  EXCEPTIONS
    input_parameter_required = 1
    internal_error           = 2.

  "-- 수신/진행 COUNT
  gv_rcv_cnt = gv_rcv_cnt + 1.
  gv_ing_cnt = gv_ing_cnt - 1.

  "-- 성공/실패 count
  IF lv_type NE 'E'.
    gv_task_s = gv_task_s + 1.
  ELSE.
    gv_task_f = gv_task_f + 1.
  ENDIF.
ENDFORM.
FUNCTION zpp_change_plnorder_date.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(I_PLNUM) TYPE  PLNUM OPTIONAL
*"     VALUE(I_PSTTR) TYPE  PSTTR OPTIONAL
*"     VALUE(I_FKDAY) TYPE  FKDAY OPTIONAL
*"     VALUE(I_FABKL) TYPE  WFCID DEFAULT 'KR'
*"     VALUE(I_TEST) TYPE  CHAR01 OPTIONAL
*"  EXPORTING
*"     VALUE(EV_RTYPE) TYPE  CHAR01
*"     VALUE(EV_MESG) TYPE  CHAR100
*"  EXCEPTIONS
*"      INPUT_PARAMETER_REQUIRED
*"      INTERNAL_ERROR
*"----------------------------------------------------------------------

  DATA:
    lv_order   TYPE bapi_pldord-pldord_num,
    lv_datlo   TYPE sy-datlo,
    ls_return  TYPE bapireturn1,
    ls_header  TYPE bapiplaf_i2,
    ls_headerx TYPE bapiplaf_i2x.

  IF i_plnum IS INITIAL OR
     i_psttr IS INITIAL OR
     i_fkday IS INITIAL.
    RAISE input_parameter_required.
    EXIT.
  ENDIF.

*--- Get Order Finish Day
  CALL FUNCTION 'WDKAL_DATE_ADD_FKDAYS'
    EXPORTING
      i_date  = i_psttr
      i_fkday = i_fkday
      i_fabkl = i_fabkl
    IMPORTING
      e_date  = lv_datlo.

  lv_order = i_plnum.
  ls_header-order_start_date = i_psttr.
  ls_header-order_fin_date   = lv_datlo.
  ls_header-plan_open_date   = i_psttr.

  ls_headerx-order_start_date = abap_true.
  ls_headerx-order_fin_date   = abap_true.
  ls_headerx-plan_open_date   = abap_true.

  "-- Call BAPI
  CALL FUNCTION 'BAPI_PLANNEDORDER_CHANGE'
    EXPORTING
      plannedorder = lv_order
      headerdata   = ls_header
      headerdatax  = ls_headerx
    IMPORTING
      return       = ls_return.

  "-- Commit Work
  IF ls_return-type = 'E'.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    RAISE internal_error.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = abap_true.
  ENDIF.

  "-- Set Return
  ev_rtype = COND #( WHEN ls_return-type IS NOT INITIAL THEN ls_return-type
                     ELSE 'S' ).

  ev_mesg  = ls_return-message.

ENDFUNCTION.

주의) 호출하는 Function은 RFC로 생성해야 함 

 

처리결과(SM50)

728x90

'SAP > ABAP' 카테고리의 다른 글

[ABAP] POPUP_TO_DECIDE  (0) 2024.02.26
[ABAP] REDUCE 문  (0) 2023.04.17
[ABAP] ALV F4에서 필드 여러개 받아야 할 경우  (0) 2022.12.05
[ABAP] Fieldcatlog Style  (0) 2022.12.02
[HANA] For All Entries의 사용  (0) 2022.11.04