본문 바로가기

SAP/ABAP

ABAP. 7

ABAP 언어에 대한 개념을 정리하는 포스팅입니다.

작성자는 ABAP에 대한 전문가가 아니며, 작성된 정보가 부정확할 수 있으니 게시글은 참고 목적으로만 봐주시면 감사하겠습니다.


ALV

ALV는 ABAP List Viewer의 약자로서 리스트 화면에 데이터를 조회하거나, 조회된 데이터를 수정/변경하는 목적으로 실무에서 많이 사용합니다.

 

ALV는 함수를 이용하는 방법과 GRID 컨트롤을 이용하는 방법 2가지가 있습니다.

개발 순서는 Function ALV -> Grid ALV -> SALV입니다.

이 중 Grid ALV에 대해 작성하려고 합니다.

 

ALV Grid 컨트롤은 화면 Display에서 SAP사에서 이미 개발한 컨트롤 기술을 사용합니다.

ALV 내부 구조

ALV가 화면에 보이기까지 내부적으로 구성되는 순서는 다음과 같습니다.

1. ALV 영역 지정 - 영역 지정은 스크린의 레이아웃에서 Custom Control을 이용하여 설정

2. ALV를 화면에 보이게 하기 위해 스크린 영역과 ALV를 연결하는 SAP 컨테이너 컨트롤이 반드시 존재해야 한다.

3. 컨테이너 컨트롤을 생성했으면 그 위에 ALV 그리드 컨트롤을 생성하여 올린다.


SAP 컨테이너는 ALV Grid 컨트롤의 연결 고리 역할을 수행하며, ALV 설정시 반드시 존재해야 합니다.

 

SAP 컨테이너의 종류는 다음과 같습니다.

1. SAP Custom Container - 스크린 페인터를 사용하는 일반적인 화면에서 영역을 정의한다.

Class: CL_GUI_CUSTOM_CONTAINER

2. SAP Dialog Box Container - Dialog Box, Full Screen에서 Dialog Box 형태로 보이도록 한다.

Class: CL_GUI_DIALOGBOX_CONTAINER

3. SAP Docking Container - 스크린 영역의 각 모서리에 붙어서 크기를 조절할 수 있다, ALV에서 Custom Container와 같이 자주 쓰인다.

Class: CL_GUI_DOCKING_CONTAINER

4. SAP Splitter Container - 여러 영역으로 컨테이너를 분리할 때 사용한다.

Class: CL_GUI_SPLITTER_CONTAINER

5. SAP Easy Splitter Container - Splitter Container와 비슷한 역할을 하며, 분리된 영역을 상하 좌우로 1번 더 분리할 수 있다.

Class: CL_GUI_EASY_SPLITTER_CONTAINER

 

이 중 Custom Container와 Docking Container를 제일 많이 사용하며, Docking Container는 실무에서도 많이 사용하니 알아두시면 좋습니다.


이론은 어느정도 알았으니 실습의 결과를 먼저 보겠습니다.

* 작성된 내용에서 모든 것을 알려주진 않습니다.

생략되는 부분도 꽤 많고, 제가 정리하기 위해 작성한 글이기에 너무 맹신하지 않길 바랍니다. *

 

실습을 진행하기 위해선 먼저 컨테이너를 선언해서 사용하기 위해 컨테이너 참조 변수를 생성해야 합니다. 컨테이너 참조 변수 생성 구문은 다음과 같습니다.

DATA:
*  GO_CONT TYPE REF TO CL_GUI_CUSTOM_CONTAINER, " Container 관련 / 실습에선 선언하지 않습니다.
  GO_DOCK1 TYPE REF TO CL_GUI_DOCKING_CONTAINER, " Docking 관련
  GO_DOCK2 TYPE REF TO CL_GUI_DOCKING_CONTAINER, " Docking 관련
  GO_SPLIT TYPE REF TO CL_GUI_SPLITTER_CONTAINER, " Splitter 관련
  GO_TOP   TYPE REF TO CL_GUI_CONTAINER, " ALV 화면을 위, 아래로 나누기 위해 (위)
  GO_BOT   TYPE REF TO CL_GUI_CONTAINER, " ALV 화면을 위, 아래로 나누기 위해 (아래)
  GO_ALV1  TYPE REF TO CL_GUI_ALV_GRID, " ALV 관련
  GO_ALV2  TYPE REF TO CL_GUI_ALV_GRID, " ALV 관련
  GO_ALV3  TYPE REF TO CL_GUI_ALV_GRID, " ALV 관련

 

 

 

참조 변수를 생성했으면 스크린을 호출합니다. 스크린은 100번 스크린을 주로 사용합니다. 스크린 호출은 아래 구문을 사용합니다.

CALL SCREEN 100.

그리고 100번 스크린을 생성합니다. 생성된 100번 스크린의 레이아웃을 통해 적절한 크기의 Custom Control을 생성합니다.

생성이 완료되었으면 100번 스크린의 Flow Logic으로 이동하여 PBO 모듈에 init_alv 모듈을 추가합니다.

 

모듈 추가가 완료되었으면 모듈을 생성하고 IF <참조 변수 이름> IS INITIAL 구문 안에서 ABAP 프로그램의 Pattern 버튼을 통해 ALV 그리드 컨트롤을 생성합니다.

* IF <참조 변수 이름> IS INITIAL 구문안의 내용은 컨테이너 오브젝트가 한번 생성되었으면 다시 생성하지 않는다는 의미입니다.

 

사진은 Custom Container에 대한 오브젝트를 생성하는 것이지만, 다른 것들도 비슷합니다.

Instance에는 선언한 참조 변수 이름이, 아래에는 그에 맞는 클래스 이름이 오면 됩니다. 아래 예시처럼 말이지요.

ex) Instance: go_dock / Class: CL_GUI_DOCKING_CONTAINER


Custom Container는 스크린에서 영역을 지정하지만 Docking Container는 인스턴스를 생성할 때 직접 스크린과 크기를 결정합니다.

 

Docking Container를 호출하는 구문은 호출 후 다음과 같이 작성하시면 됩니다.

CREATE OBJECT GO_DOCK1
      EXPORTING
        REPID                       = SY-REPID
        DYNNR                       = SY-DYNNR
        SIDE                        = CL_GUI_DOCKING_CONTAINER=>DOCK_AT_LEFT
        EXTENSION                   = 500
      EXCEPTIONS
        CNTL_ERROR                  = 1
        CNTL_SYSTEM_ERROR           = 2
        CREATE_ERROR                = 3
        LIFETIME_ERROR              = 4
        LIFETIME_DYNPRO_DYNPRO_LINK = 5
        OTHERS                      = 6.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

 

이후 ALV 그리드 컨트롤을 호출합니다. 호출 후 구문 작성은 다음과 같습니다.

CREATE OBJECT GO_ALV1
      EXPORTING
        I_PARENT          = GO_DOCK1
      EXCEPTIONS
        ERROR_CNTL_CREATE = 1
        ERROR_CNTL_INIT   = 2
        ERROR_CNTL_LINK   = 3
        ERROR_DP_CREATE   = 4
        OTHERS            = 5.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

Splitter Container를 사용하면 ALV 그리드 화면을 분할할 수 있습니다.

Splitter Container 호출 구문은 다음과 같습니다.

CREATE OBJECT GO_SPLIT
      EXPORTING
        PARENT            = GO_DOCK2
        ROWS              = 2 " 행(가로) 갯수
        COLUMNS           = 1 " 열(세로) 갯수
      EXCEPTIONS
        CNTL_ERROR        = 1
        CNTL_SYSTEM_ERROR = 2
        OTHERS            = 3.
    IF SY-SUBRC <> 0.
      MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
                 WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

 

GO_SPLIT->GET_CONTAINER(
      EXPORTING
        ROW       = 1                 " Row
        COLUMN    = 1                 " Column
      RECEIVING
        CONTAINER = GO_TOP            " Container
    ).

    GO_SPLIT->GET_CONTAINER(
      EXPORTING
        ROW       = 2                " Row
        COLUMN    = 1                " Column
      RECEIVING
        CONTAINER = GO_BOT            " Container
    ).

2번째 ALV 화면을 상, 하 2개로 나누기 위해 ALV2에는 GO_TOP을, ALV3 부분에는 GO_BOT을 선언합니다.

CREATE OBJECT GO_ALV2
      EXPORTING
        I_PARENT          = GO_TOP
      EXCEPTIONS
        ERROR_CNTL_CREATE = 1
        ERROR_CNTL_INIT   = 2
        ERROR_CNTL_LINK   = 3
        ERROR_DP_CREATE   = 4
        OTHERS            = 5.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.
    
    CREATE OBJECT GO_ALV3
      EXPORTING
        I_PARENT          = GO_BOT
      EXCEPTIONS
        ERROR_CNTL_CREATE = 1
        ERROR_CNTL_INIT   = 2
        ERROR_CNTL_LINK   = 3
        ERROR_DP_CREATE   = 4
        OTHERS            = 5.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

전체 코드

DATA: GT_DATA TYPE TABLE OF YTREQMENU_C00,
      GS_DATA LIKE LINE OF GT_DATA.

DATA: GT_MENU TYPE TABLE OF SMENU,
      GS_MENU LIKE LINE OF GT_MENU.

DATA: GT_BOOK TYPE TABLE OF SBOOK,
      GS_BOOK LIKE LINE OF GT_BOOK.

DATA: OK_CODE TYPE SY-UCOMM.

DATA:
  GO_DOCK1 TYPE REF TO CL_GUI_DOCKING_CONTAINER,
  GO_DOCK2 TYPE REF TO CL_GUI_DOCKING_CONTAINER,
  GO_SPLIT TYPE REF TO CL_GUI_SPLITTER_CONTAINER,
  GO_TOP   TYPE REF TO CL_GUI_CONTAINER,
  GO_BOT   TYPE REF TO CL_GUI_CONTAINER,
  GO_ALV1  TYPE REF TO CL_GUI_ALV_GRID,
  GO_ALV2  TYPE REF TO CL_GUI_ALV_GRID,
  GO_ALV3  TYPE REF TO CL_GUI_ALV_GRID.

DATA: GS_LAYOUT TYPE LVC_S_LAYO.

SELECTION-SCREEN BEGIN OF BLOCK BLK1 WITH FRAME.
  SELECT-OPTIONS: SO_CAR FOR GS_DATA-CARRID NO INTERVALS DEFAULT 'AA',
                  SO_CON FOR GS_DATA-CONNID NO INTERVALS DEFAULT '0017',
                  SO_FDT FOR GS_DATA-FLDATE NO INTERVALS.
SELECTION-SCREEN END OF BLOCK BLK1.

START-OF-SELECTION.
  PERFORM GET_DATA.

  CALL SCREEN 100.
*&---------------------------------------------------------------------*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE STATUS_0100 OUTPUT.
  SET PF-STATUS 'S100'.
  SET TITLEBAR 'T100'.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Module CLEAR_OK_CODE OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE CLEAR_OK_CODE OUTPUT.
  CLEAR: OK_CODE.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Module INIT_ALV OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE INIT_ALV OUTPUT.

  IF GO_DOCK1 IS INITIAL.

    CREATE OBJECT GO_DOCK1
      EXPORTING
        REPID                       = SY-REPID
        DYNNR                       = SY-DYNNR
        SIDE                        = CL_GUI_DOCKING_CONTAINER=>DOCK_AT_LEFT
        EXTENSION                   = 500
      EXCEPTIONS
        CNTL_ERROR                  = 1
        CNTL_SYSTEM_ERROR           = 2
        CREATE_ERROR                = 3
        LIFETIME_ERROR              = 4
        LIFETIME_DYNPRO_DYNPRO_LINK = 5
        OTHERS                      = 6.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    CREATE OBJECT GO_ALV1
      EXPORTING
        I_PARENT          = GO_DOCK1
      EXCEPTIONS
        ERROR_CNTL_CREATE = 1
        ERROR_CNTL_INIT   = 2
        ERROR_CNTL_LINK   = 3
        ERROR_DP_CREATE   = 4
        OTHERS            = 5.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    CALL METHOD GO_ALV1->SET_TABLE_FOR_FIRST_DISPLAY
      EXPORTING
        I_STRUCTURE_NAME              = 'YTREQMENU_C00'
*       IS_LAYOUT                     =
      CHANGING
        IT_OUTTAB                     = GT_DATA
*       IT_FIELDCATALOG               =
      EXCEPTIONS
        INVALID_PARAMETER_COMBINATION = 1
        PROGRAM_ERROR                 = 2
        TOO_MANY_LINES                = 3
        OTHERS                        = 4.
    IF SY-SUBRC <> 0.
*     Implement suitable error handling here
    ENDIF.

    CREATE OBJECT GO_DOCK2
      EXPORTING
        REPID                       = SY-REPID
        DYNNR                       = SY-DYNNR
*       SIDE                        = CL_GUI_DOCKING_CONTAINER=>DOCK_AT_RIGHT
        EXTENSION                   = 500
      EXCEPTIONS
        CNTL_ERROR                  = 1
        CNTL_SYSTEM_ERROR           = 2
        CREATE_ERROR                = 3
        LIFETIME_ERROR              = 4
        LIFETIME_DYNPRO_DYNPRO_LINK = 5
        OTHERS                      = 6.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    CREATE OBJECT GO_SPLIT
      EXPORTING
        PARENT            = GO_DOCK2
        ROWS              = 2
        COLUMNS           = 1
      EXCEPTIONS
        CNTL_ERROR        = 1
        CNTL_SYSTEM_ERROR = 2
        OTHERS            = 3.
    IF SY-SUBRC <> 0.
      MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
                 WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    GO_SPLIT->GET_CONTAINER(
      EXPORTING
        ROW       = 1                 " Row
        COLUMN    = 1                 " Column
      RECEIVING
        CONTAINER = GO_TOP            " Container
    ).

    GO_SPLIT->GET_CONTAINER(
      EXPORTING
        ROW       = 2                " Row
        COLUMN    = 1                " Column
      RECEIVING
        CONTAINER = GO_BOT            " Container
    ).

    CREATE OBJECT GO_ALV2
      EXPORTING
        I_PARENT          = GO_TOP
      EXCEPTIONS
        ERROR_CNTL_CREATE = 1
        ERROR_CNTL_INIT   = 2
        ERROR_CNTL_LINK   = 3
        ERROR_DP_CREATE   = 4
        OTHERS            = 5.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    CALL METHOD GO_ALV2->SET_TABLE_FOR_FIRST_DISPLAY
      EXPORTING
        I_STRUCTURE_NAME              = 'SMENU'
*       IS_LAYOUT                     =
      CHANGING
        IT_OUTTAB                     = GT_MENU
*       IT_FIELDCATALOG               =
      EXCEPTIONS
        INVALID_PARAMETER_COMBINATION = 1
        PROGRAM_ERROR                 = 2
        TOO_MANY_LINES                = 3
        OTHERS                        = 4.
    IF SY-SUBRC <> 0.
*     Implement suitable error handling here
    ENDIF.

    CREATE OBJECT GO_ALV3
      EXPORTING
        I_PARENT          = GO_BOT
      EXCEPTIONS
        ERROR_CNTL_CREATE = 1
        ERROR_CNTL_INIT   = 2
        ERROR_CNTL_LINK   = 3
        ERROR_DP_CREATE   = 4
        OTHERS            = 5.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    CALL METHOD GO_ALV3->SET_TABLE_FOR_FIRST_DISPLAY
      EXPORTING
        I_STRUCTURE_NAME              = 'SBOOK'
*        IS_LAYOUT                     =
      CHANGING
        IT_OUTTAB                     = GT_BOOK
*        IT_FIELDCATALOG               =
      EXCEPTIONS
        INVALID_PARAMETER_COMBINATION = 1
        PROGRAM_ERROR                 = 2
        TOO_MANY_LINES                = 3
        OTHERS                        = 4.
    IF SY-SUBRC <> 0.
*      IMPLEMENT SUITABLE ERROR HANDLING HERE
     ENDIF.

    ENDIF.

ENDMODULE.
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE USER_COMMAND_0100 INPUT.

  DATA: LT_ROW TYPE LVC_T_ROID,
        LS_ROW TYPE LVC_S_ROID.

  CASE OK_CODE.
    WHEN 'BACK' OR 'EXIT' OR 'CANCEL'.
      LEAVE TO SCREEN 0.
    WHEN 'DET'.
      CALL METHOD GO_ALV1->GET_SELECTED_ROWS
        IMPORTING
          ET_ROW_NO = LT_ROW. " Numeric IDs of Selected Rows
      IF LINES( LT_ROW ) = 0.
        MESSAGE '데이터를 선택하여 주세요!' TYPE 'I'.
      ELSE.
        READ TABLE LT_ROW INTO LS_ROW INDEX 1.

        READ TABLE GT_DATA INTO GS_DATA INDEX LS_ROW-ROW_ID.
        PERFORM GET_DETAIL.
      ENDIF.
  ENDCASE.

ENDMODULE.
*&---------------------------------------------------------------------*
*& Form GET_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM GET_DATA .

  SELECT *
    INTO TABLE GT_DATA
    FROM YTREQMENU_C00
    WHERE CARRID IN SO_CAR
    AND CONNID IN SO_CON
    AND FLDATE IN SO_FDT.

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

  SELECT *
    INTO TABLE GT_MENU
    FROM SMENU
    WHERE CARRID = GS_DATA-CARRID.

    CALL METHOD GO_ALV2->SET_TABLE_FOR_FIRST_DISPLAY
      EXPORTING
        I_STRUCTURE_NAME              = 'SMENU'
      CHANGING
        IT_OUTTAB                     = GT_MENU
      EXCEPTIONS
        INVALID_PARAMETER_COMBINATION = 1
        PROGRAM_ERROR                 = 2
        TOO_MANY_LINES                = 3
        OTHERS                        = 4.
    IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*       WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    SELECT *
      INTO TABLE GT_BOOK
      FROM SBOOK
      WHERE CARRID = GS_DATA-CARRID.

      CALL METHOD GO_ALV3->SET_TABLE_FOR_FIRST_DISPLAY
        EXPORTING
          I_STRUCTURE_NAME              = 'Sbook'
        CHANGING
          IT_OUTTAB                     = GT_BOOK
        EXCEPTIONS
          INVALID_PARAMETER_COMBINATION = 1
          PROGRAM_ERROR                 = 2
          TOO_MANY_LINES                = 3
          OTHERS                        = 4.
      IF SY-SUBRC <> 0.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*       WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
      ENDIF.


ENDFORM.

'SAP > ABAP' 카테고리의 다른 글

ABAP. 8  (0) 2024.02.24
ABAP. 6  (1) 2024.02.12
ABAP. 5  (1) 2024.01.29
ABAP. 4  (1) 2024.01.27
ABAP. 3  (1) 2024.01.25