본문 바로가기
ABAP

ALV 7

by clode 2023. 2. 16.
728x90
반응형

Spec.

조회조건과 일치하는 데이터를 ALV로 출력한뒤 항목 선택 후 예약정보 버튼 클릭시 팝업으로 예약정보를 뜨게 한다. 항공편 일자는 현재 날짜로부터 3년전까지의 데이터만 가져오게 초기값을 설정한다.

실행화면

항공사코드와 항공편 일자는 초기값을 지정한다. 항공편 일자는 현재날짜 기준으로 3년전.

아무항목을 선택하지 않고 예약정보 버튼을 누르면

항목을 선택하라는 메세지가 나온다. 항목을 선택후 버튼을 다시 누르면

해당하는 예약정보 팝업창이 뜬다. 테이블에 해당하는 데이터가 없어서 아무것도 뜨지 않는다

있는 데이터는 잘가져와서 잘 뜬다!

조회조건

1. SELECTION-SCREEN 조회조건 생성

TABLES: sflight.

SELECT-OPTIONS에 사용하는 필드는 TABLES로 선언이 되어야한다. 구조를 사용하기 때문인데 TABLES로 선언하면 테이블과 이름이 똑같은 구조가 선언된다.

SELECTION-SCREEN BEGIN OF BLOCK b1.
PARAMETERS: p_carrid TYPE sflight-carrid OBLIGATORY DEFAULT 'AA'. "필수값

SELECT-OPTIONS: s_connid FOR sflight-connid,
                s_fldate FOR sflight-fldate NO-EXTENSION.

PARAMETERS: p_count TYPE spfli-countryfr.
SELECTION-SCREEN END OF BLOCK b1.

2. 항공편 일자 초기값 설정

SELECTION-SCREEN 초기값은 INITIALIZATION에서 구현한다.

INITIALIZATION.     
  PERFORM INIT.

가독성을 위해 FORM문으로 빼준다.

FORM init .
  DATA: lv_date TYPE p0001-begda.

  CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
    EXPORTING
      date      = sy-datum
      days      = 0
      months    = 0
      signum    = '-'
      years     = 3
    IMPORTING
      calc_date = lv_date.

  s_fldate-sign = 'I'.
  s_fldate-option = 'BT'. "BETWEEN
  s_fldate-low = lv_date.
  s_fldate-high = sy-datum.
  APPEND s_fldate. CLEAR s_fldate.
ENDFORM.

예약정보 ALV

3. 화면100 ALV관련 데이터 선언

예약정보를 ALV로 뿌려줄 화면 100을 생성하고 컨테이너를 그려준다.

DATA:   BEGIN OF gs_tab,
        carrid    TYPE sflight-carrid,
        carrname  TYPE scarr-carrname,
        connid    TYPE sflight-connid,
        fldate    TYPE sflight-fldate,
        currency  TYPE sflight-currency,
        countryfr TYPE spfli-countryfr,
        cityfrom  TYPE spfli-cityfrom,
        airpfrom  TYPE spfli-airpfrom,
        cityto    TYPE spfli-cityto,
        airpto    TYPE spfli-airpto,
        fltime    TYPE spfli-fltime,
        deptime   TYPE spfli-deptime,
        END OF gs_tab,
        gt_tab LIKE TABLE OF gs_tab.

DATA: g_alv         TYPE REF TO cl_gui_alv_grid,
      g_custom_con  TYPE REF TO cl_gui_custom_container.

DATA: gs_fieldcat  TYPE lvc_s_fcat,
      gt_fieldcat  TYPE lvc_t_fcat,
      gs_layo      TYPE lvc_s_layo,
      gs_sort      TYPE lvc_s_sort,
      gt_sort      TYPE lvc_t_sort,
      gs_functions TYPE ui_functions,
      gs_refto     TYPE REF TO data,
      gs_pos       TYPE i.

ALV에 뿌려줄 데이터를 담을 구조와 인터널테이블, ALV관련 데이터를 선언해준다. 스펙과 동일한 구조를 가지게 하기 위해 직접 다 쳤다.

4. 데이터 SELECT

ALV로 뿌려줄 인터널테이블에 데이터를 SELECT해준다. 실행한뒤 나타내기 때문에 START-OF-SELECTION에 구현해준다.

START-OF-SELECTION.     
  PERFORM select_data.
FORM select_data .
  DATA: lt_scarr TYPE TABLE OF scarr,
        ls_scarr TYPE scarr.

  IF p_count IS INITIAL.
    SELECT * FROM sflight AS a INNER JOIN spfli AS b
        ON a~carrid = b~carrid
      INTO CORRESPONDING FIELDS OF TABLE gt_tab
     WHERE a~carrid = p_carrid
       AND a~connid IN s_connid
       AND a~fldate IN s_fldate.
  ELSE.
    SELECT * FROM sflight AS a INNER JOIN spfli AS b
        ON a~carrid = b~carrid
      INTO CORRESPONDING FIELDS OF TABLE gt_tab
     WHERE a~carrid = p_carrid
       AND a~connid IN s_connid
       AND a~fldate IN s_fldate
       AND b~countryfr = p_count.
  ENDIF.

  SELECT * FROM scarr
    INTO TABLE lt_scarr
     FOR ALL ENTRIES IN gt_tab
   WHERE carrid = gt_tab-carrid.

  LOOP AT gt_tab INTO gs_tab.
    *항공사 이름 가져오기
    READ TABLE lt_scarr INTO ls_scarr
    WITH KEY carrid = gs_tab-carrid.
    IF sy-subrc = 0.
      gs_tab-carrname = ls_scarr-carrname.
    ENDIF.
    MODIFY gt_tab FROM gs_tab. CLEAR gs_tab.
  ENDLOOP.

ENDFORM.

4. 컨테이너 생성

화면100의 PBO에 MODULE CREATE_CONTAINER를 입력후 생성해준다.

MODULE create_container OUTPUT.
  CHECK g_custom_con IS INITIAL.

  CREATE OBJECT g_custom_con
    EXPORTING
      container_name = 'HD_CON'.

5. 컨테이너 컨트롤 생성

  CREATE OBJECT g_alv
    EXPORTING
      i_parent = g_custom_con.

6. ALV 출력

  PERFORM make_fieldcat.

  CALL METHOD g_alv->set_table_for_first_display
    EXPORTING
      is_layout       = gs_layo
    CHANGING
      it_outtab       = gt_tab
      it_fieldcatalog = gt_fieldcat
      it_sort         = gt_sort.

필드카탈로그를 수동으로 구성해줄거기 때문에 IT_FIELDCATALOG를 사용한다. 레이아웃과 정렬은 선택사항인데 난 해줬다 보기 좋게 !!

7. 필드카탈로그 구성

  gs_fieldcat-fieldname = 'CARRID'.
  gs_fieldcat-coltext = '항공사코드'.
  gs_fieldcat-just = 'C'.
  APPEND gs_fieldcat TO gt_fieldcat.  CLEAR: gs_fieldcat.

  gs_fieldcat-fieldname = 'CARRNAME'.
  gs_fieldcat-coltext = '항공사이름'.
  gs_fieldcat-just = 'C'.
  APPEND gs_fieldcat TO gt_fieldcat.  CLEAR: gs_fieldcat.

  gs_fieldcat-fieldname = 'CONNID'.
  gs_fieldcat-coltext = '항공편 연결번호'.
  gs_fieldcat-just = 'C'.
  APPEND gs_fieldcat TO gt_fieldcat.  CLEAR: gs_fieldcat.

  gs_fieldcat-fieldname = 'FLDATE'.
  gs_fieldcat-coltext = '항공편 일자'.
  gs_fieldcat-just = 'C'.
  APPEND gs_fieldcat TO gt_fieldcat.  CLEAR: gs_fieldcat.

.
.
.

ENDFORM.

8. 저장버튼 클릭시 화면 REFRESH

화면100의 PAI에 로직을 추가한다.

  CASE ok_code.
    WHEN 'SAVE'.
      MESSAGE i000 WITH '클릭'.
      PERFORM refresh_grid.
  ENDCASE.

FORM문

FORM refresh_grid .
  DATA: l_scroll TYPE lvc_s_stbl. "최신표시
  l_scroll-row = 'X'.
  l_scroll-col = 'X'.
  CALL METHOD g_alv->refresh_table_display
    EXPORTING
      i_soft_refresh = ''
      is_stable      = l_scroll.
ENDFORM.

예약정보 팝업 ALV

예약정보 팝업 ALV를 뿌려줄 화면 200을 생성하고 컨테이너를 그려준다. 이때 화면200은 팝업이기때문에 GUI STATUS는 상태유형은 대화상자로 지정한다. 대화상자는 창닫기버튼이 활성화 되어있다.

9. 예약정보 버튼 생성

ALV툴바에 버튼을 만들어주는거라 CLASS의 툴바메소드를 사용한다.

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.

    METHODS : handler_toolbar
                  FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING e_object e_interactive
ENDCLASS.   

CLASS lcl_event IMPLEMENTATION. "구현부분
  METHOD handler_toolbar.
    PERFORM toolbar_set USING e_object e_interactive.
  ENDMETHOD.                   
ENDCLASS. 

DATA : g_application TYPE REF TO lcl_event.
FORM toolbar_set USING r_object TYPE REF TO cl_alv_event_toolbar_set
                       r_interactive.

  DATA : ls_toolbar  TYPE stb_button.

  CLEAR ls_toolbar.
  MOVE 3                 TO ls_toolbar-butn_type.
  APPEND ls_toolbar      TO r_object->mt_toolbar.

  CLEAR ls_toolbar.
  MOVE 'DISP'            TO ls_toolbar-function.
  MOVE icon_display_text TO ls_toolbar-icon.
  MOVE '예약정보'          TO ls_toolbar-quickinfo.
  MOVE '예약정보'          TO ls_toolbar-text.
  MOVE ' '               TO ls_toolbar-disabled.
  APPEND ls_toolbar TO r_object->mt_toolbar.

ENDFORM.

이 버튼을 눌렀을때 수행하는 로직은 유저커맨드 메소드로 또 다른 메소드를 사용해야한다.

10. 예약정보 버튼 이벤트

클래스의 정의부와 구현부에 메소드를 등록한다.

"정의부
    METHODS : handler_user_command
              FOR EVENT user_command OF cl_gui_alv_grid
              IMPORTING e_ucomm.

"구현부
    METHOD handler_user_command.
    PERFORM user_command_grid USING e_ucomm.
  ENDMETHOD.   

항목을 선택한뒤 예약정보 버튼을 누르면 어떤 라인을 사용자가 선택했는지 프로그램에서 라인번호를 구하고 그 라인번호와 일치하는 인터널테이블의 항목의 데이터를 가져와야한다.

FORM user_command_grid  USING r_ucomm.
  DATA : lt_rows TYPE lvc_t_row,  " ALV 제어: 테이블행
         ls_rows TYPE lvc_s_row.

  CASE r_ucomm.
    WHEN 'DISP'.     
   *현재 선택되어 있는 row_id를 구함.
      CALL METHOD g_alv->get_selected_rows
        IMPORTING
          et_index_rows = lt_rows.

      DESCRIBE TABLE lt_rows LINES sy-tfill.

      IF sy-tfill = 0. "항목을 아무것도 선택하지 않았을때
        MESSAGE s000 WITH '항목을 선택하세요'.
        EXIT.
      ELSEIF sy-tfill = 1. "항목을 선택해서 SY-TFILL에 값이 들어가면
        READ TABLE lt_rows INTO ls_rows INDEX 1.
        IF sy-subrc = 0.
          READ TABLE gt_tab INTO gs_tab INDEX ls_rows-index. "선택한줄을 GS_TAB에 넣는다
          IF sy-subrc = 0.
            SELECT * FROM sbook as a
              INNER JOIN sflight as b
              on a~carrid = b~carrid
              INNER JOIN scarr as c
              on a~carrid = c~carrid
              INTO CORRESPONDING FIELDS OF TABLE gt_tab2
             WHERE a~carrid = gs_tab-carrid
               AND a~connid = gs_tab-connid
               AND a~fldate = gs_tab-fldate.

            CALL SCREEN 200 STARTING AT 5 5
            ENDING AT 100 25.
          ENDIF.
        ENDIF.

      ELSEIF sy-tfill > 1. "여러건 선택시, 한건만 선택할수 있도록
        MESSAGE i000 WITH '한 건만 선택하세요'.
        EXIT.
      ENDIF.
  ENDCASE.

ENDFORM.

이후 버튼을 눌렀을때 화면 200을 불러온다.

11. HANDLER 등록

이벤트가 발생했는지 감지하는 핸들러를 꼭!!! 등록해줘야 프로그램이 이벤트가 발생했는지를 알고 이벤트 로직을 탄다.

  CREATE OBJECT g_application.
  SET HANDLER g_application->handler_toolbar FOR g_alv.
  SET HANDLER g_application->handler_user_command FOR g_alv.

핸들러는 ALV출력하는 로직 전에 넣어줘야한다.


12. 화면200 ALV관련 데이터 선언

DATA: BEGIN OF gs_tab2,
        carrid     TYPE sflight-carrid,
        carrname   TYPE scarr-carrname,
        connid     TYPE    sflight-connid,
        fldate     TYPE    sflight-fldate,
        bookid     TYPE    sbook-bookid,
        customid   TYPE    sbook-customid,
        custtype   TYPE    sbook-custtype,
        smoker     TYPE    sbook-smoker,
        luggweight TYPE    sbook-luggweight,
        wunit      TYPE  sbook-wunit,
        forcuram   TYPE sbook-forcuram,
        forcurkey  TYPE  sbook-forcurkey,
        loccuran   TYPE    sbook-loccuram,
        loccurkey  TYPE  sbook-loccurkey,
        order_date TYPE    sbook-order_date,
      END OF gs_tab2,
      gt_tab2 LIKE TABLE OF gs_tab2.

DATA:  g_alv2        TYPE REF TO cl_gui_alv_grid,
       g_custom_con2 TYPE REF TO cl_gui_custom_container.

DATA: gs_fieldcat2  TYPE lvc_s_fcat,
      gt_fieldcat2  TYPE lvc_t_fcat,
      gs_functions2 TYPE ui_functions.

13. 컨테이너 생성

화면100의 PBO에 MODULE CREATE_CONTAINER를 입력후 생성해준다.

MODULE create_container2 OUTPUT.

  IF  g_custom_con2 IS INITIAL.

    CREATE OBJECT g_custom_con2
      EXPORTING
        container_name = 'HD_CON2'.

14. 컨테이너 컨트롤 생성

    CREATE OBJECT g_alv2
      EXPORTING
        i_parent = g_custom_con2.

15. ALV 출력

  PERFORM make_fieldcat2.

    CALL METHOD g_alv2->set_table_for_first_display 
      CHANGING
        it_outtab       = gt_tab2 
        it_fieldcatalog = gt_fieldcat2 

필드카탈로그를 수동으로 구성해줄거기 때문에IT_FIELDCATALOG를 사용한다.


16. 필드카탈로그 구성

이번엔 화면100과 다르게 필드심볼을 사용해 구성해본다.

  CLEAR   : gt_fieldcat.
  REFRESH : gt_fieldcat.

  GET REFERENCE OF gt_fieldcat INTO gs_refto.
  ASSIGN gs_refto->* TO <fcat>.

  PERFORM fill_field_catalogs USING :
'S'   'FIELDNAME'   'CARRID',
' '   'JUST'        'C',
' '   'KEY'         'X',
'E'   'COLTEXT'     '항공사코드',

'S'   'FIELDNAME'   'CARRNAME',
' '   'JUST'        'C',
' '   'KEY'         'X',
'E'   'COLTEXT'     '항공사이름',

'S'   'FIELDNAME'   'CONNID',
' '   'JUST'        'C',
' '   'KEY'         'X',
'E'   'COLTEXT'     '항공편 연결번호',

.
.
.
.

FORM문

FORM fill_field_catalogs  USING p_gub
                                p_fname
                                p_value.
  DATA l_fname(40).
  FIELD-SYMBOLS <fany> TYPE any.

  IF p_gub = 'S'.
    CLEAR gs_fieldcat2.
  ENDIF.

  CONCATENATE 'GS_FIELDCAT2-' p_fname INTO l_fname.

  ASSIGN (l_fname) TO <fany>.
  <fany> = p_value.
  IF p_gub = 'E'.
    gs_pos              = gs_pos + 1.
    gs_fieldcat2-col_pos = gs_pos.
    APPEND gs_fieldcat2 TO <fcat>.
  ENDIF..

ENDFORM.

17. 화면 갱신 REFRESH

인터널테이블 값 변경되면 화면 갱신해서 보여주도록 컨테이너 생성하는 IF문에 ELSE로 REFRESH구문을 추가한다.

 ELSE.
     CALL METHOD g_alv2->refresh_table_display.
     CALL METHOD cl_gui_cfw=>flush.
  ENDIF.
ENDMODULE.
728x90
반응형

'ABAP' 카테고리의 다른 글

Simple Tree 2  (0) 2023.02.20
Simple Tree  (0) 2023.02.20
ALV 6 (필드카탈로그 구성)  (0) 2023.02.16
ALV 5 (SPLIT)  (0) 2023.02.16
ALV 4 (Layout)  (0) 2023.02.16

댓글