ABAP - CTS 영향도 분석 프로그램__CTS Impact Analysis Program

감귤은탱귤·2025년 12월 4일

ABAP - BC 프로그램

목록 보기
13/13

◾ 모듈 : BC
◾ 기능 설명 : CTS 운영 배포 시, 영향이 있을 수 있는 오브젝트 분석 (프로그램, 배치잡, 인터페이스)
🔰 New Syntax 사용

◾ 사용 예시 :
1. RFC 연결을 통해 연결된 시스템에 대해서, 배포 시, 영향이 있을 수 있는 오브젝트 식별
2. 배포 예상 시간대(최대 30분) 설정을 기반으로 배치잡 영향도 분석
3. 설정된 인터페이스 네이밍 룰을 기반으로 인터페이스 오브젝트 식별
4. Test Import 기능으로 CTS 배포 테스트 분석
5. /SDF/TRCHECK 를 통한 CTS 분석기능 내재화
6. 추 후, RFC 연결 대상 시스템에서 오브젝트 사용량 기반, 위험 오브젝트 식별 기능 추가 예정 (IMPACT_LEVEL 필드)



1. 소스 코드

***********************************************************************
* 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.
profile
SAP BC (2019 ~ )

0개의 댓글