As described in my post Move Cursor to next Row by Pressing Enter in OO ALV, it would be easy to implement the Excel like functionality using the OO ALV. Than I thought, let me try to implement this using the classical approch: Using the Function Module REUSE_ALV_GRID_DISPLAY.
To implement this functionality using the FM, I actually tried more than the OO ALV. Because it doesn’t have the parameters or FM which can get us the Current Cell and can accept the new values for the Next row. Finally, I got the FM GET_GLOBALS_FROM_SLVC_FULLSCR which can be useful to get the object reference. After getting the object reference, I used the same logic (as per the previous blog) to derive and move the cursor at the next line.
*&---------------------------------------------------------------------*
*& This code snippet shows how to use the classical ALV grid to
*& perform the excel like feature: Move cursor to next row by
*& pressing enter
*&---------------------------------------------------------------------*
REPORT ZTEST_NP_GRID_EDIT.
*
* Data Declration
TYPE-POOLS: SLIS.
*
TYPES: BEGIN OF TY_SFLIGHT.
INCLUDE TYPE SFLIGHT.
TYPES: BOX TYPE CHAR1,
END OF TY_SFLIGHT.
*
*
DATA: GT_SFLIGHT TYPE TABLE OF TY_SFLIGHT.
DATA: GS_LAYOUT TYPE SLIS_LAYOUT_ALV.
DATA: LT_EVTS TYPE SLIS_T_EVENT,
LA_EVTS LIKE LINE OF LT_EVTS.
*
DATA: GS_REPORT TYPE SY-CPROG,
GS_TITLE TYPE LVC_TITLE.
*
* Start of Selection
START-OF-SELECTION.
*
* Report
GS_REPORT = SY-CPROG.
GS_TITLE = 'Move Cursor to next row by pressing Enter'.
*
* Selection.
SELECT * FROM SFLIGHT
INTO CORRESPONDING FIELDS OF TABLE GT_SFLIGHT.
*
* Layout
GS_LAYOUT-EDIT = 'X'.
*
* Event for Data Changed
LA_EVTS-NAME = 'DATA_CHANGED'.
LA_EVTS-FORM = 'GET_DATA_CHANGED'.
APPEND LA_EVTS TO LT_EVTS.
*
* Call ABAP List Viewer (ALV)
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_GRID_TITLE = GS_TITLE
I_CALLBACK_PROGRAM = GS_REPORT
I_STRUCTURE_NAME = 'SFLIGHT'
IS_LAYOUT = GS_LAYOUT
IT_EVENTS = LT_EVTS
TABLES
T_OUTTAB = GT_SFLIGHT.
*
*&---------------------------------------------------------------------*
*& Form get_data_changed
*&---------------------------------------------------------------------*
* Here we will get the current cell and than add 1 to it to move
* to next row. Than we will call the method to set the new row
*----------------------------------------------------------------------*
FORM GET_DATA_CHANGED USING RR_DATA_CHANGED
TYPE REF TO CL_ALV_CHANGED_DATA_PROTOCOL.
*
DATA: LO_GRID TYPE REF TO CL_GUI_ALV_GRID.
*
DATA: LE_ROW TYPE I,
LE_VALUE TYPE C,
LE_COL TYPE I,
LES_ROW_ID TYPE LVC_S_ROW,
LES_COL_ID TYPE LVC_S_COL,
LES_ROW_NO TYPE LVC_S_ROID.
*
* Get the ALV Object reference
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
E_GRID = LO_GRID.
*
* Get the Current Cell
CALL METHOD LO_GRID->GET_CURRENT_CELL
IMPORTING
E_ROW = LE_ROW
E_VALUE = LE_VALUE
E_COL = LE_COL
ES_ROW_ID = LES_ROW_ID
ES_COL_ID = LES_COL_ID
ES_ROW_NO = LES_ROW_NO.
*
* Set to the next cell
DESCRIBE TABLE GT_SFLIGHT LINES SY-INDEX.
LES_ROW_ID-INDEX = LES_ROW_ID-INDEX + 1.
LES_ROW_NO-ROW_ID = LES_ROW_NO-ROW_ID + 1.
IF LES_ROW_ID-INDEX LE SY-INDEX.
CALL METHOD LO_GRID->SET_CURRENT_CELL_VIA_ID
EXPORTING
IS_ROW_ID = LES_ROW_ID
IS_COLUMN_ID = LES_COL_ID
IS_ROW_NO = LES_ROW_NO.
ENDIF.
ENDFORM. "get_data_changed
Nice post…
Hey,
This is very.very useful to me ,
Thank Q
regards
purna.
Hi Naimesh!!
I’m just working in a Classical ALV, and i need just the “same” thing, i must detect when user pushes ENTER in a cell to do some verifications about this field… I made this like you comment in this excepcional post but it isn’t working…
I’ve copied all your code and pasted in a new report, but when i push ENTER, cursor doesn’t move to the next cell…
Are you sure this code is working right??
I need to know that because this can be so much usefull for me.
THANKS A LOT!!!
Hello mig_diabolo69,
Are you sure this code is working right??
Yes, the code is working fine. It might be possible that cursor goes to transaction box and you press enter it would not work. You have to put the cursor on any cell in the ALV grid and than press enter, it would work.
Moreover, you can debug the code by putting the breakpoint in the subroutine GET_DATA_CHANGED.
Regards,
Naimesh Patel
Hello Naimesh,
Firstly I want to regard you your quick response and your help.
This is the code of the program I've made with your explanations. I've just debugged fixing a breakpoint in GET_DATA_CHANGED and the problem is that program don't detect ENTER pushed because never aproaches this breakpoint.
The code:
*&———————————————————————*
*& Report ZZPRUEBA
*&
*&———————————————————————*
*&
*&
*&———————————————————————*
REPORT zzprueba.
*&———————————————————————*
*& This code snippet shows how to use the classical ALV grid to
*& perform the excel like feature: Move cursor to next row by
*& pressing enter
*&———————————————————————*
*
* Data Declration
TYPE-POOLS: slis.
*
TYPES: BEGIN OF ty_eban.
INCLUDE TYPE eban.
TYPES: box TYPE char1,
END OF ty_eban.
*
*
DATA: gt_eban TYPE TABLE OF ty_eban.
DATA: gs_layout TYPE slis_layout_alv.
DATA: lt_evts TYPE slis_t_event,
la_evts LIKE LINE OF lt_evts.
*
DATA: gs_report TYPE sy-cprog,
gs_title TYPE lvc_title.
*
* Start of Selection
START-OF-SELECTION.
*
* Report
gs_report = sy-cprog.
gs_title = 'Move Cursor to next row by pressing Enter'.
*
* Selection.
SELECT * FROM eban
INTO CORRESPONDING FIELDS OF TABLE gt_eban
WHERE matnr EQ '000000000000300000'.
*
* Layout
gs_layout-edit = 'X'.
*
* Event for Data Changed
la_evts-name = 'DATA_CHANGED'.
la_evts-form = 'GET_DATA_CHANGED'.
APPEND la_evts TO lt_evts.
*
* Call ABAP List Viewer (ALV)
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_grid_title = gs_title
i_callback_program = gs_report
i_structure_name = 'EBAN'
is_layout = gs_layout
it_events = lt_evts
TABLES
t_outtab = gt_eban.
*
*&———————————————————————*
*& Form get_data_changed
*&———————————————————————*
* Here we will get the current cell and than add 1 to it to move
* to next row. Than we will call the method to set the new row
*———————————————————————-*
FORM get_data_changed USING rr_data_changed
TYPE REF TO cl_alv_changed_data_protocol.
*
DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
*
DATA: le_row TYPE i,
le_value TYPE c,
le_col TYPE i,
les_row_id TYPE lvc_s_row,
les_col_id TYPE lvc_s_col,
les_row_no TYPE lvc_s_roid.
*
* Get the ALV Object reference
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lo_grid.
*
* Get the Current Cell
CALL METHOD lo_grid->get_current_cell
IMPORTING
e_row = le_row
e_value = le_value
e_col = le_col
es_row_id = les_row_id
es_col_id = les_col_id
es_row_no = les_row_no.
*
* Set to the next cell
DESCRIBE TABLE gt_eban LINES sy-index.
les_row_id-index = les_row_id-index + 1.
les_row_no-row_id = les_row_no-row_id + 1.
IF les_row_id-index LE sy-index.
CALL METHOD lo_grid->set_current_cell_via_id
EXPORTING
is_row_id = les_row_id
is_column_id = les_col_id
is_row_no = les_row_no.
ENDIF.
ENDFORM. "get_data_changed
Regards,
Miguel.
Hello Miguel,
Your report will generate output with all cell as ready to input. You have to change something in any cell, press enter and than it will trigger the event DATA_CHANGED and hence it will move that cursor to next row.
If your requirment is to validate something, than you have to put that validation in the Subroutine GET_DATA_CHANGED. But remember, it will work if you change something.
Regards,
Naimesh Patel
Hello Naimesh,
You were right, it was my fault, your code is working nice, it has been really useful for my report!!!… But I have a new problem, i must detect when user CLICKs in a field of the ALV to change the color of all the row. I’ve read a lot of documentation aobut HOTSPOT_CLICK event, but i don’t know how to use it… I’m not detecting this event… Could you help me please? Could you make another litle report explaining how it works?
Thank you very much,
Miguel.
Hello Miguel,
i must detect when user CLICKs in a field of the ALV to change the color of all the row.
Does user clicks somewhere on the ALV to change the color of all row.? If so, than you can determin the position using the method GET_CURRENT_CELL.
Regards,
Naimesh Patel
Hi Naimesh,
User can click (simple click) in any field of ALV, then I must detect it to change the color of all the row in which this field is placed…
But my problem is not changing color of this row, my problem is how to detect SIMPLE CLICK event, i'm triying to detect HOTSPOT_CLICK but without exit 🙁
This is my code:
* Detect ENTER event
lv_a_event-name = 'DATA_CHANGED'.
lv_a_event-form = 'DATA_CHANGED'.
APPEND lv_a_event TO lv_t_event.
* Detect simple click event
lv_a_event-name = 'HOTSPOT_CLICK'.
lv_a_event-form = 'HOTSPOT_CLICK'.
APPEND lv_a_event TO lv_t_event.
*&———————————————————————*
*& Form handle_hotspot_click
*&———————————————————————*
* text
*———————————————————————-*
* –>I_ROW_ID text
* –>I_COLUMN_ID text
* –>IS_ROW_NO text
*———————————————————————-*
FORM hotspot_click USING i_row_id TYPE lvc_s_row
i_column_id TYPE lvc_s_col
is_row_no TYPE lvc_s_roid.
DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
*
DATA: le_row TYPE i,
le_value TYPE c,
le_col TYPE i,
les_row_id TYPE lvc_s_row,
les_col_id TYPE lvc_s_col,
les_row_no TYPE lvc_s_roid.
*
* Get the ALV Object reference
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lo_grid.
CALL METHOD lo_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_modified.
* Get the Current Cell
CALL METHOD lo_grid->get_current_cell
IMPORTING
e_row = le_row
e_value = le_value
e_col = le_col
es_row_id = les_row_id
es_col_id = les_col_id
es_row_no = les_row_no.
*
* Set to the next cell
DESCRIBE TABLE i_alv_data LINES sy-index.
les_row_id-index = les_row_id-index + 1.
les_row_no-row_id = les_row_no-row_id + 1.
IF les_row_id-index LE sy-index.
CALL METHOD lo_grid->set_current_cell_via_id
EXPORTING
is_row_id = les_row_id
is_column_id = les_col_id
is_row_no = les_row_no.
ENDIF.
ENDFORM . "handle_hotspot_click
I've put the same code than in ENTER event just to test it. I will change it when I achieve detection of this event…
REgards,
Miguel.
Can I use REUSE_ALV_GRID_DISPLAY_LVC with your example??
It should work. As long as you have an access to EO_GRID object using the FM GET_GLOBALS_FROM_SLVC_FULLSCR, this example would work with the ALV generated by the FM REUSE_ALV_GRID_DISPLAY_LVC.
Regards,
Naimesh Patel
Thanks for you reply.
I have a question ,
LA_EVTS-NAME = ‘DATA_CHANGED’. “?????
LA_EVTS-FORM = ‘GET_DATA_CHANGED’.” Form
Regarding the LA_EVTS-FORM, it means if I add a form named ‘GET_DATA_CHANGED’,then it will be triggered in Event, but what is LA_EVTS-NAME for ??
Regards,
Yes, event name is correct. You can get all the applicable events using the FM REUSE_ALV_EVENTS_GET.
Regards,
Naimesh Patel
Thanks.
1)I cannot find the event : DATA_CHANGED, in which List_type I can find event DATA_CHANGED using FM REUSE_ALV_EVENTS_GET?
2) I reference you sample let my program work fine, but I find I should set layout-edit = ‘X’ like your sample,( I wanted to set in fieldcat…but if I set ediable in fieldcat,, the program cannot trigger if I change some data. as user required some cells should be editable, some are uneditable.)
3)Would it be possible for you to tell me that Can I use FM REUSE_ALV_GRID_DISPLAY_LVC to catch ‘Enter’ event?
(If user Press ‘Enter’ ,,,,which event will be triggered?)
Regards,
It should work. Give a try populating DATA_CHANGED and Subroutine which gets triggered when Event fires.
I need to try with only some fields to make editable and see what happens.
Other idea is – if you don’t get the DATA_CHANGED work, you can get the O_GRID object even if you can the FM GET_GLOBALS_FROM_SLVC_FULLSCR inside the Header Event. If you get the object, then you can use it to register the event handler for DATA_CHANGED.
Regards,
Naimesh Patel
Hi. Thanks.
It can work now.
1)but why cannot I find the event name DATA_CHANGED while using FM REUSE_ALV_EVENTS_GET to see all events? whicy list_type should I use?
2) Can I use FM REUSE_ALV_GRID_DISPLAY_LVC to catch ‘Enter’ event?
(If user Press ‘Enter’ ,,,,which event will be triggered?)
Regards,