본문 바로가기

SAP ABAP 개발 및 설명/인사 마스터만들기

인사마스터 ALV 프로젝트 ver 2 (CLASS문)

CLASS 문


더보기

*이 프로그램에서는 이벤트는 ALV에서 발생시키고 이를 받는 리시버가 필요함.
*SE24는 글로벌 클래스이고 여기서 만드는 것은 LOCAL CLASS.
*CLASS는 DEFINITION과 IMPLEMENTATION 쌍으로 움직임.

*이름은 ABAP에서 제공하는 클래스인 CL/ 내가 전역으로 사용하려고 만드는 만드는 ZCL/ 로컬 프로그램에서만 사용하는 LCL로 보통 구분을 함.

CLASS lcl_event_receiver DEFINITION.
  PUBLIC SECTION.
    METHODS : handle_data_changed FOR EVENT data_changed OF cl_gui_alv_grid
      IMPORTING er_data_changed.

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


    METHODS : handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING e_object. 
      
    METHODS : HANDLE_USER_COMMAND 
      FOR EVENT USER_COMMAND OF CL_GUI_ALV_GRID
         IMPORTING  e_ucomm.

ENDCLASS.

CLASS lcl_event_receiver IMPLEMENTATION.

  METHOD : handle_data_changed.
  PERFORM handle_data_changed USING er_data_changed. 
  ENDMETHOD.

  METHOD : handle_toolbar. 
  PERFORM HANDLE_TOOLBAR USING E_OBJECT.
  ENDMETHOD.


  METHOD : HANDLE_USER_COMMAND.
  PERFORM HANDLE_USER_COMMAND USING E_UCOMM.
  ENDMETHOD.


ENDCLASS.


DATA : go_event_receiver TYPE REF TO lcl_event_receiver.

CLASS lcl_event_receiver DEFINITION.
PUBLIC SECTION.

 

"CL_GUI_ALV_GRID SE24에서 확인하면서 CL_GUI_ALV_GRUD의 이벤트 중 하나인 DATA_CHANGED에 대해서는 HANDLE_DATA_CHANGED로 받겠다는 의미.

 

METHODS handle_data_changed FOR EVENT data_changed OF cl_gui_alv_grid
IMPORTING er_data_changed. -> DATA_CHANGED의 파라미터중 보통 이것만을 사용함

 

METHODS handle_double_click FOR EVENT double_click OF cl_gui_alv_grid
IMPORTING e_row
                e_column
                es_row_no
.  -> 한줄 전체를 가지고 처리할 경우에는 이것을 사용 (파라미터가 ROW_ID)

*SE24에서 CL_GUI_ALV_GRID 중 TOOLBAR를 찾고 사용하기.
METHODS handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
IMPORTING e_object. -> Toolbar의 기능을 저장하는 테이블 타입의 오브젝트 -> e_object

METHODS HANDLE_USER_COMMAND
FOR EVENT USER_COMMAND OF CL_GUI_ALV_GRID
IMPORTING  e_ucomm.

ENDCLASS. "END - DEFINMITION"


CLASS lcl_event_receiver IMPLEMENTATION.

METHOD handle_data_changed.
PERFORM handle_data_changed USING er_data_changed. -> DEFINITION의 IMPORTING을 사용.
ENDMETHOD.

 

METHOD handle_double_click.
ENDMETHOD.

METHOD handle_toolbar"버튼을 생성하기 위해서 사용하는 TOOLBAR"

 

PERFORM HANDLE_TOOLBAR USING E_OBJECT.
->단 TOOLBAR만 만들었다고 되는것이 아니라 다시 클래스에 이것을 받을 수 있는 USER_COMMAND를 만들어서 처리할 수 있게 해야함"

ALV에서 기본적으로 제공하는 버튼을은 PBO와 PAI를 타지 않고 ALV상에서만 움직임.


하지만 내가 직접 툴바에 버튼을 생성해도 PBO를 기본적으로 타지 않기 때문에 용자가 임의로 버튼에 REFRESH 코드를 넣어주어서 PBO를 탈 수 있게 해줄 수 있음

>USER_COMMAND에서 해주는 작업.


METHOD HANDLE_USER_COMMAND. ->GRID 상에서 버튼을 누르는 것을 감지하는 이벤트를 만드는 것.

 

PERFORM HANDLE_USER_COMMAND USING E_UCOMM.

 

ENDMETHOD.
ENDCLASS



위의 클래스를 참조하는 변수 선언.
DATA : go_event_receiver TYPE REF TO lcl_event_receiver.

여기까지 해주었으면 CREATE OBJECT를 사용해야함. -> PBO의 스크린 세팅(SETTING_ALV_100.)에서 진행.


클래스 메소드 설명


FORM handle_data_changed  USING    P_ER_DATA_CHANGED TYPE REF TO CL_ALV_CHANGED_DATA_PROTOCOL.

DATA : LS_CHANGED TYPE LVC_S_MODI.
DATA : LV_TEXT TYPE dd07t-DDTEXT.


LOOP AT P_ER_DATA_CHANGED->MT_GOOD_CELLS INTO LS_CHANGED.


CASE LS_CHANGED-FIELDNAME.
    WHEN 'DEPT'.
    READ TABLE LT_DOMAIN WITH KEY domname = 'Z_DEPT08' domvalue_l = LS_CHANGED-VALUE.

    IF sy-subrc = 0.
    LV_TEXT = LT_DOMAIN-DDTEXT..
    ENDIF.



    CALL METHOD p_er_data_changed->modify_cell
      EXPORTING
         i_row_id    = LS_CHANGED-ROW_ID
         i_fieldname = 'DEPT_T'
         i_value     = LV_TEXT. 

    WHEN 'GRADE'.
    READ TABLE LT_DOMAIN WITH KEY domname = 'ZDGRADE08' domvalue_l = LS_CHANGED-VALUE.

    IF sy-subrc = 0.
    LV_TEXT = lt_domain-ddtext.
    ENDIF.

    CALL METHOD p_er_data_changed->modify_cell
    EXPORTING
        i_row_id    = LS_CHANGED-ROW_ID
        i_fieldname = 'GRADE_T'
        i_value     = LV_TEXT. 

    WHEN 'STATUS'.
    READ TABLE LT_DOMAIN WITH KEY domname = 'ZDSTATUS08' domvalue_l = LS_CHANGED-VALUE.

    IF sy-subrc = 0.
    LV_TEXT = lt_domain-ddtext.
    ENDIF.

    CALL METHOD p_er_data_changed->modify_cell
    EXPORTING
       i_row_id    = LS_CHANGED-ROW_ID
       i_fieldname = 'STATUS_T'
       i_value     = LV_TEXT. 

ENDCASE.


    CALL METHOD p_er_data_changed->modify_cell
    EXPORTING
      i_row_id    = LS_CHANGED-ROW_ID
      i_fieldname = 'STAT'
      i_value     = ICON_LED_YELLOW. 





ENDLOOP.

CLEAR LT_DOMAIN.

ENDFORM.

 

FORM handle_data_changed  USING    P_ER_DATA_CHANGED TYPE REF TO CL_ALV_CHANGED_DATA_PROTOCOL.

*P_ER_DATA_CHANGED의 MT_MOD_CELLS를 사용하면 DEPT, GRADE, STATUS의 ALV 상에서 값이 변화는 것을
*넘겨줄 뿐만 아니라 이와 관련하여 바뀌여야하는 DEPT_T, GRADE_T, STATUS_T의 변화 또한 마찬가지로 가지고 올 수 있다.


*대부분 이 방법을 사용하므로 익히는 것이 좋음.

*P_ER_DATA_CHANGED를 디버깅하면 가지고 있는 어트리뷰트 중
*그리드에서 바뀐 데이터에 대해서 MT_MOD_CELLS , MT_GOOD_CELLS라는 어트리뷰트가 가지고 있음을 확인할 수 있음.
*이 MT_*_CELLS는 인터널 테이블 형식이기 때문에 GRID에서 다수의 데이터를 변경해도 이를 다 가지고 있음.
*그렇기 때문에 이 모든 변경된 데이터를 처리하려면 루프문을 통해서 각각을 처리해주어야하고 이를 위해서는 같은 형식의 워크에어리어가 필요하다.

*MT_GOOD_CELLS의 타입은 LVC_T_MODI , LVC_S_MODI.

이를 이용해서 워크에어리어 생성.
DATA LS_CHANGED TYPE LVC_S_MODI.
DATA LV_TEXT TYPE dd07t-DDTEXT.

P_ER_DATA_CHANGED->MT_GOOD_CELLS가 인터널 테이.
"인스턴스의 어트리뷰트를 나타내주는 것이므로 아래 구문처럼 -> 을 사용"
"만약 앞이 클래스 형식이라면 클래스=>MY_GOOD_CELLS를 사용.

LOOP AT P_ER_DATA_CHANGED->MT_GOOD_CELLS INTO LS_CHANGED.

"LVC_S_MODI에 COMPONENT 중 FIELDNAME(타입 : LVC_FNAME)과 VALUE(타입 : LVC_VALUE)가 있음.
"이 중 VALUE가 의미하는 것은 사용자가 그리드에서 새로 입력한 데이터(밸류)를 포함하고 있음.

*CL_ALV_CHANGED_DATA_PROTOCOL라는 클래스 중에 MODIFY_CELL이라는 메소드가 있는데
*이 것을 사용하면 양 방향으로 수정 가능

 
CASE LS_CHANGED-FIELDNAME.
    
WHEN 'DEPT'"부서 변경"
  

1.부서명 조회
      
READ TABLE LT_DOMAIN WITH KEY domname 'Z_DEPT08' domvalue_l LS_CHANGED-VALUE.

      
IF sy-subrc 0.
      LV_TEXT 
LT_DOMAIN-DDTEXT..
      
ENDIF.


2.ALV에 반영
3.INTERNAL TABLE에 반영

 

2+3번을 MODIFY CELL이 해줄 수 있다"

*인스턴스  : P_ER_DATA_CHANGED / 클래스 : CL_ALV_CHANGED_DATA_PROTOCOL / METHOD : MODIFY_CELL.
   

CALL METHOD p_er_data_changed->modify_cell
      
EXPORTING
         i_row_id    
LS_CHANGED-ROW_ID
         i_fieldname 
'DEPT_T'
         i_value     
LV_TEXT"I_VALUE에서 요구하는 타입은 ANY이므로 무엇이든 넣을 수 있다.

    
WHEN 'GRADE'.
      
"1.부서명 조회"
      
READ TABLE LT_DOMAIN WITH KEY domname 'ZDGRADE08' domvalue_l LS_CHANGED-VALUE.

      
IF sy-subrc 0.
       LV_TEXT 
lt_domain-ddtext.
      
ENDIF.

      
CALL METHOD p_er_data_changed->modify_cell
      
EXPORTING
         i_row_id    
LS_CHANGED-ROW_ID
         i_fieldname 
'GRADE_T'
         i_value     
LV_TEXT"I_VALUE에서 요구하는 타입은 ANY이므로 무엇이든 넣을 수 있다.

    
WHEN 'STATUS'.


    
READ TABLE LT_DOMAIN WITH KEY domname 'ZDSTATUS08' domvalue_l LS_CHANGED-VALUE.

      
IF sy-subrc 0.
       LV_TEXT 
lt_domain-ddtext.
      
ENDIF.

      
CALL METHOD p_er_data_changed->modify_cell
       
EXPORTING
         i_row_id    
LS_CHANGED-ROW_ID
         i_fieldname 
'STATUS_T'
         i_value     
LV_TEXT"I_VALUE에서 요구하는 타입은 ANY이므로 무엇이든 넣을 수 있다.

ENDCASE.

상태창 변경하는 구문 변화가 있을때 STAT을 YELLOW_ICON으로 변경하기
      
CALL METHOD p_er_data_changed->modify_cell
       
EXPORTING
         i_row_id    
LS_CHANGED-ROW_ID
         i_fieldname 
'STAT'
         i_value     
ICON_LED_YELLOW"바뀐것에 대해서 YELLOW- ICON으로 변경하기
*        (i_value     = '@5D@'. 이렇게 해도 되는데 사용하지 않는 것을 권장)



ENDLOOP.
CLEAR LT_DOMAIN.
ENDFORM.

 

FORM HANDLE_toolbar  USING PO_object TYPE REF TO CL_ALV_EVENT_TOOLBAR_SET.

  DATA : LS_TOOLBAR TYPE STB_BUTTON. 

  IF SY-TCODE NE 'ZR08_0010_D'. 


  LS_TOOLBAR-function = 'CRTE'. 
  LS_TOOLBAR-ICON = ICON_CREATE.
  LS_TOOLBAR-TEXT = '사원등록'.

  APPEND LS_TOOLBAR TO PO_OBJECT->MT_TOOLBAR. 
  

  ENDIF.
ENDFORM.

FORM HANDLE_toolbar  USING PO_object TYPE REF TO CL_ALV_EVENT_TOOLBAR_SET.

  
DATA LS_TOOLBAR TYPE STB_BUTTON"툴바에서 필요한 버튼의 구조"

  
IF SY-TCODE NE 'ZR08_0010_D'. "T-CODE 생성했을 때  DISPLAY를 위한 T-CODE가 아니라면  'CRTE' 버튼을 생성해라.


  LS_TOOLBAR
-function 'CRTE'"CREATE 란 펑션"
  
LS_TOOLBAR-ICON ICON_CREATE.
  LS_TOOLBAR
-TEXT '사원등록'.

  
APPEND LS_TOOLBAR TO PO_OBJECT->MT_TOOLBAR. "내가 만든 버튼의 데이터를 PO_OBJECT 객체를 이용해서       MT_TOOLBAR로 넘겨라. "MT_TOOLBAR는 공통적인 요소"
  

  ENDIF.
ENDFORM.

 

 

 

FORM handle_user_command  USING p_e_ucomm. 
  

  CASE P_E_UCOMM.
    WHEN 'CRTE'.
     
    CLEAR GS_DISP.
      GS_DISP-STAT = ICON_LED_YELLOW. 
      GS_DISP-ENTDT = SY-DATUM. 
      GS_DISP-STATUS = '1'. 
      GS_DISP-WAERS = 'JPY'. 


   
    READ TABLE lt_domain WITH KEY domname = 'ZDSTATUS08'
                                  domvalue_l =  gs_DISP-STATUS.

    IF sy-subrc = 0.
    gs_DISP-STATUS_T = lt_domain-ddtext.
    ENDIF.

    APPEND GS_DISP TO GT_DISP. 

    PERFORM REFRESH_DATA. 


  ENDCASE.

ENDFORM.

FORM handle_user_command  USING p_e_ucomm

"U_UCOMM은 단일 변수이기 때문에 따로 타입을 안적어줘도 된다.
  

  CASE P_E_UCOMM.
    
WHEN 'CRTE'. "TOOLBAR에서 만든 ICON의 이름"
      
"아이콘입사일지위통화를 티폴트로 입력하기"


    
CLEAR GS_DISP.
      GS_DISP
-STAT ICON_LED_YELLOW. " 신규사원버튼을 입력했을 떄 상태표시를 노란색으로 표현"
      GS_DISP
-ENTDT SY-DATUM. "입사일은 현재날짜"
      GS_DISP
-STATUS '1'. "STATUS1QJS"
      GS_DISP
-WAERS 'JPY'. "통화는 JPY로 설정"


    
"재직구분 내역"
    
READ TABLE lt_domain WITH KEY domname 'ZDSTATUS08'
                                  domvalue_l 
=  gs_DISP-STATUS.

      
IF sy-subrc 0.
      gs_DISP
-STATUS_T lt_domain-ddtext.

      
ENDIF.

      
APPEND GS_DISP TO GT_DISP인터널 테이블에 추가"

PERFORM REFRESH_DATA"REFRESH 수행하여 추가된 줄이 ALV GRID에 뜨도록 보여준다.

 

"버튼을 눌르는 행동이 PBO를 타는지 아닌지에 대해서 디버깅을 수행해주면서 확인해야한다. 이 경우에는 PBO를 다시 타지 않기때문에 REFRESH를 통해 바뀐 인터널 테이블의 정보를 ALV로 가지고 와야한다.

  
ENDCASE.

ENDFORM.

반응형