메뉴 건너뛰기

SAP 한국 커뮤니티

ALV 내용 변경 방법.

초보보초보 2007.02.07 13:48 조회 수 : 8924 추천:62

Step 1. 관련된 변수 선언

* 필요한 변수만 모았습니다.
TYPE-POOLS slis.

CONSTANTS : gc_data_changed TYPE slis_formname VALUE 'ALV_DATA_CHANGED'.

DATA : gs_selfield TYPE slis_selfield.
DATA : gt_fieldcat TYPE slis_t_fieldcat_alv,
gt_events TYPE slis_t_event,
gs_gridset TYPE lvc_s_glay.


* 예를 들어서 상품코드가 바뀔때 상품명이 바뀌고 특정 플래그가 'X'가 되는
경우 입니다.
* 전체를 입력모드로 하는 것이 아니고 MATNR 필드만 입력가능하게 합니다.
* 필드의 속성을 수정이 가능하도록 합니다.
FORM set_fieldcat .

CLEAR gt_fieldcat[].
PERFORM make_fieldcat USING :

........
기타 등등
........

'S' 'FIELDNAME' 'MATNR',
' ' 'OUTPUTLEN' '18',
' ' 'EDIT' 'X', < -----
'E' 'SELTEXT_L' '상품코드',

'S' 'FIELDNAME' 'TEXT',
' ' 'OUTPUTLEN' '30',
'E' 'SELTEXT_L' '상품DESC',

........
기타 등등
........

ENDFORM.

* 이부분은 거의 표준(?) 이죠...
FORM make_fieldcat USING p_gub p_fname p_con.

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

DATA l_col(40).
FIELD-SYMBOLS <fs>.
CONCATENATE 'GS_FIELDCAT-' p_fname INTO l_col.
ASSIGN (l_col) TO <fs>.
MOVE p_con TO <fs>.

IF p_gub = 'E'.
APPEND gs_fieldcat TO gt_fieldcat.
ENDIF.

ENDFORM. " MAKE_FIELDCAT


* 이제 이벤트 처리를 합니다.
FORM set_events.
PERFORM get_alv_event_list.
PERFORM set_event_form USING : slis_ev_user_command gc_user_command,
slis_ev_top_of_page gc_top_of_page,
.....
기타등등 쓰시는 이벤트... 등록
.....
여기에 DATA_CHANGED 이벤트를 등록해줍니다.
slis_ev_data_changed gc_data_changed.

ENDFORM. " set_events

* FUNCTION을 쓸경우 사용가능한 이벤트의 리스트를 가져옵니다.
* 주의하실점은 gt_events 테이블에 'DATA_CHANGED'는 없습니다.
* 그런데, 개발클래스 SLIS를 보면 분명히 위의 이벤트가 있습니다.
* 여기서 의문점을 가지고.....
FORM get_alv_event_list.

CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = gt_events.

ENDFORM. " get_alv_event_list


* 강제로 DATA_CHANGED 이벤트를 등록합니다.
FORM set_event_form USING p_event
p_form.

CLEAR gs_events.
READ TABLE gt_events WITH KEY name = p_event
INTO gs_events.
IF sy-subrc = 0.
gs_events-form = p_form.
MODIFY gt_events FROM gs_events INDEX sy-tabix.
ELSE. < -- 당연히 없죠.. 없을 경우 등록...
gs_events-name = p_event.
gs_events-form = p_form.
APPEND gs_events TO gt_events.
ENDIF.

ENDFORM. " set_event_form

* 여기부터가 진짜죠..
* 어디서 많이 본 SOURCE인데.. 하시는 분들은 CLASS로 프로그램을 작성한
* 기억이 나신 경우입니다.
*&--------------------------------------------------------------------*
*& Form alv_data_changed
*&--------------------------------------------------------------------*
* text
*---------------------------------------------------------------------*
FORM alv_data_changed USING rr_data_changed TYPE REF TO
cl_alv_changed_data_protocol.

DATA : ls_mod_cells TYPE lvc_s_modi,
ls_cells TYPE lvc_s_modi,
l_matnr LIKE mara-matnr.

LOOP AT rr_data_changed->mt_good_cells INTO ls_mod_cells.
CASE ls_mod_cells-fieldname.
WHEN 'MATNR'.
PERFORM mark_changed USING rr_data_changed ls_mod_cells.
ENDCASE.
ENDLOOP.
ENDFORM. "alv_data_changed

* 클래스로 프로그램을 코딩할때와 똑 같죠 ^^
FORM mark_changed USING
rr_data_changed TYPE REF TO cl_alv_changed_data_protocol
rs_mod_cells TYPE lvc_s_modi.
DATA: LV_MAKTX LIKE MAKT-MAKTX.

READ TABLE gt_display INDEX rs_mod_cells-tabix.

* 화면을 갱신할 필요가 있는 경우.....
* METHOD를 바로 CALL해도 문제가 없습니다.

SELECT single maktx INTO lv_maktx
FROM MAKT
WHERE MATNR = GT_DISPLAY-MATNR
AND SPRAS = SY-LANGU.

CALL METHOD rr_data_changed->modify_cell
EXPORTING i_row_id = rs_mod_cells-row_id
i_fieldname = 'MAKTX'
i_value = LV_MAKTX.

* 화면에 보여줄 필요가 없는 경우. 가령 데이터가 바뀌었다는 것만 CHECK.
gt_display-changed = 'X'.
MODIFY TABLE GT_DISPLAY INDEX rs_mod_cells-row_id
TRANSPORTING changed.

ENDFORM. " mark_changed


* 마지막으로 중요한 부분이 남아있습니다.
* Class에서도 edit 이벤트를 등록을 해준 기억이 나실겁니다.
* 가령.. 데이터가 바뀔때..
IF sy-batch IS INITIAL.
CALL METHOD g_grid->register_edit_event EXPORTING
i_event_id =
cl_gui_alv_grid=>mc_evt_modified.
ENDIF.
* 엔터키를 눌렀을때..
IF sy-batch IS INITIAL.
CALL METHOD g_grid->register_edit_event EXPORTING
i_event_id =
cl_gui_alv_grid=>MC_EVT_ENTER.
ENDIF.

와 같이 어떤 경우에 Data_Changed 이벤트가 발생하라고 알려주죠..
이부분에서 역으로 찾았습니다.

gs_gridset-edt_cll_cb = 'X'.

이렇게 해주면 되더군요.. 엔터키를 누르는 경우나 데이터가 바뀌는 경우..
둘다 반응하더군요...


FORM display_alv_function .


gs_gridset-edt_cll_cb = 'X'.

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
.......
.......
it_events = gt_events[]
i_grid_settings = gs_gridset
.......
.......
TABLES
t_outtab = gt_display


*** 여기까지 입니다.
주의하실점은 reuse_alv_grid_display함수를 쓰는 경우의 예입니다.

*** 조금 응용을 하시면 데이터가 바뀔때 인터널테이블의 특정 필드에 'X' 표시를 하고
LOOP AT GT_DISPLAY WHERE CHANGED = 'X'.
PERFORM EXEC_BDC. "또는
PERFORM SAVE_CBO_TABLE.
ENDLOOP.
등과 같은 로직을 추가 하시면 됩니다.