본문 바로가기
ABAP

ALV 2 (이벤트)

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

ALV 이벤트 생성하는 순서

  1. 핸들러를 생성한다. (데이터 선언)
  2. 인스턴스를 생성한다. (CREATE OBJECT)
  3. 이벤트를 등록한다. (SET HANDLER)
  4. ALV 출력한다. (CALL METHOD)

ALV 더블클릭, 툴바, 버튼제어, 핫스팟 이벤트를 구현해본다. 이전 게시물인 ALV 구현 로직에 이벤트를 추가한다.

[기존 프로그램 로직]

INCLUDE ZS1D11_028_TOP                          .    " Global Data
INCLUDE ZS1D11_028_O01                          .  " PBO-Modules
INCLUDE ZS1D11_028_I01                          .  " PAI-Modules
INCLUDE ZS1D11_028_F01                          .  " FORM-Routines


 INITIALIZATION.

AT SELECTION-SCREEN.

START-OF-SELECTION.
  PERFORM select_data.

END-OF-SELECTION.
    CALL SCREEN 100.

<TOP>

REPORT zs1d11_028 MESSAGE-ID zm11.

TABLES: zs1d11t_01.

DATA: ok_code TYPE sy-ucomm,
      gs_tab TYPE zs1d11t_01,
      gt_tab TYPE TABLE OF zs1d11t_01.

"alv관련 데이터 오브젝트
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.

SELECT-OPTIONS s_seqnr FOR zs1d11t_01-seqnr.

실행하면 순번값을 From ~ to 범위로 입력 할수 있는 선택 창은 SELECT-OPTIONS로 생성해준다. 이때 FOR 뒤에오는 테이블은 TABLES로 선언이 되어있어야 한다.


<화면 100>

레이아웃에서 컨테이너를 그려준다.

PROCESS BEFORE OUTPUT.
 MODULE STATUS_0100.
 MODULE SET_ALV.

PROCESS AFTER INPUT.
 MODULE EXIT AT EXIT-COMMAND.
   FIELD OK_CODE  MODULE USER_COMMAND_0100 ON INPUT.

<PBO>

MODULE status_0100 OUTPUT.
 SET PF-STATUS 'S100'.
 SET TITLEBAR 'S100'.
ENDMODULE.


MODULE set_alv OUTPUT.
  "PBO 모듈이 실행될때마다 실행되면 안되므로 한번만 실행되도록 제어함 
  "오브젝트 만들어져있는데 계속 만들면 오류나기 때문
  CHECK g_custom_con IS INITIAL.

  "화면 100에 생성한 컨테이너 참조해 오브젝트 생성
  CREATE OBJECT g_custom_con
    EXPORTING
       container_name = 'HD_CON'.

  "ALV_CON위에서 ALV 오브젝트 생성
  CREATE OBJECT g_alv
    EXPORTING
      i_parent = g_custom_con.


  "ALV 구성
  PERFORM make_fieldcat.    "필드카탈로그 수동 구성
  PERFORM sort.            "ALV 정렬
  PERFORM layo.             "ALV 레이아웃

  "EDIT 모드     (메소드 호출하기전에 넣어줘야함).
  CALL METHOD g_alv->set_ready_for_input
   EXPORTING
      i_ready_for_input = 1.  "1은 입력모드, 0은 조회모드

  "ALV 출력
         CALL METHOD g_alv->set_table_for_first_display "인스턴스명
           EXPORTING
*            i_structure_name              = 'ZS1D11T_01' "ALV의 구조가 ZS1D11T_01테이블의 구조로 실행된다, ALV구조 자동구성
             is_layout                     = gs_layo
           CHANGING
             it_outtab                     =  gt_tab "INT의 레코드 지칭, 헤더있는 INT선언시 []로 바디 표시
             it_fieldcatalog               = gt_fieldcat "필드 카탈로그
             it_sort                       = gt_sort "정렬
             .
ENDMODULE.

만약 수동으로 필드카탈로그를 구성하는게 아니라 자동으로 테이블 구조와 동일하게 alv를 구성한다고 하면 i_structure_name 주석을 풀고 '테이블 이름'을 입력해주면 테이블과 구조가 동일한 alv로 출력된다.


<PAI>

MODULE exit INPUT.
  CASE ok_code.
  WHEN 'EXIT' OR' CANC'.
    LEAVE PROGRAM.
  ENDCASE.
ENDMODULE.


MODULE user_command_0100 INPUT.
   CASE ok_code.
        WHEN 'BACK'.
    LEAVE TO SCREEN 0.
   ENDCASE.
ENDMODULE.

<FORM>

FORM select_data .
  SELECT * FROM zs1d11t_01
    INTO TABLE gt_tab
    WHERE seqnr IN s_seqnr.       "복수선택이니까 복수조건 in
ENDFORM.


FORM make_fieldcat .
  "ALV 수동구성
  gs_fieldcat-fieldname = 'SEQNR'.
  gs_fieldcat-coltext = '순번'. "필드헤더 텍스트
  gs_fieldcat-just = 'C'. "가운데정렬, L는 왼쪽정렬, R는 오른쪽정렬
  gs_fieldcat-key = 'X'. "키값 고정
  APPEND gs_fieldcat TO gt_fieldcat.  CLEAR: gs_fieldcat.

  gs_fieldcat-fieldname = 'TEAM'.
  gs_fieldcat-coltext = '조'.
  gs_fieldcat-just = 'C'.
  APPEND gs_fieldcat TO gt_fieldcat. CLEAR gs_fieldcat.

  gs_fieldcat-fieldname = 'NOTE'.
  gs_fieldcat-coltext = '비고1'.
  gs_fieldcat-just = 'L'.
  gs_fieldcat-edit = 'X'. "비고필드는 편집 가능하게
  APPEND gs_fieldcat TO gt_fieldcat. CLEAR gs_fieldcat.

ENDFORM.


FORM sort .
  "ALV 정렬
  "정렬시에 같은값의 셀은 병합되서 나온다.
  gs_sort-spos = 1. "정렬할 열 순서
  gs_sort-fieldname = 'SEQNR'.
  gs_sort-up = 'X'.     "오름차순, 내림차순은 DOWN = 'X'
  APPEND gs_sort TO gt_sort. CLEAR gs_sort.

  gs_sort-spos = 2.
  gs_sort-fieldname = 'TEAM'.
  gs_sort-up = 'X'.     "오름차순, 내림차순은 DOWN = 'X'
  APPEND gs_sort TO gt_sort. CLEAR gs_sort.

  gs_sort-spos = 3.
  gs_sort-fieldname = 'NOTE'.
  gs_sort-down = 'X'.     "오름차순, 내림차순은 DOWN = 'X'
  APPEND gs_sort TO gt_sort. CLEAR gs_sort.
ENDFORM.


FORM layo .
  "ALV 레이아웃 설정
  gs_layo-zebra = 'X'. "줄무늬 
  gs_layo-smalltitle = 'X'.
  gs_layo-cwidth_opt = 'X'. "너비 최적화
  gs_layo-no_merging = 'X'. "셀병합 불가능
ENDFORM.

Double click

[ 더블클릭 이벤트 프로그램 로직 ]

화면100의 ALV에서 순번 필드를 더블클릭했을때 해당하는 순번의 팀원정보 데이터를 ALV로 출력하는 화면 200을 나타나게 한다. 팀원정보테이블은 ZS1D11T_02이다.


<TOP>

"화면 200(더블클릭)에서 사용할 변수 선언 
DATA:     gs_tab2 TYPE zs1d11t_02,
          gt_tab2 TYPE TABLE OF zs1d11t_02.

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_layo2 TYPE lvc_s_layo,          "레이아웃 옵션
          gs_sort2 TYPE lvc_s_sort,           "정렬
          gt_sort2 TYPE lvc_t_sort,
          gs_functions2 TYPE ui_functions.

  FIELD-SYMBOLS : <fcat> TYPE lvc_t_fcat.

"클래스 정의부분 
CLASS lcl_event DEFINITION.
 PUBLIC SECTION. "접근성 제어, 다른프로그램에서 접근가능

   METHODS : handler_double_click
             FOR EVENT double_click OF cl_gui_alv_grid
             IMPORTING e_row e_column  es_row_no.
ENDCLASS.              

"클래스 구현부분
CLASS lcl_event IMPLEMENTATION. 

  METHOD handler_double_click.
    PERFORM double_click_0100  USING e_row e_column.
  ENDMETHOD.                
ENDCLASS.   

DATA : g_application TYPE REF TO lcl_event.

핸들러를 생성하기 위해 클래스를 참조하는 변수 G_APPLICATION을 선언해준다. 핸들러를 등록할때 사용한다.

<FORM>

FORM double_click_0100  USING    p_row   p_column.
    DATA : l_message(80).

  "더블클릭으로 선택된 줄 값 읽어오기
  READ TABLE gt_tab INTO gs_tab INDEX p_row. "p_row가 더블클릭한 줄 들어가고
                                             "p_cloumn에 더블클릭한 seqnr 들어간다

  CHECK sy-subrc = 0.

  SELECT * FROM zs1d11t_02
    INTO TABLE gt_tab2
    WHERE seqnr = gs_tab-seqnr.

    CALL SCREEN 200 STARTING AT 5 5 ENDING AT 95 55.

ENDFORM.

화면은 창으로 띄우기 위해 크기를 지정해서 CALL SCREEN 해준다.


<화면200>

화면 200을 생성해 더블클릭했을때 나타날 화면을 만들어준다. 화면에는 컨테이너를 그려준다.

PROCESS BEFORE OUTPUT.
 MODULE status_0200.
 MODULE set_alv2.

PROCESS AFTER INPUT.
MODULE exit AT EXIT-COMMAND.
 MODULE user_command_0200.

<PBO>

MODULE status_0200 OUTPUT.
 SET PF-STATUS 'S200'.
 SET TITLEBAR 'S200'.
ENDMODULE.


MODULE set_alv2 OUTPUT.
  IF  g_custom_con2 IS INITIAL.
  "화면 200에 생성한 컨테이너 참조해 오브젝트 생성
  CREATE OBJECT g_custom_con2
    EXPORTING
       container_name = 'HD_CON2'.

  "ALV_CON2위에서 ALV 오브젝트2 생성
  CREATE OBJECT g_alv2
    EXPORTING
      i_parent = g_custom_con2.

*  ALV 출력
         CALL METHOD g_alv2->set_table_for_first_display "인스턴스명
           EXPORTING
             i_structure_name              = 'ZS1D11T_02' "ALV의 구조가 ZS1D11T_01테이블의 구조로 실행
           CHANGING
             it_outtab                     =  gt_tab2 "INT의 레코드 지칭
                  .

*  인터널테이블 값 변경되면 화면 갱신해서 보여주도록
   ELSE.
     CALL METHOD g_alv2->refresh_table_display.
     CALL METHOD cl_gui_cfw=>flush.
 ENDIF.
ENDMODULE.

GUI STATUS는 대화상자로 생성해준다. 별다른 버튼없이 창을 닫을 수 있는 버튼만 있으면 되기 때문.

200의 ALV는 필드카탈로그로 구조를 수동 구성하지 않고 전체를 보여주도록 I_STRUCTURE_NAME에 팀원정보 테이블 이름을 입력해준다. GT_TAB2의 값이 변경되면 변경된 값을 보여줄수 있도록 REFRESH도 해준다.

<PBO> 핸들러 등록

화면100의 ALV에서 일어나는 이벤트기때문에 화면100의 MODULE set_alv OUTPUT에 핸들러를 등록하는 로직을 추가한다.

  CREATE OBJECT g_application.
  SET HANDLER g_application->handler_double_click FOR g_alv. "g_alv 그리드안에서 이벤트 발생했는지 감시하겠다

g_alv 그리드안에서 이벤트가 발생했는지 감지하는 핸들러를 등록해준다. alv를 출력하는 로직 이전에 넣어준다.

[실행화면]


Tool bar, 버튼제어

[ 툴바제어 프로그램 로직 ]


<TOP>

CLASS lcl_event DEFINITION.
 METHODS : handler_toolbar
           FOR EVENT toolbar OF cl_gui_alv_grid "여기에 정의되어있는 toolbar의 매개변수가
           IMPORTING e_object e_interactive. "이렇게 두개가 있음, 똑같이 맞춰줘야한다
 METHODS : handler_user_command
           FOR EVENT user_command OF cl_gui_alv_grid
           IMPORTING e_ucomm.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION. 
  METHOD handler_toolbar. "툴바
    PERFORM toolbar_set USING e_object e_interactive.
  ENDMETHOD.
    METHOD handler_user_command. "버튼제어
    PERFORM user_command_grid USING e_ucomm.
  ENDMETHOD.             
ENDCLASS.

더블클릭 이벤트와 마찬가지로 클래스 정의부와 구현부에 메소드를 선언한다.

정의부 메소드의 IMPORTING은 CL_GUI_ALV_GRID의 이벤트에 TOOLBAR가 가지고 있는 필드를 맞춰주는거다.

버튼제어 유저커맨드는 gui status에서 버튼 만들어서 pai에 로직 구현하는것처럼 alv에서 버튼을 누르면 grid안에서 일어나는 이벤트가 되기때문에 pai가 아닌 유저커맨드 이벤트를 만들어준다.


<FORM>

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 'BUT2'            TO ls_toolbar-function. "INT에 APPEND
  MOVE icon_display_text TO ls_toolbar-icon.
  MOVE '버튼 2'          TO ls_toolbar-quickinfo.
  MOVE '버튼 2'          TO ls_toolbar-text.
  MOVE ' '               TO ls_toolbar-disabled.
  APPEND ls_toolbar TO r_object->mt_toolbar.
ENDFORM.

ALV 기본 툴바에 버튼2 버튼을 추가로 만들어준다. ALV 툴바가 아닌 기존에는 GUI STATUS에서 버튼을 생성해줬지만 툴바 버튼은 GRID안에서 일어나는 이벤트기 때문에 클래스 안에서 구현해줘야 한다.

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

  CASE r_ucomm.
    WHEN 'BUT2'.
*     현재 선택되어 있는 row_id를 구함.
      CALL METHOD g_alv->get_selected_rows
        IMPORTING
          et_index_rows = lt_rows. "alv에서 선택된 라인이 it_rows에 들어간다.

      DESCRIBE TABLE lt_rows LINES sy-tfill.

      IF sy-tfill = 0.
        MESSAGE i000 WITH '항목을 선택하세요'.
        EXIT.
      ELSE.
        MESSAGE i000 WITH '버튼 2 클릭'.
    ENDIF.

  ENDCASE.
ENDFORM.

항목을 아무것도 선택하지 않고 버튼을 누르면 항목을 선택하라는 메세지가 나오고, 항목을 선택한뒤 버튼을 누르면 버튼2 클릭이라는 메세지가 출력된다.

툴바 버튼의 기능을 수행하는 로직은 여기다가 입력하면 된다. 버튼 클릭시 저장을 한다던지.. 하면 MODIFY 구문은 여기다 하면 됨!


<PBO> 핸들러 등록

화면100의 MODULE set_alv OUTPUT

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

마찬가지로 ALV를 출력하는 구문 전에 넣어줘야한다. 이전에 입력했던 CREATE OBJECT 구문 다음에 넣어주면 된다.

[실행 화면]


HOT SPOT

더블클릭은 두번 클릭하지만 핫스팟은 한번 클릭했을때 이벤트를 실행하는 기능이다. 그리고 핫스팟을 설정할 필드 항목을 카탈로그에서 지정해주어야 한다.

[ 핫스팟 프로그램 로직 ]


<TOP>

CLASS lcl_event DEFINITION.
    METHODS : handler_hotspot_click
              FOR EVENT hotspot_click OF cl_gui_alv_grid
              IMPORTING e_row_id  e_column_id es_row_no.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION. 
  METHOD handler_hotspot_click.
   PERFORM HOTSPOT_CLICK USING E_ROW_ID E_COLUMN_ID.
  ENDMETHOD.              
ENDCLASS.

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


<FORM>

FORM hotspot_click  USING p_row_id p_column_id.
  DATA : l_col(40).
  FIELD-SYMBOLS <fs>.

  DATA : l_message(20).
  READ TABLE gt_tab INTO gs_tab INDEX p_row_id.

  CHECK sy-subrc = 0.

  CONCATENATE 'GS_TAB-' p_column_id  INTO l_col.
  ASSIGN      (l_col)         TO       <fs>.

  CHECK NOT <fs> IS INITIAL.

  CASE p_column_id.
    WHEN 'TEAM'.   
      CONCATENATE <fs> '조' INTO l_message.
      MESSAGE i000 WITH l_message.
  ENDCASE.

ENDFORM.

조 항목을 클릭했을때 클릭한 필드의 값과 라는 텍스트를 합쳐서 메세지로 출력한다.


<PBO> 핸들러 등록

화면100의 MODULE set_alv OUTPUT

  SET HANDLER g_application->handler_hotspot_click FOR g_alv.

<FIELD CATALOG>

필드에 핫스팟을 구현해줄거기 때문에 필드카탈로그의 TEAM에 핫스팟 기능을 추가해준다.

  gs_fieldcat-fieldname = 'TEAM'.
  gs_fieldcat-coltext = '조'.
  gs_fieldcat-just = 'C'.
  gs_fieldcat-hotspot = 'X'. "핫스팟
  APPEND gs_fieldcat TO gt_fieldcat. CLEAR gs_fieldcat.

[실행 화면]

728x90
반응형

'ABAP' 카테고리의 다른 글

ALV 4 (Layout)  (0) 2023.02.16
ALV 3 (Hotspot)  (0) 2023.02.16
ALV  (0) 2023.02.16
엑셀 업로드 + BDC  (0) 2023.02.16
엑셀 업로드  (2) 2023.02.16

댓글