‎2006 Nov 22 8:44 AM
Hello;
i am using fm REUSE_ALV_GRID (not OO) to display an internal table. The user wants to change the data in a certain cell. I have marked this cell as editable and it works fine. I want to learn what to check in the event of data_changed. I have added this event in table ALV_EVENTS and directed to a subroutine. What parameters should i pass to the subroutine and what should i check to read the relevant line? Is it possible to control changes in more than one line?
Thx
Ali
‎2006 Nov 22 10:13 AM
<i>Is it possible to control changes in more than one line?</i>
yes.
for usage of the method, and editable grid please refer the sample code.
REPORT ZTESTDFALV1 .
*Data Declaration
*----------------
DATA: BEGIN OF T_EKKO,
EBELN TYPE EKPO-EBELN,
EBELP TYPE EKPO-EBELP,
END OF T_EKKO.
DATA: BEGIN OF IT_EKKO OCCURS 0.
INCLUDE STRUCTURE T_EKKO.
DATA: END OF IT_EKKO.
DATA: BEGIN OF IT_BACKUP OCCURS 0.
INCLUDE STRUCTURE T_EKKO.
DATA: END OF IT_BACKUP.
*ALV data declarations
TYPE-POOLS: SLIS. "ALV Declarations
DATA: FIELDCATALOG TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
GD_LAYOUT TYPE SLIS_LAYOUT_ALV,
GD_REPID LIKE SY-REPID.
************************************************************************
*Start-of-selection.
START-OF-SELECTION.
PERFORM DATA_RETRIEVAL.
PERFORM BUILD_FIELDCATALOG.
PERFORM BUILD_LAYOUT.
IT_BACKUP[] = IT_EKKO[].
PERFORM DISPLAY_ALV_REPORT.
*&--------------------------------------------------------------------*
*& Form build_fieldcatalog
*&--------------------------------------------------------------------*
* text
*---------------------------------------------------------------------*
FORM BUILD_FIELDCATALOG.
REFRESH FIELDCATALOG.
CLEAR FIELDCATALOG.
*
FIELDCATALOG-FIELDNAME = 'EBELN'.
FIELDCATALOG-SELTEXT_M = 'Purchase Order'.
FIELDCATALOG-INPUT = 'X'.
FIELDCATALOG-EDIT = 'X'.
FIELDCATALOG-COL_POS = 2.
APPEND FIELDCATALOG.
CLEAR FIELDCATALOG.
FIELDCATALOG-FIELDNAME = 'EBELP'.
FIELDCATALOG-SELTEXT_M = 'PO Item'.
FIELDCATALOG-COL_POS = 3.
APPEND FIELDCATALOG.
CLEAR FIELDCATALOG.
ENDFORM. " BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
*& Form BUILD_LAYOUT
*&---------------------------------------------------------------------*
* Build layout for ALV grid report
*----------------------------------------------------------------------*
FORM BUILD_LAYOUT.
"Permet d'ajuster les colonnes au text
* gd_layout-colwidth_optimize = 'X'.
GD_LAYOUT-TOTALS_TEXT = 'Totals'(201).
* gd_layout-box_fieldname = 'SELECT'.
* gd_layout-box_tabname = 'IT_EKKO'.
ENDFORM. " BUILD_LAYOUT
*&---------------------------------------------------------------------*
*& Form DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
* Display report using ALV grid
*----------------------------------------------------------------------*
FORM DISPLAY_ALV_REPORT.
GD_REPID = SY-REPID.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = GD_REPID
* i_callback_top_of_page = 'TOP-OF-PAGE'
I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
I_CALLBACK_USER_COMMAND = 'USER_COMMAND'
* i_grid_title = 'My Title'
IS_LAYOUT = GD_LAYOUT
IT_FIELDCAT = FIELDCATALOG[]
TABLES
T_OUTTAB = IT_EKKO
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
IF SY-SUBRC <> 0.
WRITE:/ SY-SUBRC.
ENDIF.
ENDFORM. " DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
*& Form DATA_RETRIEVAL
*&---------------------------------------------------------------------*
* Retrieve data form EKPO table and populate itab it_ekko
*----------------------------------------------------------------------*
FORM DATA_RETRIEVAL.
SELECT EBELN EBELP
UP TO 10 ROWS
FROM EKPO
INTO CORRESPONDING FIELDS OF TABLE IT_EKKO.
ENDFORM. " DATA_RETRIEVAL
*----------------------------------------------------------------------*
* FORM SET_PF_STATUS *
*----------------------------------------------------------------------*
FORM SET_PF_STATUS USING RT_EXTAB TYPE SLIS_T_EXTAB.
SET PF-STATUS 'STANDARD_FULLSCREEN1' EXCLUDING RT_EXTAB.
ENDFORM. "set_pf_status
*&--------------------------------------------------------------------*
*& Form user_command
*&--------------------------------------------------------------------*
* text
*---------------------------------------------------------------------*
* -->R_UCOMM text
* -->RS_SELFIELDtext
*---------------------------------------------------------------------*
FORM USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
RS_SELFIELD TYPE SLIS_SELFIELD.
<b>DATA: GD_REPID LIKE SY-REPID, "Exists
REF_GRID TYPE REF TO CL_GUI_ALV_GRID. "new
*then insert the following code in your USER_COMMAND routine...
IF REF_GRID IS INITIAL.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
E_GRID = REF_GRID.
ENDIF.
IF NOT REF_GRID IS INITIAL.
CALL METHOD REF_GRID->CHECK_CHANGED_DATA
.
ENDIF.</b>
CASE R_UCOMM.
WHEN '&IC1'.
CHECK RS_SELFIELD-TABINDEX > 0.
IF RS_SELFIELD-VALUE EQ '6000000001'.
CALL TRANSACTION 'ZDF2'.
ENDIF.
WHEN 'ENTER'.
READ TABLE IT_EKKO INDEX RS_SELFIELD-TABINDEX.
IF SY-SUBRC = 0.
READ TABLE IT_BACKUP INDEX RS_SELFIELD-TABINDEX.
IF SY-SUBRC = 0.
IF IT_EKKO <> IT_BACKUP.
* then do your check
ENDIF.
ENDIF.
ENDIF.
PERFORM DATA_RETRIEVAL.
RS_SELFIELD-REFRESH = 'X'.
ENDCASE.
ENDFORM. "user_commandRegards
Vijay
‎2006 Nov 22 9:59 AM
i hav never tried this but wat u can do is import ER_DATA_CHANGED from event data changed .
ER_DATA_CHANGED is of type CL_ALV_CHANGED_DATA_PROTOCOL .
CL_ALV_CHANGED_DATA_PROTOCOL has some attributes as follows:
MT_MOD_CELLS-Table of Modified Cells
MP_MOD_ROWS-Table of Modified Rows
MT_DELETED_ROWS-Deleted Rows
ans so on .
try using all these attributes to make where cahnges have been made .
A simpler approach would be make use of two tables .
wat i do is whenever user makes some changes , after making all his changes he has to press enter .
n i register the event for pressing 'enter' as follows ..
CALL METHOD ref_alv_grid_item->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter
EXCEPTIONS
error = 1
OTHERS = 2.
then in PAI i compare the two tables to make out where changes have been made .
both the ways should work .
if the first thing works then jst let me knw .
second method i hav used successfully .
if this helps u the plz reward points .
‎2006 Nov 22 10:04 AM
you can use this method to check whether data is changed or not.
(where lv_check and refresh_grid is flag ie 1 char variable)
CALL METHOD reuse_alv_grid->check_changed_data
IMPORTING
e_valid = lv_check
CHANGING
c_refresh = refresh_grid.
Now refersh_grid and lv_check will be 1 if data is changed.
use 2 table for checking which data is changed,
1st will be table you display on grid and 2nd will be its image at the time of last refresh_grid or if the grid is not yet refreshed then the grid you use for first display.
now in the data_change event set a variable to indicate that data is changed(let this variable be gv_change)
now in the screen in which you are dealing.. put a module before control_display module in which you will compare two tables.
In this way you can even check for change in multiple lines.
‎2006 Nov 22 10:05 AM
u will pass only one parameter to this event data_changed
it is char of length 1
if any data is changed that value will returm X , if no data is changed it will return space
CALL METHOD W_GRID->CHECK_CHANGED_DATA
IMPORTING
E_VALID = L_VALID.
‎2006 Nov 22 10:13 AM
<i>Is it possible to control changes in more than one line?</i>
yes.
for usage of the method, and editable grid please refer the sample code.
REPORT ZTESTDFALV1 .
*Data Declaration
*----------------
DATA: BEGIN OF T_EKKO,
EBELN TYPE EKPO-EBELN,
EBELP TYPE EKPO-EBELP,
END OF T_EKKO.
DATA: BEGIN OF IT_EKKO OCCURS 0.
INCLUDE STRUCTURE T_EKKO.
DATA: END OF IT_EKKO.
DATA: BEGIN OF IT_BACKUP OCCURS 0.
INCLUDE STRUCTURE T_EKKO.
DATA: END OF IT_BACKUP.
*ALV data declarations
TYPE-POOLS: SLIS. "ALV Declarations
DATA: FIELDCATALOG TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
GD_LAYOUT TYPE SLIS_LAYOUT_ALV,
GD_REPID LIKE SY-REPID.
************************************************************************
*Start-of-selection.
START-OF-SELECTION.
PERFORM DATA_RETRIEVAL.
PERFORM BUILD_FIELDCATALOG.
PERFORM BUILD_LAYOUT.
IT_BACKUP[] = IT_EKKO[].
PERFORM DISPLAY_ALV_REPORT.
*&--------------------------------------------------------------------*
*& Form build_fieldcatalog
*&--------------------------------------------------------------------*
* text
*---------------------------------------------------------------------*
FORM BUILD_FIELDCATALOG.
REFRESH FIELDCATALOG.
CLEAR FIELDCATALOG.
*
FIELDCATALOG-FIELDNAME = 'EBELN'.
FIELDCATALOG-SELTEXT_M = 'Purchase Order'.
FIELDCATALOG-INPUT = 'X'.
FIELDCATALOG-EDIT = 'X'.
FIELDCATALOG-COL_POS = 2.
APPEND FIELDCATALOG.
CLEAR FIELDCATALOG.
FIELDCATALOG-FIELDNAME = 'EBELP'.
FIELDCATALOG-SELTEXT_M = 'PO Item'.
FIELDCATALOG-COL_POS = 3.
APPEND FIELDCATALOG.
CLEAR FIELDCATALOG.
ENDFORM. " BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
*& Form BUILD_LAYOUT
*&---------------------------------------------------------------------*
* Build layout for ALV grid report
*----------------------------------------------------------------------*
FORM BUILD_LAYOUT.
"Permet d'ajuster les colonnes au text
* gd_layout-colwidth_optimize = 'X'.
GD_LAYOUT-TOTALS_TEXT = 'Totals'(201).
* gd_layout-box_fieldname = 'SELECT'.
* gd_layout-box_tabname = 'IT_EKKO'.
ENDFORM. " BUILD_LAYOUT
*&---------------------------------------------------------------------*
*& Form DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
* Display report using ALV grid
*----------------------------------------------------------------------*
FORM DISPLAY_ALV_REPORT.
GD_REPID = SY-REPID.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = GD_REPID
* i_callback_top_of_page = 'TOP-OF-PAGE'
I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
I_CALLBACK_USER_COMMAND = 'USER_COMMAND'
* i_grid_title = 'My Title'
IS_LAYOUT = GD_LAYOUT
IT_FIELDCAT = FIELDCATALOG[]
TABLES
T_OUTTAB = IT_EKKO
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
IF SY-SUBRC <> 0.
WRITE:/ SY-SUBRC.
ENDIF.
ENDFORM. " DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
*& Form DATA_RETRIEVAL
*&---------------------------------------------------------------------*
* Retrieve data form EKPO table and populate itab it_ekko
*----------------------------------------------------------------------*
FORM DATA_RETRIEVAL.
SELECT EBELN EBELP
UP TO 10 ROWS
FROM EKPO
INTO CORRESPONDING FIELDS OF TABLE IT_EKKO.
ENDFORM. " DATA_RETRIEVAL
*----------------------------------------------------------------------*
* FORM SET_PF_STATUS *
*----------------------------------------------------------------------*
FORM SET_PF_STATUS USING RT_EXTAB TYPE SLIS_T_EXTAB.
SET PF-STATUS 'STANDARD_FULLSCREEN1' EXCLUDING RT_EXTAB.
ENDFORM. "set_pf_status
*&--------------------------------------------------------------------*
*& Form user_command
*&--------------------------------------------------------------------*
* text
*---------------------------------------------------------------------*
* -->R_UCOMM text
* -->RS_SELFIELDtext
*---------------------------------------------------------------------*
FORM USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
RS_SELFIELD TYPE SLIS_SELFIELD.
<b>DATA: GD_REPID LIKE SY-REPID, "Exists
REF_GRID TYPE REF TO CL_GUI_ALV_GRID. "new
*then insert the following code in your USER_COMMAND routine...
IF REF_GRID IS INITIAL.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
E_GRID = REF_GRID.
ENDIF.
IF NOT REF_GRID IS INITIAL.
CALL METHOD REF_GRID->CHECK_CHANGED_DATA
.
ENDIF.</b>
CASE R_UCOMM.
WHEN '&IC1'.
CHECK RS_SELFIELD-TABINDEX > 0.
IF RS_SELFIELD-VALUE EQ '6000000001'.
CALL TRANSACTION 'ZDF2'.
ENDIF.
WHEN 'ENTER'.
READ TABLE IT_EKKO INDEX RS_SELFIELD-TABINDEX.
IF SY-SUBRC = 0.
READ TABLE IT_BACKUP INDEX RS_SELFIELD-TABINDEX.
IF SY-SUBRC = 0.
IF IT_EKKO <> IT_BACKUP.
* then do your check
ENDIF.
ENDIF.
ENDIF.
PERFORM DATA_RETRIEVAL.
RS_SELFIELD-REFRESH = 'X'.
ENDCASE.
ENDFORM. "user_commandRegards
Vijay
‎2006 Nov 22 12:12 PM
Hi,
Thx for the answer but it does not seem to work. I have made a subroutine to check data changes. I pass the name of the subroutine in ALV events parameter table. I want to process this subroutine when the user changes a cell and presses Enter. Pressing Enter does not trigger the data changed event. What should i check? ( i don't use OO based ALV Grid!!)
My code is as follows:
..
CLEAR ALV_EVENTS.
ALV_EVENTS-NAME = SLIS_EV_DATA_CHANGED.
ALV_EVENTS-FORM = 'DATA_CHANGED'.
APPEND ALV_EVENTS.
..
..
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = ALV_REPID
IS_LAYOUT = ALV_LAYOUT
IT_FIELDCAT = ALV_FIELDCAT[]
I_SAVE = 'A'
IT_EVENTS = ALV_EVENTS[]
IS_PRINT = ALV_PRINT
IS_VARIANT = ALV_VARIANT
I_CALLBACK_USER_COMMAND = USER_SCREEN
I_CALLBACK_PF_STATUS_SET = PF_STATUS
TABLES
T_OUTTAB = ITAB[]
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
....
FORM DATA_CHANGED USING rr_data_changed
type ref to cl_alv_changed_data_protocol.
data: ls_good type lvc_s_modi.
loop at rr_data_changed->mt_good_cells into ls_good.
endloop.
ENDFORM.
Thx again.
Ali
‎2006 Nov 22 12:15 PM
Ali,
the example is working fine in my system, if you want to use the example, you need to set the pf-status and see. it is working or not.
Regards
Vijay
‎2006 Nov 22 12:31 PM
Hi Ali,
Any changes to your ALV, be it a cell modified, added, deleted - will come up in the internal table. mt_mod_cells / mod_rows etc, like somebody mentioend.
The event data_changed is called whenever the content changs. and you will have a handler method for this method, where the idea is for you to do a validation.
if your validation passes, another event data_changed_finished is called. again u shd have a handler for this method. here u will get a table mt_good_cells which will have all the correct entries that have passed validation.
Hope this helps.
pls reward points.
PP.
‎2006 Dec 02 11:45 PM
You have to set the following flag
g_grid_settings-EDT_CLL_CB = 'X'.
So the code would be
CLEAR h_EVENT.
h_EVENT-NAME = SLIS_EV_DATA_CHANGED.
h_EVENT-FORM = 'DATA_CHANGED'.
APPEND h_EVENT to g_events_tab.
gt_layout-lights_fieldname = 'LIGHTS'.
gt_layout-box_fieldname = 'CBOX'.
g_grid_settings-EDT_CLL_CB = 'X'.
call function 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = g_repid
I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS'
I_CALLBACK_USER_COMMAND = 'USER_COMMAND'
I_CALLBACK_TOP_OF_PAGE = 'TOP_OF_PAGE'
I_GRID_SETTINGS = G_GRID_SETTINGS
IS_LAYOUT = gt_layout
IT_FIELDCAT = gt_fieldcat
IT_EXCLUDING = gt_excluding
I_DEFAULT = 'X'
I_SAVE = 'A'
IS_VARIANT = gt_variant
it_events = g_events_tab[]
it_event_exit = g_event_exit_tab[]
TABLES
t_outtab = OUTPUT
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
FORM DATA_CHANGED USING rr_data_changed
type ref to cl_alv_changed_data_protocol.
data: ls_good type lvc_s_modi.
loop at rr_data_changed->mt_good_cells into ls_good.
call method rr_data_changed->get_cell_value
EXPORTING
i_row_id = ls_good-row_id
i_fieldname = ls_good-fieldname
IMPORTING
e_value = l_value.
do your check, and if in error
call method rr_data_changed->add_protocol_entry
EXPORTING
i_msgid = '0K'
i_msgno = '000'
i_msgty = 'E'
i_msgv1 = l_value
i_msgv2 = 'Error'
i_fieldname = ls_good-fieldname
i_row_id = ls_good-row_id.
endloop.
endform.