abap 多线程-员工花名册

abap 多线程处理花名册
一般HR报表字段都会非常多,可能涉及好几十张表,经常跑到runtime error都跑不出来,现通过多线程的方式把效率优化提升上去

*&---------------------------------------------------------------------*
*& 包含               ZHRI0001F01
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& FORM FRM_GET_DOCUMENT
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM FRM_GET_DOCUMENT .

  DATA:LT_RESULT_TAB     TYPE TABLE OF SWHACTOR,
       LT_HRP9302_PARENT TYPE TABLE OF HRP9302,
       LT_RESULT_OBJEC   TYPE TABLE OF OBJEC,
       LT_RESULT_STRUC   TYPE TABLE OF STRUC.

  DATA:LV_ZZVARIANT TYPE STRING,
       LT_DATA      TYPE ZTHR_PA001,
       LT_HEAD      TYPE STANDARD TABLE OF ZSHR_HEAD,
       LT_DATA_NOID TYPE ZLHR_OM_LIST_NOID,
       LR_PERNR     TYPE STANDARD TABLE OF HRHCP_S_RANGE_PERNR,
       LS_PERNR     LIKE LINE OF LR_PERNR.
  DATA:LV_TABIX TYPE SY-TABIX,
       LV_CALL_TIME TYPE I.

  GV_TASK_ALL = GV_TASK_RUN = 0.

  LV_ZZVARIANT = 'ROOT_' && SY-MANDT.

  SELECT SINGLE *
    INTO @DATA(LS_ZHRT_HARD_CODE)
    FROM ZHRT_HARD_CODE
   WHERE ZZPROGRAM EQ 'ALL'
     AND ZZVARIANT EQ @LV_ZZVARIANT.

  CLEAR:LT_RESULT_TAB ,LT_RESULT_OBJEC ,LT_RESULT_STRUC.
  PERFORM FRM_RH_STRUC_GET TABLES LT_RESULT_TAB LT_RESULT_OBJEC LT_RESULT_STRUC USING 'O' LS_ZHRT_HARD_CODE-ZZLOW 'O-O-S-P' P_BEGDA P_ENDDA.

  DELETE LT_RESULT_OBJEC WHERE otype NE 'P'.
  DELETE LT_RESULT_OBJEC WHERE OBJID NOT IN S_PERNR.

  LV_CALL_TIME = 1.

  LOOP AT LT_RESULT_OBJEC ASSIGNING FIELD-SYMBOL(<FS_RESULT_OBJEC>).

    AT FIRST.
      CLEAR:GV_OPEN_TASK_NUM.
    ENDAT.

    LV_TABIX = LV_TABIX + 1.

    LS_PERNR = VALUE #( SIGN = 'I' OPTION = 'EQ' LOW = <FS_RESULT_OBJEC>-OBJID ).
    APPEND LS_PERNR TO LR_PERNR.

*   异步调用函数
    IF LV_TABIX EQ 100.

      IF GV_OPEN_TASK_NUM = GV_WP.    "P_WP = RZ12中的 MAX. REQUESTS IN QUEUE

*       获取并发进程返回的结果
        WAIT UNTIL GV_RCV_JOBS >= GV_SND_JOBS.
        PERFORM FRM_CALL_FM TABLES LR_PERNR CHANGING LV_CALL_TIME.
        GV_OPEN_TASK_NUM = 1.
        CLEAR:LR_PERNR.
      ELSE.
        PERFORM FRM_CALL_FM TABLES LR_PERNR CHANGING LV_CALL_TIME.
      ENDIF.

      CLEAR:LV_TABIX.
    ENDIF.

    AT LAST.
      IF LV_TABIX NE 100.
        IF GV_OPEN_TASK_NUM = GV_WP.    "P_WP = RZ12中的 MAX. REQUESTS IN QUEUE

*         获取并发进程返回的结果
          WAIT UNTIL GV_RCV_JOBS >= GV_SND_JOBS.
          PERFORM FRM_CALL_FM TABLES LR_PERNR CHANGING LV_CALL_TIME.
          CLEAR:LR_PERNR.
          GV_OPEN_TASK_NUM = 1.
        ELSE.
          PERFORM FRM_CALL_FM TABLES LR_PERNR CHANGING LV_CALL_TIME.
        ENDIF.
      ENDIF.
    ENDAT.

*   异步调用函数
  ENDLOOP.

  WAIT UNTIL GV_TASK_ALL EQ GV_TASK_RUN.
  SORT GT_OUTPUT BY PERNR.
*  PERFORM FRM_SHOW_SALV TABLES GT_OUTPUT.

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_SHOW
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM FRM_SHOW .
  PERFORM FRM_SET_FIELDCAT.
  PERFORM FRM_SET_LAYOUT.
  PERFORM FRM_SHOW_ALV.
ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_SET_FIELDCAT
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM FRM_SET_FIELDCAT .
  CLEAR:GT_ALV_FILEDCAT.
*
  SELECT *
    INTO TABLE @DATA(LT_DD03L)
    FROM DD03L
   WHERE TABNAME    EQ 'ZSHR_PA001'.
  DELETE LT_DD03L WHERE FIELDNAME EQ '.INCLUDE'.


  SELECT *
    INTO TABLE @DATA(LT_DD03T)
    FROM DD03T
   WHERE TABNAME    EQ 'ZSHR_PA001'
     AND DDLANGUAGE EQ @SY-LANGU.

  SORT LT_DD03L BY POSITION.
  SORT LT_DD03T BY FIELDNAME.

  LOOP AT LT_DD03L ASSIGNING FIELD-SYMBOL(<FS_DD03L>).
    READ TABLE LT_DD03T ASSIGNING FIELD-SYMBOL(<FS_DD03T>) WITH KEY FIELDNAME = <FS_DD03L>-FIELDNAME BINARY SEARCH.
    IF SY-SUBRC EQ 0.
      PERFORM FRM_FILL_FIELDCAT USING <FS_DD03L>-FIELDNAME <FS_DD03T>-DDTEXT  <FS_DD03L>-KEYFLAG '' '' '' ''."公司代码
    ENDIF.
  ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_LAYOUT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_SET_LAYOUT .
  GS_REPID = SY-REPID.
  GS_LAYOUT-ZEBRA = 'X'.
  GS_LAYOUT-CWIDTH_OPT = 'X'.
*  GS_LAYOUT-BOX_FNAME = 'SLBOX'.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SHOW_ALV
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_SHOW_ALV .
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program       = gs_repid
      i_save                   = 'A'
      it_fieldcat_lvc          = gt_alv_filedcat[]
      i_grid_title             = CONV lvc_title( |#总条目数:{ lines( GT_OUTPUT ) }| )
*     it_sort_lvc              = gs_sortinfo[]
*     i_grid_settings          = gs_glay
      is_layout_lvc            = gs_layout
*     it_events                = gs_event
      i_callback_pf_status_set = 'PF_STATUS'
      i_callback_user_command  = 'USER_COMMAND'
    TABLES
      t_outtab                 = GT_OUTPUT
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_FILL_FIELDCAT
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*&      --> FIELDNAME
*&      --> COLTEXT
*&      --> KEY
*&      --> REF_TABLE
*&      --> REF_FIELD
*&      --> OUTPUTLEN
*&      --> NO_ZERO
*&---------------------------------------------------------------------*
FORM FRM_FILL_FIELDCAT  USING    P_FIELDNAME
                                 P_COLTEXT
                                 P_KEY
                                 P_REF_TABLE
                                 P_REF_FIELD
                                 P_OUTPUTLEN
                                 P_NO_ZERO.

  DATA:LS_ALV_FILED LIKE GS_ALV_FILED.

    LS_ALV_FILED-FIELDNAME     =  P_FIELDNAME.
    LS_ALV_FILED-COLTEXT       =  P_COLTEXT.
    LS_ALV_FILED-OUTPUTLEN     =  P_OUTPUTLEN.
    LS_ALV_FILED-NO_ZERO       =  P_NO_ZERO.
    LS_ALV_FILED-KEY           =  P_KEY.
    LS_ALV_FILED-REF_TABLE     =  P_REF_TABLE.
    LS_ALV_FILED-REF_FIELD     =  P_REF_FIELD.
    APPEND LS_ALV_FILED TO GT_ALV_FILEDCAT.
ENDFORM.
FORM pf_status USING rt_extab TYPE slis_t_extab.

  DATA FCODE TYPE RSMPE-FUNC.

  SET PF-STATUS 'STD' EXCLUDING RT_EXTAB.

ENDFORM.
FORM USER_COMMAND  USING R_UCOMM TYPE SY-UCOMM
                          RS_SELFIELD TYPE SLIS_SELFIELD.
  DATA:LR_GRID    TYPE REF TO CL_GUI_ALV_GRID.
  DATA:LV_TABIX TYPE SY-TABIX,
       LV_INDICATOR_TEXT TYPE STRING.
* 将界面中的选择数据更新到内表中
*=====GET_GLOBALS_FROM_SLVC_FULLSCR  START==========
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      E_GRID = LR_GRID.
  CALL METHOD LR_GRID->CHECK_CHANGED_DATA.
*=====GET_GLOBALS_FROM_SLVC_FULLSCR  END============
  CASE R_UCOMM.
    WHEN '&IC1'. "ALV双击事件
      PERFORM FRM_DOUBLE_CLICK USING RS_SELFIELD-TABINDEX.
    WHEN 'CLEAR'.
      PERFORM FRM_SET_INDICATOR USING TEXT-T02.
    WHEN 'BACK'.
      CLEAR:GT_OUTPUT,GT_ALV_FILEDCAT.
      LEAVE TO SCREEN 0.
    WHEN OTHERS.

  ENDCASE.
*  RS_SELFIELD-ROW_STABLE = 'X'.
*  RS_SELFIELD-COL_STABLE = 'X'.
  RS_SELFIELD-REFRESH = 'X'.
ENDFORM.                    "USER_COMMAND

*&---------------------------------------------------------------------*
*& Form FRM_INIT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_INIT .
  P_BEGDA = SY-DATUM.
  P_ENDDA = SY-DATUM.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CHECK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_CHECK .

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_SET_INDICATOR
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> TEXT_T01
*&---------------------------------------------------------------------*
FORM FRM_SET_INDICATOR  USING    P_TEXT_T01.
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
  EXPORTING
      text       = P_TEXT_T01.   "text for process
ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_DOUBLE_CLICK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_DOUBLE_CLICK USING P_INDEX.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SHOW_SALV
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LT_BSIS
*&---------------------------------------------------------------------*
FORM FRM_SHOW_SALV  TABLES   P_LT_TABLE.

DATA: LO_ALV TYPE REF TO CL_SALV_TABLE,
      LR_FUNCTIONS TYPE REF TO CL_SALV_FUNCTIONS_LIST.
  CL_SALV_TABLE=>FACTORY( IMPORTING R_SALV_TABLE = LO_ALV
                        CHANGING  T_TABLE   = P_LT_TABLE[] ).



  LR_FUNCTIONS = LO_ALV->GET_FUNCTIONS( ).
  LR_FUNCTIONS->SET_ALL( 'X' ).

  LO_ALV->SET_SCREEN_STATUS(
    PFSTATUS      =  'STANDARD_FULLSCREEN'
    REPORT        =  'SAPLKKBL'
    SET_FUNCTIONS = LO_ALV->C_FUNCTIONS_ALL ).

*  LO_ALV->SET_SCREEN_POPUP(
*    START_COLUMN = 1
*    END_COLUMN   = 100
*    START_LINE   = 1
*    END_LINE     = 20 ).

  LO_ALV->DISPLAY( ).

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SAVE_MESSAGE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_SAVE_MESSAGE .


ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_START_INIT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_START_INIT .

*  CALL FUNCTION 'SPBT_INITIALIZE'
*     EXPORTING
*       group_name                           = GV_CON_SERV_GROUP
**     IMPORTING
**       MAX_PBT_WPS                          =
**       FREE_PBT_WPS                         =
*     EXCEPTIONS
*       invalid_group_name                   = 1
*       internal_error                       = 2
*       pbt_env_already_initialized          = 3
*       currently_no_resources_avail         = 4
*       no_pbt_resources_found               = 5
*       cant_init_different_pbt_groups       = 6
*       OTHERS                               = 7
*            .

*  获取 RFC Serve Group name         Start--*
* 一般系统默认g_classname = 'parallel_generators',但为了通用性按照如下方法获取
  CALL 'C_SAPGPARAM'                                      "#EC CI_CCALL
    ID 'NAME'  FIELD 'rdisp/myname'
    ID 'VALUE' FIELD GV_APPLSERVER.

  SELECT SINGLE CLASSNAME
    FROM RZLLITAB
    INTO GV_CLASSNAME   "SERVER GROUP NAME
    WHERE APPLSERVER = GV_APPLSERVER
    AND GROUPTYPE = 'S'.   "S:服务器组,空:登陆组
*  获取 RFC Serve Group name         End--*


ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_RH_STRUC_GET
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*&      --> LT_RESULT_TAB
*&      --> LT_RESULT_OBJEC
*&      --> LT_RESULT_STRUC
*&      --> <FS_PA0001>_PLANS
*&---------------------------------------------------------------------*
FORM FRM_RH_STRUC_GET  TABLES   P_LT_RESULT_TAB STRUCTURE SWHACTOR
                                P_LT_RESULT_OBJEC STRUCTURE OBJEC
                                P_LT_RESULT_STRUC STRUCTURE STRUC
                       USING   P_OTYPE
                               P_OBJID
                               P_ACT_WEGID
                               P_ACT_BEGDA
                               P_ACT_ENDDA .


  DATA:LV_ACT_OTYPE TYPE OBJEC-OTYPE,
       LV_ACT_OBJID TYPE STRING,
       LV_ACT_WEGID LIKE  GDSTR-WEGID,
       LV_ACT_BEGDA TYPE SY-DATUM,
       LV_ACT_ENDDA TYPE SY-DATUM.

  LV_ACT_OTYPE = P_OTYPE.
  LV_ACT_OBJID = P_OBJID.
  LV_ACT_WEGID = P_ACT_WEGID.
  LV_ACT_BEGDA = P_ACT_BEGDA.
  LV_ACT_ENDDA = P_ACT_ENDDA.

  CALL FUNCTION 'RH_STRUC_GET'
    EXPORTING
      ACT_OTYPE        = LV_ACT_OTYPE
      ACT_OBJID        = LV_ACT_OBJID
      ACT_WEGID        = LV_ACT_WEGID
      ACT_PLVAR        = '01'
      ACT_BEGDA        = LV_ACT_BEGDA
      ACT_ENDDA        = LV_ACT_ENDDA
      ACT_TDEPTH       = 0
      ACT_TFLAG        = 'X'
      ACT_VFLAG        = 'X'
      AUTHORITY_CHECK  = 'X'
      TEXT_BUFFER_FILL = 'X'
*     BUFFER_MODE      = 'X'
    TABLES
      RESULT_TAB       = P_LT_RESULT_TAB
      RESULT_OBJEC     = P_LT_RESULT_OBJEC
      RESULT_STRUC     = P_LT_RESULT_STRUC
    EXCEPTIONS
      NO_PLVAR_FOUND   = 1
      NO_ENTRY_FOUND   = 2
      OTHERS           = 3.

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM FRM_SUBROUTINE_DONE
*&---------------------------------------------------------------------*
*& TEXT
*&---------------------------------------------------------------------*
*& -->  P1        TEXT
*& <--  P2        TEXT
*&---------------------------------------------------------------------*
FORM FRM_SUBROUTINE_DONE USING P_TASKNAME.
  GV_RCV_JOBS = GV_RCV_JOBS + 1.  ""RECEIVING DATA

  DATA: INFO_RFCDEST LIKE RFCSI-RFCDEST.

  DATA EV_RETURN    TYPE STRING.
  DATA ET_HEAD      TYPE STANDARD TABLE OF ZSHR_HEAD.
  DATA ET_DATA_NOID TYPE STANDARD TABLE OF ZSHR_OM_LIST_NOID.
  DATA ET_PERNR     TYPE STANDARD TABLE OF HRHCP_S_RANGE_PERNR.

  DATA:LT_DATA      TYPE TABLE OF ZSHR_PA001,
       LS_MSG       TYPE STRING.

  TRY.
    RECEIVE RESULTS FROM FUNCTION 'ZZF_STAFF_ROSTER'
      IMPORTING
        EV_RETURN          = EV_RETURN
      TABLES
        ET_HEAD            = ET_HEAD
        ET_DATA_NOID       = ET_DATA_NOID
        ET_PERNR           = ET_PERNR
     .

    /UI2/CL_JSON=>DESERIALIZE( EXPORTING JSON = EV_RETURN CHANGING DATA = LT_DATA ).
    LOOP AT LT_DATA ASSIGNING FIELD-SYMBOL(<FS_DATA>).
      MOVE-CORRESPONDING <FS_DATA> TO GS_OUTPUT.
      APPEND GS_OUTPUT TO GT_OUTPUT.
    ENDLOOP.

    GV_TASK_NAME_RUNING = P_TASKNAME.
    GV_TASK_RUN = GV_TASK_RUN + 1.
*    LS_MSG = LS_ROOT->GET_LONGTEXT( ).
  CATCH CX_ROOT INTO DATA(LS_DATA).

  ENDTRY.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CALL_FM
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_CALL_FM TABLES LR_PERNR STRUCTURE HRHCP_S_RANGE_PERNR
                                  CHANGING P_LV_CALL_TIME.

  data:LT_DATA      TYPE ZTHR_PA001,
       LT_HEAD      TYPE STANDARD TABLE OF ZSHR_HEAD,
       LT_DATA_NOID TYPE ZLHR_OM_LIST_NOID.
  DATA:LV_MSG       TYPE STRING.

  CLEAR:GV_TASK_NAME.
  CONCATENATE 'TASK0062' SY-UNAME GV_TASK_NAME INTO GV_TASK_NAME.

  GV_TASK_NAME = GV_TASK_NAME && P_LV_CALL_TIME.

  SORT LR_PERNR BY LOW.

  TRY.
    CALL FUNCTION 'ZZF_STAFF_ROSTER'
        STARTING NEW TASK GV_TASK_NAME
        DESTINATION IN GROUP GV_CLASSNAME
        PERFORMING FRM_SUBROUTINE_DONE ON END OF TASK "子程序
      EXPORTING
        IV_BEGDA           = P_BEGDA
        IV_ENDDA           = P_ENDDA
      TABLES
        ET_HEAD            = LT_HEAD
        ET_DATA_NOID       = LT_DATA_NOID
        ET_PERNR           = LR_PERNR
              .
    IF SY-SUBRC EQ 0.
      GV_SND_JOBS = GV_SND_JOBS + 1.
    ENDIF.
    GV_OPEN_TASK_NUM = GV_OPEN_TASK_NUM + 1.   "记录启动的进程数量

    P_LV_CALL_TIME = P_LV_CALL_TIME + 1.
    GV_TASK_ALL = GV_TASK_ALL + 1.
    CLEAR:LR_PERNR[].
  CATCH CX_ROOT INTO DATA(LS_ROOT) .
    LV_MSG = LS_ROOT->get_longtext( ).
  ENDTRY.

ENDFORM.
posted @ 2022-01-25 13:56  linhuang  阅读(37)  评论(0编辑  收藏  举报  来源