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.