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'. "STATUS는 1QJS"
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.
'SAP ABAP 개발 및 설명 > 인사 마스터만들기' 카테고리의 다른 글
인사마스터 ALV 프로젝트 ver 2 (PAI) (0) | 2020.10.10 |
---|---|
인사마스터 ALV 프로젝트 ver 2 (PBO) (0) | 2020.10.09 |
인사마스터 ALV 프로젝트 ver 2 (TOP문 , 메인프로그램) (0) | 2020.10.02 |
인사마스터 ALV 프로젝트 ver 1.3 (0) | 2020.09.17 |
인사마스터 ALV 프로젝트 ver 1.2 (0) | 2020.09.16 |