◾ 모듈 : BC
◾ 기능 설명 : CTS 운영 배포 시, 영향이 있을 수 있는 오브젝트 분석 (프로그램, 배치잡, 인터페이스)
🔰 New Syntax 사용◾ 사용 예시 :
1. RFC 연결을 통해 연결된 시스템에 대해서, 배포 시, 영향이 있을 수 있는 오브젝트 식별
2. 배포 예상 시간대(최대 30분) 설정을 기반으로 배치잡 영향도 분석
3. 설정된 인터페이스 네이밍 룰을 기반으로 인터페이스 오브젝트 식별
4. Test Import 기능으로 CTS 배포 테스트 분석
5. /SDF/TRCHECK 를 통한 CTS 분석기능 내재화
6. 추 후, RFC 연결 대상 시스템에서 오브젝트 사용량 기반, 위험 오브젝트 식별 기능 추가 예정 (IMPACT_LEVEL 필드)
***********************************************************************
* Report : ZBC_CTS_IMPACT_ANALYSIS *
* Module/Sub-Module : BC *
* Description : CTS Import Impact Analysis *
***********************************************************************
* MODIFICATION LOG *
* *
* DATE AUTHORS DESCRIPTION *
* ---------- ------------------ ------------------------------------- *
* YHJ Initial Release *
***********************************************************************
REPORT ZBC_CTS_IMPACT_ANALYSIS.
*----------------------------------------------------------------------*
* TYPE-POOLS
*----------------------------------------------------------------------*
TYPE-POOLS: SLIS, ICON.
*----------------------------------------------------------------------*
* TABLES
*----------------------------------------------------------------------*
TABLES: SSCRFIELDS, E070.
*----------------------------------------------------------------------*
* TYPES
*----------------------------------------------------------------------*
TYPES: BEGIN OF TY_OBJECT,
SEL TYPE C,
LINECOLOR(4) TYPE C,
TRKORR TYPE E070-TRKORR,
TRFUNC(4) TYPE C,
PGMID TYPE E071-PGMID,
OBJM_TYPE TYPE E071-OBJECT,
OBJM_DESC TYPE KO100-TEXT,
OBJM_NAME TYPE E071-OBJ_NAME,
OBJC_TYPE TYPE E071-OBJECT,
OBJC_NAME TYPE E071-OBJ_NAME,
DEPTH TYPE I,
PARENT TYPE STRING,
EXISTS TYPE ABAP_BOOL,
INTERFACE TYPE STRING,
BATCH_EXIST TYPE C,
IMPACT_LEVEL TYPE STRING,
IDX_SORT(4) TYPE N,
END OF TY_OBJECT.
TYPES: BEGIN OF TY_TIMELINE,
T1 TYPE C,
T2 TYPE C,
T3 TYPE C,
T4 TYPE C,
T5 TYPE C,
T6 TYPE C,
T7 TYPE C,
T8 TYPE C,
T9 TYPE C,
T10 TYPE C,
T11 TYPE C,
T12 TYPE C,
T13 TYPE C,
T14 TYPE C,
T15 TYPE C,
T16 TYPE C,
T17 TYPE C,
T18 TYPE C,
T19 TYPE C,
T20 TYPE C,
T21 TYPE C,
T22 TYPE C,
T23 TYPE C,
T24 TYPE C,
T25 TYPE C,
T26 TYPE C,
T27 TYPE C,
T28 TYPE C,
T29 TYPE C,
T30 TYPE C,
T31 TYPE C,
END OF TY_TIMELINE.
*----------------------------------------------------------------------*
* DATA
*----------------------------------------------------------------------*
DATA: GT_OBJECT TYPE TABLE OF TY_OBJECT WITH HEADER LINE,
GT_DATA TYPE TABLE OF TY_OBJECT WITH HEADER LINE.
DATA: GT_OBJ_DESC_IN LIKE TABLE OF KO105,
GT_OBJ_DESC_OUT LIKE TABLE OF KO100.
DATA: GV_SORT(4) TYPE N,
GV_RFC_ON TYPE C.
DATA: FUNCTXT TYPE SMP_DYNTXT.
*----------------------------------------------------------------------*
* SELECTION-SCREEN
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE t101.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE t201.
SELECT-OPTIONS: P_TRKORR FOR E070-TRKORR NO INTERVALS.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (12) t301.
SELECTION-SCREEN COMMENT (4) ICON1.
SELECTION-SCREEN END OF LINE.
PARAMETERS: P_RFC TYPE RFCDEST DEFAULT 'PRD'.
PARAMETERS: P_IMP_S TYPE T DEFAULT '210000'.
PARAMETERS: P_IMP_E TYPE T DEFAULT '213000'.
SELECTION-SCREEN SKIP 1.
PARAMETERS: P_CK_INF TYPE C AS CHECKBOX DEFAULT 'X' USER-COMMAND CHK1.
PARAMETERS: P_NAM_IF(20) TYPE C DEFAULT 'Z*_INF_*' MODIF ID INF.
SELECTION-SCREEN END OF BLOCK b2.
PARAMETERS: P_CK_OTX TYPE C AS CHECKBOX DEFAULT ''.
PARAMETERS: P_D_INF TYPE C AS CHECKBOX DEFAULT ''.
PARAMETERS: P_D_BTC TYPE C AS CHECKBOX DEFAULT ''.
SELECTION-SCREEN SKIP 1.
PARAMETERS: P_CK_EXT TYPE C AS CHECKBOX DEFAULT ''.
PARAMETERS: P_CK_BTC TYPE C AS CHECKBOX DEFAULT ''.
SELECTION-SCREEN SKIP 1.
PARAMETERS: P_EX_Y TYPE C AS CHECKBOX DEFAULT 'X'.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN: FUNCTION KEY 1, FUNCTION KEY 2, FUNCTION KEY 3.
AT SELECTION-SCREEN.
PERFORM MENU_SELECT.
AT SELECTION-SCREEN OUTPUT.
PERFORM MODIFY_SCREEN.
PERFORM RFC_CHECK.
*----------------------------------------------------------------------*
* INITIALIZATION *
*----------------------------------------------------------------------*
INITIALIZATION.
MOVE 'CTS Impact Analysis ' TO t101.
MOVE 'RFC Status : ' TO t301.
PERFORM MENU_BAR.
PERFORM RFC_CHECK.
*----------------------------------------------------------------------*
* START-OF-SELECTION.
*----------------------------------------------------------------------*
START-OF-SELECTION.
"### 백그라운드 수행
IF SY-BATCH = 'X'.
"### 프론트 수행
ELSE.
"### 전역 데이터 구조 초기화
REFRESH: GT_OBJECT, GT_DATA, GT_OBJ_DESC_IN, GT_OBJ_DESC_OUT.
CLEAR: GT_OBJECT, GT_DATA.
IF P_CK_EXT = 'X' OR P_CK_BTC = 'X'.
PERFORM RFC_CHECK.
IF GV_RFC_ON IS INITIAL. REJECT. ENDIF.
ENDIF.
PERFORM VALIDATION_CHECK.
"### CTS 내 오브젝트 가져오기
PERFORM GET_CTS_OBJECT.
"### 정렬 레벨을 위한 IDX_SORT 값 초기화
GV_SORT = 1.
"### 재귀호출을 통한 CTS 내 오브젝트 깊이 파악
LOOP AT GT_OBJECT INTO DATA(LS_OBJECT).
PERFORM RECURSE_USED_OBJECT USING LS_OBJECT 0.
GV_SORT += 1.
ENDLOOP.
IF P_CK_OTX = 'X'.
LOOP AT GT_DATA.
READ TABLE GT_OBJ_DESC_OUT WITH KEY OBJECT = GT_DATA-OBJM_TYPE INTO DATA(LS_OBJ_DESC).
GT_DATA-OBJM_DESC = LS_OBJ_DESC-TEXT.
MODIFY GT_DATA.
ENDLOOP.
ENDIF.
"### 연관 인터페이스 영향도 점검
IF P_CK_INF = 'X' AND P_NAM_IF IS NOT INITIAL.
PERFORM CHECK_RELATED_INTERFACE.
ENDIF.
"### RFC 연결시스템에서 오브젝트 존재 여부 점검
IF P_CK_EXT = 'X'.
PERFORM CHECK_OBJECT_EXISTENCE.
ENDIF.
"### RFC 연결시스템에서 PROGRAM 오브젝트의 배치잡 존재 여부 점검
IF P_CK_BTC = 'X'.
PERFORM CHECK_BATCHJOB_EXIST.
ENDIF.
PERFORM REVIEW_DATA.
PERFORM DISPLAY_DATA.
ENDIF.
*----------------------------------------------------------------------*
* END-OF-SELECTION.
*----------------------------------------------------------------------*
END-OF-SELECTION.
*&---------------------------------------------------------------------*
*& ZBC_CTS_IMPACT_ANALYSIS_F01
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form MODIFY_SCREEN
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM MODIFY_SCREEN .
%_P_TRKORR_%_APP_%-TEXT = 'CTS Number'.
%_P_RFC_%_APP_%-TEXT = 'RFC Destination'.
%_P_IMP_S_%_APP_%-TEXT = 'PRD Import Start Time'.
%_P_IMP_E_%_APP_%-TEXT = 'PRD Import End Time'.
%_P_CK_INF_%_APP_%-TEXT = 'Check Interface(Proxy) Object'.
%_P_NAM_IF_%_APP_%-TEXT = 'Interface Naming Rule'.
%_P_CK_OTX_%_APP_%-TEXT = ' Display Object Description'.
%_P_D_INF_%_APP_%-TEXT = ' Display Only Interface Object'.
%_P_D_BTC_%_APP_%-TEXT = ' Display Only Batchjob Object'.
%_P_CK_EXT_%_APP_%-TEXT = ' (RFC) Excute Exist Object Check'.
%_P_CK_BTC_%_APP_%-TEXT = ' (RFC) Excute Batchjob Check'.
%_P_EX_Y_%_APP_%-TEXT = ' Excluding Y*, LY* Object'.
LOOP AT SCREEN.
IF GV_RFC_ON IS INITIAL.
IF SCREEN-NAME = 'P_CK_EXT' OR SCREEN-NAME = 'P_CK_BTC'.
SCREEN-INPUT = 0.
ENDIF.
ELSE.
IF SCREEN-NAME = 'P_CK_EXT' OR SCREEN-NAME = 'P_CK_BTC'.
SCREEN-INPUT = 1.
ENDIF.
ENDIF.
IF P_CK_INF = 'X'.
IF SCREEN-GROUP1 = 'INF'.
SCREEN-ACTIVE = 1.
ENDIF.
IF SCREEN-NAME = 'P_D_INF'.
SCREEN-INPUT = 1.
ENDIF.
ELSE.
IF SCREEN-GROUP1 = 'INF'.
SCREEN-ACTIVE = 0.
ENDIF.
IF SCREEN-NAME = 'P_D_INF'.
SCREEN-INPUT = 0.
ENDIF.
ENDIF.
MODIFY SCREEN.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form MENU_BAR
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM MENU_BAR .
FUNCTXT-ICON_ID = ICON_BUSINESS_AREA.
FUNCTXT-QUICKINFO = 'ANALYSIS_BATCH_SCHEDULE'.
FUNCTXT-ICON_TEXT = 'Batch Schedule'.
SSCRFIELDS-FUNCTXT_01 = FUNCTXT.
FUNCTXT-ICON_ID = ICON_IMPORT_ALL_REQUESTS.
FUNCTXT-QUICKINFO = 'TEST_Import'.
FUNCTXT-ICON_TEXT = 'Test Import'.
SSCRFIELDS-FUNCTXT_02 = FUNCTXT.
FUNCTXT-ICON_ID = ICON_WORKING_PLAN.
FUNCTXT-QUICKINFO = '/SDF/TRCHECK'.
FUNCTXT-ICON_TEXT = '/SDF/TRCHECK'.
SSCRFIELDS-FUNCTXT_03 = FUNCTXT.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form MENU_SELECT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM MENU_SELECT .
CASE SY-UCOMM.
"### 1. ANALYSIS_BATCH_SCHEDULE
"### 영향받는 배치잡 스케쥴링 확인
WHEN 'FC01'.
"### 배치잡 영향도 점검은 RFC 체크가 필수
PERFORM RFC_CHECK.
IF GV_RFC_ON IS INITIAL. REJECT. ENDIF.
PERFORM VALIDATION_CHECK .
"### 배치잡 영향도 점검은 배포 예상 시간대가 필수
IF ( P_IMP_S IS INITIAL ) OR ( P_IMP_E IS INITIAL ).
IF ( P_IMP_S IS INITIAL ) AND ( P_IMP_S <> '000000' ).
MESSAGE |배치잡 영향도 점검에는 배포 예상 시간대 입력이 필수 입니다.| TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
ENDIF.
IF GV_RFC_ON = 'X'.
"### 배치잡 영향도 체크 전, 참조 오브젝트 확인 먼저 수행
PERFORM RUN_BASIC_IMPACT_CHECK.
"### 배치잡 영향도 있는 오브젝트 선별
PERFORM CHECK_BATCHJOB_EXIST.
"### GT_DATA 에서 배치잡 영향도 없는 엔트리 삭제
DELETE GT_DATA WHERE BATCH_EXIST = SPACE.
"### 영향도 있는 배치잡에 대한 타임라인표 작성
PERFORM ANALYSIS_BATCH_SCHEDULE.
ENDIF.
"### 2. TEST Import
"### 테스트 임포트
WHEN 'FC02'.
* PERFORM RFC_CHECK.
PERFORM EXCUTE_TEST_IMPORT.
"### 3. /SDF/TRCHECK
WHEN 'FC03'.
PERFORM EXCUTE_SDF_TRCHECK.
ENDCASE.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form RFC_CHECK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM RFC_CHECK .
CLEAR: GV_RFC_ON.
"### RFC 를 통한 점검 기능 사용 시, 해당 RFC 목적지가 유효한지 확인
CALL FUNCTION 'RFC_PING'
DESTINATION P_RFC
EXCEPTIONS
SYSTEM_FAILURE = 1
COMMUNICATION_FAILURE = 2.
"### 유효하면, 그린라이트
IF SY-SUBRC = 0.
WRITE ICON_LED_GREEN AS ICON TO ICON1.
GV_RFC_ON = 'X'.
PERFORM MODIFY_SCREEN.
"### 유효하지 않다면, 레드라이트
ELSE.
WRITE ICON_LED_RED AS ICON TO ICON1.
CLEAR: GV_RFC_ON.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form VALIDATION_CHECK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM VALIDATION_CHECK .
"### CTS 번호는 필수값
IF P_TRKORR IS INITIAL.
MESSAGE |CTS 번호는 필수값 입니다.| TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
"### 배포 예상 시간대 유효성 체크
"### 배포 예상 시작 시간은 종료 시간보다 작을 수 없음.
"### 또한 배포 예상 시간은 자정(00:00:00) 을 통과할 수 없음
IF P_IMP_S > P_IMP_E.
MESSAGE |배포 예상 시작시간은 종료시간보다 작을 수 없습니다.| TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
"### 배포 예상 종료시간이 없을 경우, 시작시간과 동일하게 설정
IF P_IMP_E IS INITIAL.
P_IMP_E = P_IMP_S.
ENDIF.
"### 배포 예상 시간대는 최대 30분 제한.
IF ( P_IMP_E - P_IMP_S ) > 1800.
MESSAGE |배포 예상 시간대는 최대 30분입니다.| TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
"### 배포 예상 종료 시간은 자정이 될수 없음.
IF P_IMP_E >= 235959.
MESSAGE |배포 예상 종료시간은 자정(00:00:00) 이 될 수 없습니다.| TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_CTS_OBJECTS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM GET_CTS_OBJECT.
WITH
+LT_E070 AS (
SELECT TRKORR, TRFUNCTION
FROM E070 ),
+LT_E071 AS (
SELECT *
FROM E071
WHERE TRKORR IN @P_TRKORR
AND PGMID <> 'CORR' )
SELECT
A~TRKORR,
A~TRFUNCTION,
B~PGMID,
B~OBJECT,
B~OBJ_NAME
FROM +LT_E070 AS A
INNER JOIN +LT_E071 AS B
ON A~TRKORR = B~TRKORR
INTO TABLE @DATA(LT_E000).
LOOP AT LT_E000 INTO DATA(LS_E000).
GT_OBJECT-TRKORR = LS_E000-TRKORR.
IF LS_E000-TRFUNCTION = 'K'.
GT_OBJECT-TRFUNC = 'Work'.
ELSEIF LS_E000-TRFUNCTION = 'W'.
GT_OBJECT-TRFUNC = 'Cust'.
ELSE.
GT_OBJECT-TRFUNC = LS_E000-TRFUNCTION.
ENDIF.
GT_OBJECT-PGMID = LS_E000-PGMID.
GT_OBJECT-OBJM_TYPE = LS_E000-OBJECT.
GT_OBJECT-OBJM_NAME = LS_E000-OBJ_NAME.
GT_OBJECT-OBJC_NAME = LS_E000-OBJ_NAME.
GT_OBJECT-DEPTH = 0.
GT_OBJECT-PARENT = '-'.
APPEND GT_OBJECT. CLEAR GT_OBJECT.
ENDLOOP.
"### 오브젝트 텍스트 데이터 가져오기
IF P_CK_OTX = 'X'.
CALL FUNCTION 'TRINT_OBJECT_TABLE'
EXPORTING
IV_COMPLETE = 'X'
TABLES
TT_TYPES_IN = GT_OBJ_DESC_IN
TT_TYPES_OUT = GT_OBJ_DESC_OUT.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form RECURSE_USED_OBJECT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> LS_OBJECT
*& --> P_0
*&---------------------------------------------------------------------*
FORM RECURSE_USED_OBJECT USING P_LS_OBJECT TYPE TY_OBJECT
P_DEPTH.
DATA: LT_FINDSTRING TYPE STANDARD TABLE OF STRING WITH HEADER LINE,
LT_FOUND TYPE STANDARD TABLE OF RSFINDLST WITH HEADER LINE,
LT_SCOPE TYPE STANDARD TABLE OF STRING WITH HEADER LINE,
LV_HITS TYPE SYTABIX.
DATA: LT_EUOBJ_CLS LIKE TABLE OF EUOBJEDIT WITH HEADER LINE.
DATA: TEMP_OBJECT TYPE TABLE OF TY_OBJECT WITH HEADER LINE,
CLEAR_LINE TYPE TY_OBJECT.
DATA: LV_OBJ_CLS LIKE EUOBJ-ID.
DATA: DEPTH_COUNT TYPE I.
CLEAR: LT_FINDSTRING, LT_FOUND.
APPEND P_LS_OBJECT-OBJC_NAME TO LT_FINDSTRING.
"### 오브젝트 클래스 마스터 테이블 / LT_FOUND 오브젝트 구분에 사용
SELECT * INTO CORRESPONDING FIELDS OF TABLE LT_EUOBJ_CLS
FROM EUOBJEDIT.
"### 최상위 오브젝트는 따로 묶고, 정렬 전용 필드값 IDX_SORT 에 정렬 순서값 입력
IF P_LS_OBJECT-DEPTH = 0.
MOVE-CORRESPONDING P_LS_OBJECT TO GT_DATA.
GT_DATA-OBJC_TYPE = P_LS_OBJECT-OBJM_TYPE.
GT_DATA-IDX_SORT = GV_SORT.
APPEND GT_DATA.
ENDIF.
"### PGMID 중 CORR 을 제외한 R3TR, LIMU 대상으로만 깊이 탐색
IF P_LS_OBJECT-PGMID = 'R3TR' OR P_LS_OBJECT-PGMID = 'LIMU'.
MOVE P_LS_OBJECT-OBJC_TYPE TO LV_OBJ_CLS.
IF LV_OBJ_CLS IS INITIAL.
MOVE P_LS_OBJECT-OBJM_TYPE TO LV_OBJ_CLS.
ENDIF.
"### 오브젝트 의존성 검색
CALL FUNCTION 'RS_EU_CROSSREF'
EXPORTING
I_FIND_OBJ_CLS = LV_OBJ_CLS
NO_DIALOG = 'X'
IMPORTING
O_HITS = LV_HITS
TABLES
I_FINDSTRINGS = LT_FINDSTRING
O_FOUNDS = LT_FOUND
I_SCOPE_OBJECT_CLS = LT_SCOPE
EXCEPTIONS
not_executed = 1
not_found = 2
illegal_object = 3
no_cross_for_this_object = 4
batch = 5
batchjob_error = 6
wrong_type = 7
object_not_exist = 8
OTHERS = 9.
"### 검색된 의존성 오브젝트가 있다면(LT_FOUND), CHILD OBJECT 데이터 입력
IF ( SY-SUBRC = 0 AND LV_HITS > 0 ).
LOOP AT LT_FOUND.
"### Y오브젝트(테스트, 임시) 제외 옵션 선택시, Y, LY 오브젝트 제외
"### LT_FOUND-OBJECT 는 오브젝트 이름인 OBJC_NAME 과 동일
"### LT_FOUND-OBJECT_CLS 는 오브젝트 타입인 OBJC_TYPE 과 동일
IF ( LT_FOUND-OBJECT CP 'Y*' ) OR ( LT_FOUND-OBJECT CP 'LY*' ).
IF P_EX_Y = 'X'.
CONTINUE.
ENDIF.
ENDIF.
CLEAR: TEMP_OBJECT.
READ TABLE LT_EUOBJ_CLS WITH KEY TYPE = LT_FOUND-OBJECT_CLS.
"### 펑션모듈(FUNC) 는 하드코딩
IF LT_EUOBJ_CLS-TADIR = 'FUGR' AND LT_EUOBJ_CLS-E071 = 'FUNC'.
LT_EUOBJ_CLS-TADIR = 'FUNC'.
ENDIF.
* READ TABLE GT_OBJ_DESC_OUT WITH KEY OBJECT = P_LS_OBJECT-OBJM_TYPE INTO DATA(LS_OBJ_DESC).
TEMP_OBJECT-TRKORR = P_LS_OBJECT-TRKORR.
TEMP_OBJECT-TRFUNC = P_LS_OBJECT-TRFUNC.
TEMP_OBJECT-PGMID = P_LS_OBJECT-PGMID.
* TEMP_OBJECT-OBJM_DESC = LS_OBJ_DESC-TEXT.
TEMP_OBJECT-OBJM_DESC = LS_OBJ_DESC-TEXT.
TEMP_OBJECT-OBJM_NAME = P_LS_OBJECT-OBJM_NAME.
TEMP_OBJECT-OBJC_TYPE = LT_EUOBJ_CLS-TADIR.
"### 인클루드 오브젝트(ENCL_OBJEC) 가 있다면, 인클루드 오브젝트 이름 선택
"### => 클래스 계열에서 postfix 없는 이름을 사용해야 하기 때문에
IF ( LT_FOUND-ENCL_OBJEC IS INITIAL ).
TEMP_OBJECT-OBJC_NAME = LT_FOUND-OBJECT.
ELSEIF ( LT_FOUND-ENCL_OBJEC IS NOT INITIAL ). "OR TEMP_OBJECT-OBJECT = 'TABL'.
IF TEMP_OBJECT-OBJC_TYPE = 'FUNC'.
TEMP_OBJECT-OBJC_NAME = LT_FOUND-OBJECT.
ELSE.
TEMP_OBJECT-OBJC_NAME = LT_FOUND-ENCL_OBJEC.
ENDIF.
ENDIF.
TEMP_OBJECT-DEPTH = P_DEPTH + 1.
TEMP_OBJECT-PARENT = P_LS_OBJECT-OBJC_NAME.
APPEND TEMP_OBJECT.
"### 중복 오브젝트 삽입을 방지하기 위해, 기존 인터널 테이블에 데이터 체크
READ TABLE GT_DATA WITH KEY TRKORR = TEMP_OBJECT-TRKORR
PGMID = TEMP_OBJECT-PGMID
OBJM_TYPE = TEMP_OBJECT-OBJM_TYPE
OBJM_NAME = TEMP_OBJECT-OBJM_NAME
DEPTH = ( TEMP_OBJECT-DEPTH - 1 )
OBJC_TYPE = TEMP_OBJECT-OBJC_TYPE
OBJC_NAME = TEMP_OBJECT-OBJC_NAME TRANSPORTING NO FIELDS.
IF SY-SUBRC <> 0.
"### 정렬 키값 입력
TEMP_OBJECT-IDX_SORT = GV_SORT.
APPEND TEMP_OBJECT TO GT_DATA.
"### 오브젝트 타입이 다음과 같다면, 더이상 하위 오브젝트를 탐색하지 않음.
"### - PROG : 프로그램 => 하위 오브젝트가 TRAN(티코드) 만 있는 경우가 대부분임.
"### - TRAN : 티코드 => 하위 오브젝트가 SHI3(영역 메뉴) 만 있는 경우가 대부분임.
"### - ENHO : 인핸스먼트 => 하위 오브젝트를 찾을 수 있는 방법이 없음.
IF TEMP_OBJECT-OBJC_TYPE = 'PROG' OR TEMP_OBJECT-OBJC_TYPE = 'TRAN' OR TEMP_OBJECT-OBJC_TYPE = 'ENHO'.
CONTINUE.
ENDIF.
"### 하위 오브젝트 의존성 재탐색을 위해, DEPTH 를 1 증가시키고, 재귀 호출
DEPTH_COUNT = P_DEPTH + 1.
PERFORM RECURSE_USED_OBJECT USING TEMP_OBJECT DEPTH_COUNT.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CHECK_RELATED_INTERFACE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM CHECK_RELATED_INTERFACE .
LOOP AT GT_DATA.
"### 영향받는 인터페이스 체크
IF GT_DATA-OBJC_TYPE = 'CLAS' AND GT_DATA-OBJC_NAME CP P_NAM_IF.
GT_DATA-INTERFACE = 'X'.
MODIFY GT_DATA.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CHECK_OBJECT_EXISTENCE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM CHECK_OBJECT_EXISTENCE .
DATA: CHECK_SQL TYPE STRING.
DATA: RFC_OPT LIKE TABLE OF RFC_DB_OPT WITH HEADER LINE,
RFC_FLD LIKE TABLE OF RFC_DB_FLD WITH HEADER LINE,
RFC_DATA LIKE TABLE OF TAB512 WITH HEADER LINE.
DATA: LV_QTABLE LIKE DD02L-TABNAME VALUE 'TADIR'.
DATA: R3TR_OBJTYPE TYPE TROBJTYPE,
R3TR_OBJNAME TYPE TROBJ_NAME.
DATA: LV_SAPL_TEMP LIKE E071-OBJ_NAME.
LOOP AT GT_DATA.
CLEAR: RFC_OPT, RFC_FLD, RFC_DATA, R3TR_OBJTYPE, R3TR_OBJNAME.
REFRESH: RFC_OPT, RFC_FLD, RFC_DATA.
* "### LIMU 오브젝트일 경우, R3TR 오브젝트로 변환
* IF GT_DATA-PGMID = 'LIMU'.
*
* CALL FUNCTION 'GET_R3TR_OBJECT_FROM_LIMU_OBJ'
* EXPORTING
* P_LIMU_OBJTYPE = GT_DATA-OBJ_CHLD
* P_LIMU_OBJNAME = GT_DATA-OBJ_NAME
* IMPORTING
* P_R3TR_OBJTYPE = R3TR_OBJTYPE
* P_R3TR_OBJNAME = R3TR_OBJNAME.
*
** RFC_OPT-TEXT = |OBJECT = '{ R3TR_OBJTYPE }' AND OBJ_NAME = '{ R3TR_OBJNAME }'|.
* IF R3TR_OBJNAME CP 'SAPL*'.
* SHIFT R3TR_OBJNAME LEFT DELETING LEADING 'SAPL'.
* ELSEIF R3TR_OBJNAME CP 'SAPL*'.
*
* ENDIF.
*
* RFC_OPT-TEXT = |OBJ_NAME = '{ R3TR_OBJNAME }'|.
*
* ELSE.
*
** RFC_OPT-TEXT = |OBJECT = '{ GT_DATA-OBJ_CHLD }' AND OBJ_NAME = '{ GT_DATA-OBJ_NAME }'|.
*
* IF GT_DATA-OBJ_NAME CP 'SAPL*'.
* SHIFT GT_DATA-OBJ_NAME LEFT DELETING LEADING 'SAPL'.
* ENDIF.
*
* RFC_OPT-TEXT = |OBJ_NAME = '{ GT_DATA-OBJ_NAME }'|.
*
* ENDIF.
"### 오브젝트 체크 예외케이스 정리
"### 1. 펑션 그룹 오브젝트
IF GT_DATA-OBJC_NAME CP 'LZ*'.
RFC_OPT-TEXT = |INCLUDE = '{ GT_DATA-OBJC_NAME }'|.
APPEND RFC_OPT.
LV_QTABLE = 'D010INC'.
RFC_FLD-FIELDNAME = 'MASTER'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'INCLUDE'. APPEND RFC_FLD.
"### 2. 권한 그룹 오브젝트
ELSEIF GT_DATA-OBJC_TYPE = 'ACGR'.
RFC_OPT-TEXT = |AGR_NAME = '{ GT_DATA-OBJC_NAME }'|.
APPEND RFC_OPT.
LV_QTABLE = 'AGR_DEFINE'.
RFC_FLD-FIELDNAME = 'AGR_NAME'. APPEND RFC_FLD.
"### 3. 펑션 모듈 오브젝트
ELSEIF GT_DATA-OBJC_TYPE = 'FUNC'.
RFC_OPT-TEXT = |FUNCNAME = '{ GT_DATA-OBJC_NAME }'|.
APPEND RFC_OPT.
LV_QTABLE = 'TFDIR'.
RFC_FLD-FIELDNAME = 'FUNCNAME'. APPEND RFC_FLD.
"### 4. 메소드 오브젝트
ELSEIF GT_DATA-OBJC_TYPE = 'METH'.
RFC_OPT-TEXT = |CLASSNAME = '{ GT_DATA-OBJC_NAME+0(30) }' AND METHODNAME = '{ GT_DATA-OBJC_NAME+30(30) }'|.
APPEND RFC_OPT.
LV_QTABLE = 'TMDIR'.
RFC_FLD-FIELDNAME = 'CLASSNAME'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'METHODNAME'. APPEND RFC_FLD.
"### 5. 프로그램 스크린 오브젝트
ELSEIF GT_DATA-OBJC_TYPE = 'DYNP'.
RFC_OPT-TEXT = |PROG = '{ GT_DATA-OBJC_NAME+0(40) }' AND DNUM = '{ GT_DATA-OBJC_NAME+40(40) }'|.
APPEND RFC_OPT.
LV_QTABLE = 'D020S'.
RFC_FLD-FIELDNAME = 'PROG'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'DNUM'. APPEND RFC_FLD.
"### - 그 외, 예외 오브젝트를 제외하고는 TADIR 에서 검색
ELSE.
RFC_OPT-TEXT = |OBJ_NAME = '{ GT_DATA-OBJC_NAME }'|.
IF GT_DATA-OBJC_NAME CP 'SAPL*'.
LV_SAPL_TEMP = GT_DATA-OBJC_NAME.
SHIFT LV_SAPL_TEMP LEFT DELETING LEADING 'SAPL'.
RFC_OPT-TEXT = |OBJ_NAME = '{ LV_SAPL_TEMP }'|.
ENDIF.
APPEND RFC_OPT.
LV_QTABLE = 'TADIR'.
RFC_FLD-FIELDNAME = 'PGMID'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'OBJECT'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'OBJ_NAME'. APPEND RFC_FLD.
ENDIF.
"### 비교 시스템(P_RFC) TADIR 테이블을 검색하여, 해당 오브젝트가 존재하는지 체크
CALL FUNCTION 'RFC_READ_TABLE'
DESTINATION P_RFC
EXPORTING
QUERY_TABLE = LV_QTABLE
TABLES
OPTIONS = RFC_OPT
FIELDS = RFC_FLD
DATA = RFC_DATA
EXCEPTIONS
OTHERS = 1.
IF SY-SUBRC = 0.
IF RFC_DATA[] IS NOT INITIAL.
GT_DATA-EXISTS = 'X'.
MODIFY GT_DATA.
ENDIF.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CHECK_BATCHJOB_EXIST
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM CHECK_BATCHJOB_EXIST .
DATA: RFC_OPT LIKE TABLE OF RFC_DB_OPT WITH HEADER LINE,
RFC_FLD LIKE TABLE OF RFC_DB_FLD WITH HEADER LINE,
RFC_DATA LIKE TABLE OF TAB512 WITH HEADER LINE.
DATA: LT_BATCH TYPE TABLE OF V_OP WITH HEADER LINE.
* RFC_OPT-TEXT = |PERIODIC = 'X' AND STATUS = 'S' AND SDLSTRDT <> ''|.
RFC_OPT-TEXT = |PERIODIC = 'X' AND STATUS = 'S'|.
APPEND RFC_OPT.
RFC_FLD-FIELDNAME = 'JOBNAME'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'JOBCOUNT'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'PROGNAME'. APPEND RFC_FLD.
"### 비교 시스템(P_RFC) 의 V_OP 뷰테이블을 확인
CALL FUNCTION 'RFC_READ_TABLE'
DESTINATION P_RFC
EXPORTING
QUERY_TABLE = 'V_OP'
DELIMITER = '|'
TABLES
OPTIONS = RFC_OPT
FIELDS = RFC_FLD
DATA = RFC_DATA
EXCEPTIONS
OTHERS = 1.
LOOP AT RFC_DATA.
SPLIT RFC_DATA-WA AT '|' INTO TABLE DATA(LT_VOP).
LT_BATCH-JOBNAME = LT_VOP[ 1 ].
LT_BATCH-JOBCOUNT = LT_VOP[ 2 ].
LT_BATCH-PROGNAME = LT_VOP[ 3 ].
APPEND LT_BATCH. CLEAR LT_BATCH.
ENDLOOP.
"### V_OP 테이블에서 배치잡 사용 여부 체크
LOOP AT GT_DATA WHERE ( OBJC_TYPE = 'PROG' OR OBJC_TYPE = 'REPS' ).
"### 배치잡 리스트 중, 오브젝트가 검색된다면, 배치잡에 사용되므로, BATCH_EXIST = 'X' 플래그
IF LINE_EXISTS( LT_BATCH[ PROGNAME = GT_DATA-OBJC_NAME ] ).
GT_DATA-BATCH_EXIST = 'X'.
MODIFY GT_DATA.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form REVIEW_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM REVIEW_DATA .
IF P_D_INF = 'X'.
DELETE GT_DATA WHERE INTERFACE = SPACE.
ENDIF.
IF P_D_BTC = 'X'.
DELETE GT_DATA WHERE BATCH_EXIST = SPACE.
ENDIF.
SORT GT_DATA BY TRKORR OBJM_NAME DEPTH PARENT.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form DISPLAY_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM DISPLAY_DATA .
DATA: L_POS TYPE I VALUE 0.
DATA: TEMP_SORT TYPE SLIS_T_SORTINFO_ALV WITH HEADER LINE.
DATA: LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
LT_LAYOUT TYPE SLIS_LAYOUT_ALV.
"### Build Field Catalog
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TRKORR'.
LT_FIELDCAT-SELTEXT_M = 'CTS Number'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'PGMID'.
LT_FIELDCAT-SELTEXT_M = 'PGMID'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 6.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJM_TYPE'.
LT_FIELDCAT-SELTEXT_M = 'Object Type'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 6.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
IF P_CK_OTX = 'X'.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJM_DESC'.
LT_FIELDCAT-SELTEXT_M = 'Object Text'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
ENDIF.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJM_NAME'.
LT_FIELDCAT-SELTEXT_M = 'Object Name'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'DEPTH'.
LT_FIELDCAT-SELTEXT_M = 'Depth'.
LT_FIELDCAT-OUTPUTLEN = 5.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'PARENT'.
LT_FIELDCAT-SELTEXT_M = 'Parent'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJC_TYPE'.
LT_FIELDCAT-SELTEXT_M = 'Child Obj. Type'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJC_NAME'.
LT_FIELDCAT-SELTEXT_M = 'Child Obj. Name'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
IF P_CK_EXT = 'X'.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'EXISTS'.
LT_FIELDCAT-SELTEXT_M = 'Exists'.
LT_FIELDCAT-OUTPUTLEN = 5.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
ENDIF.
IF P_CK_INF = 'X'.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'INTERFACE'.
LT_FIELDCAT-SELTEXT_M = 'Interface'.
LT_FIELDCAT-OUTPUTLEN = 10.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
ENDIF.
IF P_CK_BTC = 'X'.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'BATCH_EXIST'.
LT_FIELDCAT-SELTEXT_M = 'Batch'.
LT_FIELDCAT-OUTPUTLEN = 4.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
ENDIF.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'IMPACT_LEVEL'.
LT_FIELDCAT-SELTEXT_M = 'IMPACT'.
LT_FIELDCAT-OUTPUTLEN = 8.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
"### Build Sort Catalog
TEMP_SORT-FIELDNAME = 'TRKORR'.
TEMP_SORT-TABNAME = 'GT_DATA'.
TEMP_SORT-UP = 'X'.
* TEMP_SORT-EXPA = 'X'.
APPEND TEMP_SORT. CLEAR: TEMP_SORT.
"### ALV Layout 설정
LT_LAYOUT-BOX_FIELDNAME = 'SEL'.
LT_LAYOUT-INFO_FIELDNAME = 'LINECOLOR'.
LT_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
* LT_LAYOUT-ZEBRA = 'X'.
LT_LAYOUT-BOX_TABNAME = 'GT_DATA'.
"### 위에 설정된 Field Catalog 와 Layout 을 사용하여 ALV 리스트 출력 펑션 콜
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
* I_CALLBACK_USER_COMMAND = 'USER_COMMAND_DISP'
* I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
* I_GRID_TITLE = GV_ALV_HEADER
I_CALLBACK_TOP_OF_PAGE = 'TOP-OF-PAGE'
* I_HTML_HEIGHT_TOP = 10
* IT_EVENTS = GT_EVENT[]
IT_SORT = TEMP_SORT[]
IT_FIELDCAT = LT_FIELDCAT[]
IS_LAYOUT = LT_LAYOUT
* I_SAVE = 'A'
TABLES
T_OUTTAB = GT_DATA
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
ENDFORM.
*-------------------------------------------------------------------*
* Form TOP-OF-PAGE *
*-------------------------------------------------------------------*
* ALV Report Header *
*-------------------------------------------------------------------*
FORM TOP-OF-PAGE.
*ALV Header declarations
DATA: LT_HEADER TYPE SLIS_T_LISTHEADER,
LS_HEADER TYPE SLIS_LISTHEADER.
LS_HEADER-TYP = 'S'.
LS_HEADER-INFO = |■ Total CTS Count : { LINES( P_TRKORR ) }|.
APPEND LS_HEADER TO LT_HEADER.
CLEAR: LS_HEADER.
LOOP AT P_TRKORR.
LS_HEADER-TYP = 'S'.
LS_HEADER-INFO = | - { P_TRKORR-LOW }|.
APPEND LS_HEADER TO LT_HEADER.
CLEAR: LS_HEADER.
ENDLOOP.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
IT_LIST_COMMENTARY = LT_HEADER
I_ALV_FORM = 'X'.
ENDFORM. "TOP-OF-PAGE.
*&---------------------------------------------------------------------*
*& Form RUN_BASIC_IMPACT_CHECK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM RUN_BASIC_IMPACT_CHECK .
"### 전역 데이터 구조 초기화
REFRESH: GT_OBJECT, GT_DATA, GT_OBJ_DESC_IN, GT_OBJ_DESC_OUT.
CLEAR: GT_OBJECT, GT_DATA.
PERFORM VALIDATION_CHECK.
"### CTS 내 오브젝트 가져오기
PERFORM GET_CTS_OBJECT.
"### 정렬 레벨을 위한 IDX_SORT 값 초기화
GV_SORT = 1.
"### 재귀호출을 통한 CTS 내 오브젝트 깊이 파악
LOOP AT GT_OBJECT INTO DATA(LS_OBJECT).
PERFORM RECURSE_USED_OBJECT USING LS_OBJECT 0.
GV_SORT += 1.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form ANALYSIS_BATCH_SCHEDULE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM ANALYSIS_BATCH_SCHEDULE .
DATA: LV_IMP_S_RANGE TYPE T,
LV_IMP_E_RANGE TYPE T,
LV_IMP_CURSOR TYPE T,
LV_IMP_WINDOW TYPE I,
LV_TERM TYPE T VALUE '000500',
LV_INTER TYPE T VALUE '000100'.
DATA: RFC_OPT LIKE TABLE OF RFC_DB_OPT WITH HEADER LINE,
RFC_FLD LIKE TABLE OF RFC_DB_FLD WITH HEADER LINE,
RFC_DATA LIKE TABLE OF TAB512 WITH HEADER LINE.
DATA: LT_BATCH TYPE TABLE OF V_OP WITH HEADER LINE.
DATA: LV_RUNTIME TYPE P DECIMALS 2,
LV_DUETIME TYPE SYTABIX.
DATA: BEGIN OF LT_SCH_BATCH OCCURS 0,
SEL TYPE C,
LINECOLOR(4) TYPE C,
TRKORR TYPE E070-TRKORR,
OBJM_TYPE TYPE E071-OBJECT,
OBJM_NAME TYPE E071-OBJ_NAME,
OBJC_TYPE TYPE E071-OBJECT,
OBJC_NAME TYPE E071-OBJ_NAME,
DEPTH TYPE I,
BATCH_EXIST TYPE C,
JOBNAME LIKE TBTCO-JOBNAME,
SDLSTRTDT LIKE TBTCO-SDLSTRTDT,
SDLSTRTTM LIKE TBTCO-SDLSTRTTM,
STRTDATE LIKE TBTCO-STRTDATE,
STRTTIME LIKE TBTCO-STRTTIME,
ENDDATE LIKE TBTCO-ENDDATE,
ENDTIME LIKE TBTCO-ENDTIME,
PERIOD(10) TYPE C,
PRDMINS LIKE TBTCO-PRDMINS,
PRDHOURS LIKE TBTCO-PRDHOURS,
PRDDAYS LIKE TBTCO-PRDDAYS,
PRDWEEKS LIKE TBTCO-PRDWEEKS,
PRDMONTHS LIKE TBTCO-PRDMONTHS,
ESTI_RUN TYPE I,
BATCH_IMPACT TYPE C.
INCLUDE TYPE TY_TIMELINE.
DATA: END OF LT_SCH_BATCH.
DATA: LT_TEMP_BATCH LIKE TABLE OF LT_SCH_BATCH WITH HEADER LINE.
DATA: BEGIN OF LT_TIMESET OCCURS 0,
TIME_IDX(3) TYPE C,
TIME_VAL TYPE T,
TIME_TXT(5) TYPE C,
TIME_SEQ(4) TYPE I,
END OF LT_TIMESET.
"### 1. 배치잡 기초정보 가져오기
"### 1-1. V_OP 테이블을 읽기위한 쿼리, 셀렉트 필드 설정
RFC_OPT-TEXT = |PERIODIC = 'X' AND STATUS = 'S'|.
APPEND RFC_OPT.
RFC_FLD-FIELDNAME = 'JOBNAME'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'JOBCOUNT'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'PROGNAME'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'SDLSTRTDT'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'SDLSTRTTM'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'PRDMINS'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'PRDHOURS'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'PRDDAYS'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'PRDWEEKS'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'PRDMONTHS'. APPEND RFC_FLD.
"### 1-2. RFC 테이블 읽기
CALL FUNCTION 'RFC_READ_TABLE'
DESTINATION P_RFC
EXPORTING
QUERY_TABLE = 'V_OP'
DELIMITER = '|'
TABLES
OPTIONS = RFC_OPT
FIELDS = RFC_FLD
DATA = RFC_DATA
EXCEPTIONS
OTHERS = 1.
"### 1-3. 가져온 테이블 데이터를 필드에 맞게 매핑
LOOP AT RFC_DATA.
SPLIT RFC_DATA-WA AT '|' INTO TABLE DATA(LT_VOP).
LT_BATCH-JOBNAME = LT_VOP[ 1 ].
LT_BATCH-JOBCOUNT = LT_VOP[ 2 ].
LT_BATCH-PROGNAME = LT_VOP[ 3 ].
LT_BATCH-SDLSTRTDT = LT_VOP[ 4 ].
LT_BATCH-SDLSTRTTM = LT_VOP[ 5 ].
LT_BATCH-PRDMINS = LT_VOP[ 6 ].
LT_BATCH-PRDHOURS = LT_VOP[ 7 ].
LT_BATCH-PRDDAYS = LT_VOP[ 8 ].
LT_BATCH-PRDWEEKS = LT_VOP[ 9 ].
LT_BATCH-PRDMONTHS = LT_VOP[ 10 ].
APPEND LT_BATCH. CLEAR LT_BATCH.
ENDLOOP.
"### 1-4. 배치잡 영향도 오브젝트에 기초 정보 재매핑
"### 영향도 계산을 위한 메인 테이블 LT_SCH_BATCH 데이터 구성
LOOP AT GT_DATA.
LOOP AT LT_BATCH WHERE PROGNAME = GT_DATA-OBJC_NAME.
MOVE-CORRESPONDING GT_DATA TO LT_SCH_BATCH.
MOVE-CORRESPONDING LT_BATCH TO LT_SCH_BATCH.
APPEND LT_SCH_BATCH. CLEAR LT_SCH_BATCH.
ENDLOOP.
ENDLOOP.
SORT LT_SCH_BATCH BY TRKORR.
DELETE ADJACENT DUPLICATES FROM LT_SCH_BATCH COMPARING ALL FIELDS.
"### 2. 배포 예상 시간 타임라인 매칭 및 시간대셋트 데이터 구성.
LV_IMP_CURSOR = P_IMP_S.
LV_IMP_WINDOW = ( ( P_IMP_E - P_IMP_S ) / 60 ) + 1.
"### 2-1. 배포 예상 시간대를 1분단위로 쪼개서, 시간대(윈도우) 데이터 구성
DO LV_IMP_WINDOW TIMES.
LT_TIMESET-TIME_IDX = |T{ SY-INDEX }|.
LT_TIMESET-TIME_VAL = LV_IMP_CURSOR.
LT_TIMESET-TIME_SEQ = ( LV_IMP_CURSOR+0(2) * 60 ) + LV_IMP_CURSOR+2(2).
LT_TIMESET-TIME_TXT = |{ LV_IMP_CURSOR+0(2) }:{ LV_IMP_CURSOR+2(2) }|.
APPEND LT_TIMESET. CLEAR: LT_TIMESET.
IF LV_IMP_CURSOR = P_IMP_E.
EXIT.
ELSE.
LV_IMP_CURSOR += LV_INTER.
ENDIF.
ENDDO.
"### 3. 배포 시간대, 배치잡 영향도 계산 및 데이터 재구성
DATA: LV_IMP_SEQ_START(4) TYPE I,
LV_IMP_SEQ_END(4) TYPE I,
LV_ADJ_START1(4) TYPE I,
LV_ADJ_START2(4) TYPE I,
LV_ADJ_END(4) TYPE I,
LV_BTC_START(4) TYPE I,
LV_BTC_PERIOD(4) TYPE I,
LV_BTC_CURSOR(4) TYPE I,
LV_KMAX(4) TYPE I,
LV_KMIN(4) TYPE I.
DATA: LV_OFFSET_MIN TYPE P DECIMALS 2,
LV_OFFSET_MAX TYPE P DECIMALS 2.
FIELD-SYMBOLS: <fs_time> TYPE ANY.
DATA: TEMP_NIDX TYPE I,
TEMP_TIDX TYPE STRING.
"### 3-1. 배치잡 관련된 시간 값을 모두 분단위 시리얼 변환
"### 3-1-1. 배포 예상 시간을 분으로 시리얼 변환
"### 변환값 예시
"### 13:00 => 780 / 17:00 => 1020
LV_IMP_SEQ_START = ( P_IMP_S+0(2) * 60 ) + P_IMP_S+2(2).
LV_IMP_SEQ_END = ( P_IMP_E+0(2) * 60 ) + P_IMP_E+2(2).
LOOP AT LT_SCH_BATCH.
"### 3-1-2. 배치잡 시작 시간 시리얼 변환
LV_BTC_START = ( LT_SCH_BATCH-SDLSTRTTM+0(2) * 60 ) + LT_SCH_BATCH-SDLSTRTTM+2(2).
"### 3-1-3. 배치잡 주기 시리얼 변환
"### 분 주기 배치잡
IF LT_SCH_BATCH-PRDMINS IS NOT INITIAL.
LV_BTC_PERIOD = LT_SCH_BATCH-PRDMINS.
LT_SCH_BATCH-PERIOD = |{ CONV I( LT_SCH_BATCH-PRDMINS ) } m|.
"### 시 주기 배치잡
ELSEIF LT_SCH_BATCH-PRDHOURS IS NOT INITIAL.
LV_BTC_PERIOD = ( LT_SCH_BATCH-PRDHOURS * 60 ).
LT_SCH_BATCH-PERIOD = |{ CONV I( LT_SCH_BATCH-PRDHOURS ) } H|.
"### 일, 주, 월 주기 배치잡은 하루 한번 수행이므로, 0값 설정,
"### 즉, 주기값이 0인 배치잡은 일, 주, 월 주기 배치잡임.
ELSE.
LV_BTC_PERIOD = 0.
IF LT_SCH_BATCH-PRDDAYS IS NOT INITIAL.
LT_SCH_BATCH-PERIOD = |{ CONV I( LT_SCH_BATCH-PRDDAYS ) } D|.
ELSEIF LT_SCH_BATCH-PRDWEEKS IS NOT INITIAL.
LT_SCH_BATCH-PERIOD = |{ CONV I( LT_SCH_BATCH-PRDWEEKS ) } W|.
ELSEIF LT_SCH_BATCH-PRDMONTHS IS NOT INITIAL.
LT_SCH_BATCH-PERIOD = |{ CONV I( LT_SCH_BATCH-PRDMONTHS ) } M|.
ENDIF.
ENDIF.
"### 배치잡 주기단위 기록용 모디파이
MODIFY LT_SCH_BATCH.
"### 3-2-1. 배포 예상 시간대에 근접한 배치잡 시작 시간 계산 (분, 시 주기 배치잡 대상)
"### LV_ADJ_START1 은 배포 예상 시간대에 근접한 최저 시간
"### LV_ADJ_START2 는 배포 예상 시간대에 근접한 최대 시간
IF LV_BTC_PERIOD <> 0.
LV_OFFSET_MIN = FLOOR( ( LV_IMP_SEQ_START - LV_BTC_START ) / LV_BTC_PERIOD ).
LV_ADJ_START1 = ( LV_OFFSET_MIN * LV_BTC_PERIOD ) + LV_BTC_START.
LV_OFFSET_MAX = CEIL( ( LV_IMP_SEQ_START - LV_BTC_START ) / LV_BTC_PERIOD ).
LV_ADJ_START2 = ( LV_OFFSET_MAX * LV_BTC_PERIOD ) + LV_BTC_START.
"### 3-2-2. LV_ADJ_START1 또는 LV_ADJ_START2 값이 배포 예상 시간대 안이라면, 영향도 있음.
IF ( LV_ADJ_START1 >= LV_IMP_SEQ_START AND LV_ADJ_START1 <= LV_IMP_SEQ_END ) OR
( LV_ADJ_START2 >= LV_IMP_SEQ_START AND LV_ADJ_START2 <= LV_IMP_SEQ_END ).
LT_SCH_BATCH-BATCH_IMPACT = 'X'.
LT_SCH_BATCH-LINECOLOR = 'C300'.
MODIFY LT_SCH_BATCH.
ENDIF.
"### 3-2-3. 영향도 있는 배치잡에 대해서, 타임라인 상 수행시점 표시
IF LT_SCH_BATCH-BATCH_IMPACT = 'X'.
"### LV_ADJ_START1, LV_ADJ_START2 값 중,
"### 배포 예상 시간대(LT_TIMESET) 범주에 들어오는 시간대 선택
READ TABLE LT_TIMESET INDEX 1.
IF LV_ADJ_START1 >= LT_TIMESET-TIME_SEQ.
ASSIGN LV_ADJ_START1 TO <fs_time>.
ELSEIF LV_ADJ_START2 >= LT_TIMESET-TIME_SEQ.
ASSIGN LV_ADJ_START2 TO <fs_time>.
ENDIF.
IF SY-SUBRC = 0.
LV_BTC_CURSOR = <fs_time>.
"### 최대 배포 예상 시간대 간격만큼 반복 수행.
DO LV_IMP_WINDOW TIMES.
"### LT_TIMESET 테이블에서 현재 배치잡 수행 시간대 읽기
READ TABLE LT_TIMESET WITH KEY TIME_SEQ = LV_BTC_CURSOR.
"### LT_TIMESET 테이블에서 읽은 값 중, TIME_IDX 값으로 필드를 찾아 X값 표시
ASSIGN COMPONENT LT_TIMESET-TIME_IDX OF STRUCTURE LT_SCH_BATCH TO FIELD-SYMBOL(<fs_field>).
IF SY-SUBRC = 0.
<fs_field> = 'X'.
ENDIF.
MODIFY LT_SCH_BATCH.
LV_BTC_CURSOR += LV_BTC_PERIOD.
"### 다음 주기 수행시간이 배포 예상 종료시간을 초과한다면, 반복문 탈출.
IF LV_BTC_CURSOR > LV_IMP_SEQ_END.
EXIT.
ENDIF.
ENDDO.
ENDIF.
ENDIF.
"### 3-3-1. 배포 예상 시간대에 수행되는 배치잡 표시 (일, 주, 월 주기 배치잡 대상)
"### LV_BTC_PERIOD = 0 대상.
ELSE.
LV_BTC_CURSOR = LV_BTC_START.
READ TABLE LT_TIMESET WITH KEY TIME_SEQ = LV_BTC_CURSOR.
"### 배치잡 시작 시간이, 배포 예상 시간대 윈도우 안에 있다면, 해당 타임라인에 체크
"### 일, 주, 월 주기 배치잡은 하루 1번 수행이므로 반복할 필요 없이, 한번 체크로 종료.
IF SY-SUBRC = 0.
LT_SCH_BATCH-BATCH_IMPACT = 'X'.
LT_SCH_BATCH-LINECOLOR = 'C300'.
ASSIGN COMPONENT LT_TIMESET-TIME_IDX OF STRUCTURE LT_SCH_BATCH TO FIELD-SYMBOL(<fs_field2>).
IF SY-SUBRC = 0.
<fs_field2> = 'X'.
ENDIF.
MODIFY LT_SCH_BATCH.
ENDIF.
ENDIF.
ENDLOOP.
"### 4. 배포에 영향도가 있는 배치잡에 대해서, 이전 이력 기반으로 수행시간 계산
"### - 분 단위 배치잡은 엔트리 건수도 많고, 짧은 주기일 경우, 런타임이 대부분 짧기 때문에 분석 제외.
LOOP AT LT_SCH_BATCH WHERE BATCH_IMPACT = 'X' AND PERIOD NP '*m'.
REFRESH: LT_BATCH, RFC_OPT, RFC_FLD, RFC_DATA.
CLEAR: LT_BATCH, RFC_OPT, RFC_FLD, RFC_DATA.
"### 배치잡 수행시간 계산을 위한 기초 데이터 읽기
RFC_OPT-TEXT = |JOBNAME = '{ LT_SCH_BATCH-JOBNAME }'|. APPEND RFC_OPT.
RFC_OPT-TEXT = |AND STATUS = 'F' AND PERIODIC = 'X'|. APPEND RFC_OPT.
RFC_FLD-FIELDNAME = 'JOBNAME'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'STRTDATE'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'STRTTIME'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'ENDDATE'. APPEND RFC_FLD.
RFC_FLD-FIELDNAME = 'ENDTIME'. APPEND RFC_FLD.
CALL FUNCTION 'RFC_READ_TABLE'
DESTINATION P_RFC
EXPORTING
QUERY_TABLE = 'V_OP'
DELIMITER = '|'
TABLES
OPTIONS = RFC_OPT
FIELDS = RFC_FLD
DATA = RFC_DATA
EXCEPTIONS
OTHERS = 1.
LOOP AT RFC_DATA.
SPLIT RFC_DATA-WA AT '|' INTO TABLE DATA(LT_EXTIME).
LT_BATCH-JOBNAME = LT_EXTIME[ 1 ].
LT_BATCH-STRTDATE = LT_EXTIME[ 2 ].
LT_BATCH-STRTTIME = LT_EXTIME[ 3 ].
LT_BATCH-ENDDATE = LT_EXTIME[ 4 ].
LT_BATCH-ENDTIME = LT_EXTIME[ 5 ].
APPEND LT_BATCH. CLEAR LT_BATCH.
ENDLOOP.
"### 배치잡 수행시간 평균을 구하기 위해, 누적 수행시간값 초기화
LV_RUNTIME = 0.
LOOP AT LT_BATCH.
CALL FUNCTION 'SWI_DURATION_DETERMINE'
EXPORTING
START_DATE = LT_BATCH-STRTDATE
END_DATE = LT_BATCH-ENDDATE
START_TIME = LT_BATCH-STRTTIME
END_TIME = LT_BATCH-ENDTIME
IMPORTING
DURATION = LV_DUETIME.
LV_RUNTIME = LV_RUNTIME + LV_DUETIME.
ENDLOOP.
"### 누적 수행시간값을 평균을 내고, 분 단위로 변환
LV_RUNTIME = CEIL( ( LV_RUNTIME / LINES( LT_BATCH ) ) / 60 ).
"### 평균 배치잡 수행시간이 1분을 넘는다면, 예상 수행시간 필드(ESTI_RUN) 에 기록
IF LV_RUNTIME > 1.
LT_SCH_BATCH-ESTI_RUN = LV_RUNTIME.
ELSE.
LT_SCH_BATCH-ESTI_RUN = 1.
ENDIF.
MODIFY LT_SCH_BATCH.
"### ESTI_RUN 이 1분이 넘는다면, 타임라인 상에 수행 예상 시간만큼 추가 표기
REFRESH: LT_TEMP_BATCH. CLEAR: LT_TEMP_BATCH.
"### 원본 데이터가 섞일 수 있으니, 지표 확인용 LT_TEMP_BATCH 테이블 생성 및 복사
LT_TEMP_BATCH[] = LT_SCH_BATCH[].
DATA(END_CURSOR) = |T{ LV_IMP_WINDOW }|.
LOOP AT LT_TEMP_BATCH WHERE ESTI_RUN > 1.
LOOP AT LT_TIMESET.
ASSIGN COMPONENT LT_TIMESET-TIME_IDX OF STRUCTURE LT_TEMP_BATCH TO FIELD-SYMBOL(<fs_field3>).
IF SY-SUBRC = 0 AND <fs_field3> = 'X'.
TEMP_TIDX = LT_TIMESET-TIME_IDX.
REPLACE ALL OCCURRENCES OF 'T' IN TEMP_TIDX WITH ''.
TEMP_NIDX = TEMP_TIDX + 1.
"### ESTI_RUN 값만큼 커서를 한칸씩 이동하여 타임라인상에 X 표기
DO ( LT_TEMP_BATCH-ESTI_RUN - 1 ) TIMES.
DATA(RUN_CURSOR) = |T{ TEMP_NIDX }|.
ASSIGN COMPONENT RUN_CURSOR OF STRUCTURE LT_SCH_BATCH TO FIELD-SYMBOL(<fs_field4>).
IF SY-SUBRC = 0.
<fs_field4> = 'X'.
ENDIF.
MODIFY LT_SCH_BATCH.
TEMP_NIDX += 1.
"### 타임 윈도우 상 최대값을 벗어나면, 그대로 표기 종료
IF RUN_CURSOR = END_CURSOR.
EXIT.
ENDIF.
ENDDO.
ENDIF.
ENDLOOP.
ENDLOOP.
ENDLOOP.
"### 사용된 필드심볼 전부 해제
UNASSIGN: <fs_time>, <fs_field>, <fs_field2>, <fs_field3>, <fs_field4>.
"### 5. 결과 데이터 출력
DATA: L_POS TYPE I VALUE 0.
DATA: LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
LT_LAYOUT TYPE SLIS_LAYOUT_ALV.
"### Build Field Catalog
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'TRKORR'.
LT_FIELDCAT-SELTEXT_M = 'CTS Number'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJM_TYPE'.
LT_FIELDCAT-SELTEXT_M = 'Object Type'.
LT_FIELDCAT-OUTPUTLEN = 6.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJM_NAME'.
LT_FIELDCAT-SELTEXT_M = 'Object Name'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'DEPTH'.
LT_FIELDCAT-SELTEXT_M = 'Depth'.
LT_FIELDCAT-OUTPUTLEN = 5.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJC_TYPE'.
LT_FIELDCAT-SELTEXT_M = 'Child Obj. Type'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'OBJC_NAME'.
LT_FIELDCAT-SELTEXT_M = 'Child Obj. Name'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'JOBNAME'.
LT_FIELDCAT-SELTEXT_M = 'Job Name'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'BATCH_IMPACT'.
LT_FIELDCAT-SELTEXT_M = 'IMPACT'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-JUST = 'C'.
LT_FIELDCAT-OUTPUTLEN = 4.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'PERIOD'.
LT_FIELDCAT-SELTEXT_M = 'Period'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-JUST = 'C'.
LT_FIELDCAT-OUTPUTLEN = 6.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = 'ESTI_RUN'.
LT_FIELDCAT-SELTEXT_M = 'Run time'.
LT_FIELDCAT-SELTEXT_L = 'Run Time (min)'.
LT_FIELDCAT-KEY = 'X'.
LT_FIELDCAT-OUTPUTLEN = 4.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
LOOP AT LT_TIMESET.
L_POS = L_POS + 1.
LT_FIELDCAT-COL_POS = L_POS.
LT_FIELDCAT-FIELDNAME = LT_TIMESET-TIME_IDX.
LT_FIELDCAT-SELTEXT_M = LT_TIMESET-TIME_TXT.
LT_FIELDCAT-JUST = 'C'.
LT_FIELDCAT-OUTPUTLEN = 4.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
ENDLOOP.
"### ALV Layout 설정
LT_LAYOUT-BOX_FIELDNAME = 'SEL'.
LT_LAYOUT-INFO_FIELDNAME = 'LINECOLOR'.
LT_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
* LT_LAYOUT-ZEBRA = 'X'.
LT_LAYOUT-BOX_TABNAME = 'LT_SCH_BATCH'.
"### 위에 설정된 Field Catalog 와 Layout 을 사용하여 ALV 리스트 출력 펑션 콜
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
* I_CALLBACK_USER_COMMAND = 'USER_COMMAND_DISP'
* I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
* I_GRID_TITLE = GV_ALV_HEADER
* I_CALLBACK_TOP_OF_PAGE = 'TOP-OF-PAGE'
* I_HTML_HEIGHT_TOP = 10
* IT_EVENTS = GT_EVENT[]
* IT_SORT = TEMP_SORT[]
IT_FIELDCAT = LT_FIELDCAT[]
IS_LAYOUT = LT_LAYOUT
* I_SAVE = 'A'
TABLES
T_OUTTAB = LT_SCH_BATCH
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form EXCUTE_TEST_IMPORT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM EXCUTE_TEST_IMPORT .
DATA: LT_TP_QUEUE TYPE TMSIQREQS,
LS_TP_QUEUE LIKE STMSIQREQ.
DATA: LT_TEST_QUEUE LIKE TABLE OF TMSBUFFER,
LS_TEST_QUEUE LIKE TMSBUFFER.
DATA: LT_RET_IMPORT TYPE STMS_TP_IMPORTS.
DATA: LT_TP_RC LIKE STPA-RETCODE.
DATA: BEGIN OF LT_TMSSYS OCCURS 0,
CHECK TYPE C,
LINECOLOR(4) TYPE C.
INCLUDE STRUCTURE TMSCSYS.
DATA: END OF LT_TMSSYS.
DATA: LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
LT_EXTAB TYPE SLIS_T_EXTAB WITH HEADER LINE.
DATA: LV_RET TYPE C,
LV_COUNT TYPE I VALUE 0.
DATA: LV_CLIENT(3) TYPE C.
"### 품질시스템 제한
SELECT * INTO CORRESPONDING FIELDS OF TABLE LT_TMSSYS
FROM TMSCSYS
WHERE TMSCFG = 'A'.
LT_FIELDCAT-COL_POS = 1.
LT_FIELDCAT-FIELDNAME = 'SYSNAM'.
LT_FIELDCAT-SELTEXT_M = ' SID'.
LT_FIELDCAT-OUTPUTLEN = 5.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
LT_FIELDCAT-COL_POS = 2.
LT_FIELDCAT-FIELDNAME = 'SYSTXT'.
LT_FIELDCAT-SELTEXT_M = 'Desc.'.
LT_FIELDCAT-OUTPUTLEN = 12.
APPEND LT_FIELDCAT. CLEAR LT_FIELDCAT.
LT_EXTAB = '&ETA'. APPEND LT_EXTAB.
LT_EXTAB = '&OUP'. APPEND LT_EXTAB.
LT_EXTAB = '&ODN'. APPEND LT_EXTAB.
LT_EXTAB = '&ILT'. APPEND LT_EXTAB.
LT_EXTAB = '&OL0'. APPEND LT_EXTAB.
LT_EXTAB = '%SC'. APPEND LT_EXTAB.
LT_EXTAB = '%SC+'. APPEND LT_EXTAB.
CALL FUNCTION 'REUSE_ALV_POPUP_TO_SELECT'
EXPORTING
I_TITLE = 'Select Test Import System'
I_SCREEN_START_COLUMN = 10
I_SCREEN_START_LINE = 10
I_SCREEN_END_COLUMN = 70
I_SCREEN_END_LINE = 20
I_CHECKBOX_FIELDNAME = 'CHECK'
I_LINEMARK_FIELDNAME = 'LINECOLOR'
I_TABNAME = 'LT_TMSSYS'
IT_FIELDCAT = LT_FIELDCAT[]
IT_EXCLUDING = LT_EXTAB[]
IMPORTING
E_EXIT = LV_RET
TABLES
T_OUTTAB = LT_TMSSYS.
LV_COUNT = 0.
IF LV_RET IS INITIAL.
LOOP AT LT_TMSSYS WHERE CHECK = 'X'.
LV_COUNT += 1.
ENDLOOP.
IF LV_COUNT = 1.
READ TABLE LT_TMSSYS WITH KEY CHECK = 'X'.
ELSE.
MESSAGE |타겟 시스템은 1개만 선택할 수 있습니다.| TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
ELSE.
REJECT.
ENDIF.
"### 타겟 시스템 TP Queue 읽어오기
CALL FUNCTION 'TMS_UIQ_IQD_READ_QUEUE'
EXPORTING
IV_SYSTEM = LT_TMSSYS-SYSNAM
IV_DOMAIN = LT_TMSSYS-DOMNAM
IV_COLLECT = 'X'
IV_READ_SHADOW = 'X'
IV_MONITOR = 'X'
IMPORTING
ET_REQUESTS = LT_TP_QUEUE
EXCEPTIONS
READ_CONFIG_FAILED = 1
TABLE_OF_REQUESTS_IS_EMPTY = 2
OTHERS = 3.
IF SY-SUBRC = 0.
"### 현재 입력된 CTS 번호로 TP QUEUE 파일에서 정보 가져오기
LOOP AT P_TRKORR.
READ TABLE LT_TP_QUEUE INTO LS_TP_QUEUE WITH KEY SYSNAM = LT_TMSSYS-SYSNAM
TRKORR = P_TRKORR-LOW.
IF SY-SUBRC = 0.
MOVE-CORRESPONDING LS_TP_QUEUE TO LS_TEST_QUEUE.
APPEND LS_TEST_QUEUE TO LT_TEST_QUEUE.
"### Import Queue 에 대상 CTS 가 없을 경우, 오류 메세지 출력
ELSE.
MESSAGE |대상 CTS 가 Import Queue 에 없습니다.| TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
ENDLOOP.
"### TP QUEUE 에서 가져온 CTS 정보로 TEST IMPORT 수행
CALL FUNCTION 'TMS_MGR_IMPORT_TR_REQUEST'
EXPORTING
IV_SYSTEM = LT_TMSSYS-SYSNAM
IV_DOMAIN = LT_TMSSYS-DOMNAM
IV_REQUEST = 'SOME'
IV_CLIENT = LV_CLIENT
IV_OVERTAKE = 'X'
IV_SUBSET = 'X'
IV_OFFLINE = 'X'
IV_MONITOR = 'X'
IV_TEST_IMPORT = 'X'
IT_REQUESTS = LT_TEST_QUEUE
IMPORTING
EV_TP_RET_CODE = LT_TP_RC
ET_TP_IMPORTS = LT_RET_IMPORT
EXCEPTIONS
READ_CONFIG_FAILED = 1
TABLE_OF_REQUESTS_IS_EMPTY = 2
OTHERS = 3.
"### TEST IMPORT 가 정상적으로 수행되었다면, RET_CODE 로 결과 확인
IF SY-SUBRC = 0.
iF LT_TP_RC = '0000'.
MESSAGE |TEST Import : 성공| TYPE 'S'.
ELSE.
MESSAGE |TEST Import : 오류| TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ELSE.
MESSAGE |Test Import 수행에 실패했습니다.| TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ELSE.
MESSAGE |Import Queue 읽기에 실패했습니다.| TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form EXCUTE_SDF_TRCHECK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM EXCUTE_SDF_TRCHECK .
DATA: LT_POPUP LIKE SVAL OCCURS 0 WITH HEADER LINE.
DATA: LV_RET TYPE C.
DATA: LT_RFCDES LIKE TABLE OF RFCDES WITH HEADER LINE.
DATA: LV_S_RFCDEST TYPE RFCDEST,
LV_T_RFCDEST TYPE RFCDEST.
LT_POPUP-TABNAME = 'RFCATTRIB'.
LT_POPUP-FIELDNAME = 'RFCDEST'.
LT_POPUP-FIELDTEXT = 'Source System RFC'.
LT_POPUP-FIELD_OBL = 'X'.
APPEND LT_POPUP. CLEAR LT_POPUP.
LT_POPUP-TABNAME = 'RFCCHECK'.
LT_POPUP-FIELDNAME = 'RFCDEST'.
LT_POPUP-FIELDTEXT = 'Target System RFC'.
LT_POPUP-FIELD_OBL = 'X'.
APPEND LT_POPUP. CLEAR LT_POPUP.
"### 팝업 출력
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
POPUP_TITLE = 'RFC Info'
IMPORTING
RETURNCODE = LV_RET
TABLES
FIELDS = LT_POPUP
EXCEPTIONS
ERROR_IN_FIELDS = 1
OTHERS = 2.
IF LV_RET IS INITIAL.
READ TABLE LT_POPUP WITH KEY TABNAME = 'RFCATTRIB'. LV_S_RFCDEST = LT_POPUP-VALUE.
READ TABLE LT_POPUP WITH KEY TABNAME = 'RFCCHECK'. LV_T_RFCDEST = LT_POPUP-VALUE.
SELECT * INTO CORRESPONDING FIELDS OF TABLE LT_RFCDES
FROM RFCDES
WHERE RFCTYPE = '3'.
READ TABLE LT_RFCDES WITH KEY RFCDEST = LV_S_RFCDEST.
IF SY-SUBRC <> 0.
MESSAGE 'Source System 의 RFC 목적지 이름이 올바르지 않습니다.' TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
READ TABLE LT_RFCDES WITH KEY RFCDEST = LV_T_RFCDEST.
IF SY-SUBRC <> 0.
MESSAGE 'Target System 의 RFC 목적지 이름이 올바르지 않습니다.' TYPE 'S' DISPLAY LIKE 'E'.
REJECT.
ENDIF.
SUBMIT /SDF/CMO_TR_CHECK
WITH P_SOURCE = LV_S_RFCDEST
WITH P_TARGET = LV_T_RFCDEST
WITH R_PRJ_CO = 'X'
WITH P_ORI_TR IN P_TRKORR
WITH P_CRSREF = abap_true "-- Cross reference
WITH P_DGP = abap_true "-- Sequence Check
WITH P_SWCOMP = abap_true "-- Cross release
WITH P_IMPTIM = abap_true "-- Import Time in source
WITH P_OICHCK = abap_true "-- Online import check
AND RETURN.
ELSE.
REJECT.
ENDIF.
ENDFORM.