본문 바로가기
ABAP/소스코드

[Report] Customer Exit(SMOD) 및 BAdI 찾는 리포트

by name_text 2023. 7. 20.

Customer Exit(SMOD)

BAdI

 

인터넷에 돌아다니는 User-exit(Customer exit)을 찾은 리포트에 BAdI 와 구현정보 까지 찾을수 있도록 기능을 개선한 리포트입니다.

 

T-Code를 입력하면 해당 T-Code의 프로그램의 개발클래스에 포함된 SMOD와 SXSD(BAdI)를 찾는 방식이며

BAdI의 경우 연관된 다른 개발클래스(하위 개발클래스, _BADI 개발클래스 등)에서 까지 검색을 하게 하였습니다.

 

T-Code를 입력하고 실행하면, 해당 T-Code에 관련된 Exit 및 BAdI를 검색합니다.

 

# 소스코드

*&---------------------------------------------------------------------*
*& Report ZCMR9001
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZCMR9001.
* Finding the user-exits of a SAP transaction code
*
* Enter the transaction code in which you are looking for the user-exit
* and it will list you the list of user-exits in the transaction code.
* Also a drill down is possible which will help you to branch to SMOD.
*
* Written by : SAP Basis, ABAP Programming and Other IMG Stuff
*              http://www.sap-img.com
*
* Modify by : https://playabap.tistory.com

TABLES: TSTC, TADIR, TRDIR, TFDIR, ENLFDIR.
TABLES: TSTCT, TDEVCT.
DATA: GT_TADIR TYPE SORTED TABLE OF TADIR WITH UNIQUE KEY DEVCLASS OBJECT OBJ_NAME,
      GS_TADIR LIKE LINE OF GT_TADIR,
      GT_TMP   TYPE STANDARD TABLE OF TADIR,
      GS_TMP   LIKE LINE OF GT_TMP,
      GV_CURSOR_F(30)  TYPE C,
      GV_DEVCLASS      LIKE TADIR-DEVCLASS,
      GV_DEVCLASS_BADI LIKE TADIR-DEVCLASS,
      GV_SBD_OK        TYPE C,
      GV_SUB_OK        TYPE C,
      GV_EXT_OK        TYPE C,
      GV_CNT_SMOD      TYPE I,
      GV_CNT_SXSD      TYPE I.

PARAMETERS : P_TCODE LIKE TSTC-TCODE MEMORY ID TCD OBLIGATORY.

START-OF-SELECTION.
  SELECT SINGLE * FROM TSTC WHERE TCODE EQ P_TCODE.
  IF SY-SUBRC EQ 0.
    SELECT SINGLE * FROM TADIR  WHERE PGMID     EQ 'R3TR'
                                  AND OBJECT    EQ 'PROG'
                                  AND OBJ_NAME  EQ TSTC-PGMNA.
    IF SY-SUBRC EQ 0.
      MOVE TADIR-DEVCLASS TO GV_DEVCLASS.
    ELSE.
      SELECT SINGLE * FROM TRDIR WHERE NAME EQ TSTC-PGMNA.
      IF TRDIR-SUBC EQ 'F'.
        SELECT SINGLE * FROM TFDIR    WHERE PNAME     EQ TSTC-PGMNA.
        SELECT SINGLE * FROM ENLFDIR  WHERE FUNCNAME  EQ TFDIR-FUNCNAME.
        SELECT SINGLE * FROM TADIR    WHERE PGMID     EQ 'R3TR'
                                        AND OBJECT    EQ 'FUGR'
                                        AND OBJ_NAME  EQ ENLFDIR-AREA.
        MOVE TADIR-DEVCLASS TO GV_DEVCLASS.
      ENDIF.
    ENDIF.
    CONCATENATE GV_DEVCLASS 'BADI' INTO GV_DEVCLASS_BADI SEPARATED BY '_'.

    "T-Code에 해당하는 프로그램의 개발클래스에서 SMOD 와 BADI(SXSD) 찾기
    CLEAR: GV_SBD_OK, GV_SUB_OK, GV_EXT_OK.
    "1. 개발클래스의 SMOD, SXSD 오브젝트
    SELECT OBJECT OBJ_NAME  DEVCLASS
      INTO CORRESPONDING FIELDS OF TABLE GT_TADIR
    FROM TADIR
    WHERE PGMID     EQ 'R3TR'
      AND OBJECT    IN ( 'SMOD', 'SXSD' )
      AND DEVCLASS  EQ GV_DEVCLASS.
    SELECT OBJECT OBJ_NAME  DEVCLASS
      APPENDING CORRESPONDING FIELDS OF TABLE GT_TADIR
    FROM TADIR
    WHERE PGMID     EQ 'R3TR'
      AND OBJECT    IN ( 'SMOD', 'SXSD' )
      AND DEVCLASS  EQ GV_DEVCLASS_BADI.
    IF SY-SUBRC EQ 0.
      GV_SBD_OK = 'X'.
    ENDIF.
    "2. 하위 개발클래스의 SMOD, SXSD 오브젝트
    SELECT OBJECT OBJ_NAME  A~DEVCLASS
      APPENDING CORRESPONDING FIELDS OF TABLE GT_TADIR
    FROM TADIR AS A
      INNER JOIN TDEVC AS B ON A~DEVCLASS EQ B~DEVCLASS
    WHERE A~PGMID     EQ 'R3TR'
      AND A~OBJECT    IN ( 'SMOD', 'SXSD' )
      AND B~PARENTCL  EQ GV_DEVCLASS.
    IF SY-SUBRC EQ 0.
      GV_SUB_OK = 'X'.
    ENDIF.
    "3. 개발클래스 앞 2자리 개발클래스의 SMOD, SXSD 오브젝트
    IF GV_DEVCLASS NE GV_DEVCLASS(2).
      SELECT OBJECT OBJ_NAME  DEVCLASS
        APPENDING CORRESPONDING FIELDS OF TABLE GT_TADIR
      FROM TADIR AS A
      WHERE PGMID     EQ 'R3TR'
        AND OBJECT    IN ( 'SMOD', 'SXSD' )
        AND DEVCLASS  EQ GV_DEVCLASS(2).
      IF SY-SUBRC EQ 0.
        GV_EXT_OK = 'X'.
      ENDIF.
    ENDIF.

    SELECT SINGLE * FROM TSTCT  WHERE SPRSL EQ SY-LANGU
                                  AND TCODE EQ P_TCODE.
    FORMAT COLOR COL_POSITIVE INTENSIFIED OFF.
    WRITE:/2(20) 'Transaction Code',
           28(20) P_TCODE,
           45(138) TSTCT-TTEXT.
    SKIP.

    IF NOT GT_TADIR[] IS INITIAL.
      GT_TMP[] = GT_TADIR[].
      SORT GT_TMP BY DEVCLASS.
      DELETE ADJACENT DUPLICATES FROM GT_TMP COMPARING DEVCLASS.

      "1. 개발클래스의 SMOD, SXSD 오브젝트
      PERFORM WRITE_ENHANCEMENT_LIST USING GV_DEVCLASS.
      IF GV_SBD_OK EQ 'X'.
        PERFORM WRITE_ENHANCEMENT_LIST USING GV_DEVCLASS_BADI.
      ENDIF.

      "2. 하위 개발클래스의 SMOD, SXSD 오브젝트
      IF GV_SUB_OK EQ 'X'.
        LOOP AT GT_TMP INTO GS_TMP WHERE DEVCLASS NE GV_DEVCLASS AND DEVCLASS NE GV_DEVCLASS(2).
          PERFORM WRITE_ENHANCEMENT_LIST USING GS_TMP-DEVCLASS.
        ENDLOOP.
      ENDIF.

      "3. 개발클래스 앞 2자리 개발클래스의 SXSD 오브젝트
      IF GV_EXT_OK EQ 'X'.
        PERFORM WRITE_ENHANCEMENT_LIST USING GV_DEVCLASS(2).
      ENDIF.
    ELSE.
      FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.
      WRITE:/(101) 'NO USER EXIT EXISTS'.
    ENDIF.
  ELSE.
    FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.
    WRITE:/(101) 'TRANSACTION CODE DOES NOT EXIST'.
  ENDIF.

AT LINE-SELECTION.
  PERFORM LINE_SELECTION.

*&---------------------------------------------------------------------*
*& Form WRITE_ENHANCEMENT_LIST
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM WRITE_ENHANCEMENT_LIST USING P_DEVCLASS.
  DATA: LV_INIT TYPE C,
        LV_OBJECT LIKE TADIR-OBJECT,
        LV_HEADER_T(20)  TYPE C,
        LV_TEXT TYPE CUS_TEXT,
        LV_IMP  TYPE SXC_ATTRT-IMP_NAME,
        LV_IMP_T TYPE SXC_ATTRT-TEXT.
  CLEAR: GV_CNT_SMOD, GV_CNT_SXSD.
  CLEAR TDEVCT-CTEXT.
  SELECT SINGLE * FROM TDEVCT WHERE SPRAS EQ SY-LANGU
                                AND DEVCLASS EQ P_DEVCLASS.

  WRITE:/(183) SY-ULINE.
  FORMAT COLOR COL_GROUP INTENSIFIED OFF.
  WRITE:/1 SY-VLINE,
         2(20) 'DevClass(Package)',
         28(20) P_DEVCLASS,
         45(50) TDEVCT-CTEXT,
         183 SY-VLINE.
  DO 2 TIMES.
    IF SY-INDEX EQ 1.
      LV_OBJECT = 'SMOD'.
      LV_HEADER_T = 'Exit Name'.
    ELSE.
      LV_OBJECT = 'SXSD'.
      LV_HEADER_T = 'BAdI Name'.
    ENDIF.
    CLEAR LV_INIT.
    LOOP AT GT_TADIR INTO GS_TADIR WHERE DEVCLASS EQ P_DEVCLASS AND OBJECT EQ LV_OBJECT.
      IF LV_INIT IS INITIAL.
        LV_INIT = 'X'.
        FORMAT COLOR COL_HEADING INTENSIFIED ON.
        WRITE:/(183) SY-ULINE.
        WRITE:/1 SY-VLINE,
              2 'Type',
              6 SY-VLINE,
              7 LV_HEADER_T,
              27 SY-VLINE ,
              28 'Description',
              101 SY-VLINE,
              102 'Implementation',
              122 SY-VLINE,
              123 'Description',
              183 SY-VLINE.
      ENDIF.

      CLEAR: LV_IMP, LV_IMP_T.
      CASE GS_TADIR-OBJECT.
        WHEN 'SMOD'.
          ADD 1 TO GV_CNT_SMOD.
          SELECT SINGLE MODTEXT INTO LV_TEXT
            FROM MODSAPT WHERE SPRSL EQ SY-LANGU AND NAME  EQ GS_TADIR-OBJ_NAME.

          "구현정보
          SELECT SINGLE
            A~NAME  B~MODTEXT
            INTO ( LV_IMP, LV_IMP_T )
          FROM MODACT AS A
            LEFT OUTER JOIN MODTEXT AS B ON A~NAME EQ B~NAME AND B~SPRSL EQ SY-LANGU
          WHERE A~MEMBER EQ GS_TADIR-OBJ_NAME.
        WHEN 'SXSD'.
          ADD 1 TO GV_CNT_SXSD.
          SELECT SINGLE TEXT INTO LV_TEXT
            FROM SXS_ATTRT WHERE SPRSL EQ SY-LANGU AND EXIT_NAME EQ GS_TADIR-OBJ_NAME.

          "구현정보
          SELECT SINGLE
            A~IMP_NAME  B~TEXT
            INTO ( LV_IMP, LV_IMP_T )
          FROM SXC_EXIT AS A
            LEFT OUTER JOIN SXC_ATTRT AS B ON A~IMP_NAME EQ B~IMP_NAME AND B~SPRSL EQ SY-LANGU
          WHERE A~EXIT_NAME EQ GS_TADIR-OBJ_NAME.
      ENDCASE.

      FORMAT COLOR COL_NORMAL INTENSIFIED OFF.
      WRITE:/1 SY-VLINE,
            2 LV_OBJECT,
            6 SY-VLINE,
            7 GS_TADIR-OBJ_NAME HOTSPOT ON,
            27 SY-VLINE ,
            28 LV_TEXT,
            101 SY-VLINE,
            102 LV_IMP HOTSPOT ON,
            122 SY-VLINE ,
            123 LV_IMP_T,
            183 SY-VLINE.
    ENDLOOP.
  ENDDO.
  WRITE:/(183) SY-ULINE.
  FORMAT COLOR COL_TOTAL INTENSIFIED ON.
  WRITE:/2 'No of exits:' , GV_CNT_SMOD.
  WRITE:/2 'No of BAdIs:' , GV_CNT_SXSD.
  SKIP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form LINE_SELECTION
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM LINE_SELECTION .
  DATA: LV_VALUE(20) TYPE C.

  GET CURSOR FIELD GV_CURSOR_F.

  IF GV_CURSOR_F EQ 'GS_TADIR-OBJ_NAME'.
    LV_VALUE = SY-LISEL+6(20).
    CASE SY-LISEL+1(4).
      WHEN 'SMOD'.
        SET PARAMETER ID 'MON' FIELD LV_VALUE.
        CALL TRANSACTION 'SMOD' AND SKIP FIRST  SCREEN.
      WHEN 'SXSD'.
        SET PARAMETER ID 'EXN' FIELD LV_VALUE.
        CALL TRANSACTION 'SE18' AND SKIP FIRST  SCREEN.
    ENDCASE.
  ELSE.
    LV_VALUE = SY-LISEL+101(20).
    IF LV_VALUE IS NOT INITIAL.
      CASE SY-LISEL+1(4).
        WHEN 'SMOD'.
          SET PARAMETER ID 'MON' FIELD LV_VALUE.
          CALL TRANSACTION 'CMOD' AND SKIP FIRST  SCREEN.
        WHEN 'SXSD'.
          SET PARAMETER ID 'IMN' FIELD LV_VALUE.
          CALL TRANSACTION 'SE19' AND SKIP FIRST  SCREEN.
      ENDCASE.
    ENDIF.
  ENDIF.
ENDFORM.

 

댓글