When you use CL_GUI_ALV_GRID in edit mode or you change your internal table used to display data on ALV grid it may happen that after refreshing the grid using refresh_table_display your cursor or scroll goes to the begining of the grid. Users feels little lost in such situation but there is an easy solution for that.

datais_stable type lvc_s_stbl.
is_stable-row 'X'.
is_stable-col 'X'.
"or 
is_stable 'XX'.

grid->refresh_table_display(
  exporting
    is_stable      =   is_stable   " With Stable Rows/Columns
*    i_soft_refresh =   i_soft_refresh  " Without Sort, Filter, etc.
  exceptions
    finished       1
    others         2
).
if sy-subrc <> 0.
* message id sy-msgid type sy-msgty number sy-msgno
*            with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.

EDIT: Method of mine which can be found bellow doesn't have to be used to achieve your goal. To be honest I can't remember why I created separate version of it as only the cursor act a bit different than oryginal one. I must have had mind eclipse at the time :-) . Excuse me for that.

So to keep scroll position and current cell we will need to use  following methods of CL_GUI_ALV_GRID:

  • get_scroll_info_via_id - gets current scroll information

  • get_current_cell         - gets current cell, we will use that data to set the cursor at the end

  • get_selected_rows      - gets selected rows

  • get_selected_cells_id  - if we didn't select any rows, we check for the selected cell information

  • refresh_table_display  - then simple refresh of grid

  • set_selected_cells_id   - after refresh it's time to set back all information, so set selected cell

  • set_selected_rows       - or set seleted rows (depanding what we received at the begining)

  • set_scroll_info_via_id  - set scroll position back

  • set_current_cell_via_id - set cursor back.

There is no special coding here, just standard ALV grid methods used in proper order.

Method definition, Importing parameters:

I_SOFT TYPE CHAR01  DEFAULT 'X' 
I_SET_CURRENT TYPE CHAR01  DEFAULT SPACE 
I_SET_SELECTED TYPE CHAR01  DEFAULT SPACE

Changing parameters:

GRID TYPE REF TO CL_GUI_ALV_GRID 

Implementation of the code:

method grid_refresh_and_keep_position.
  dataes_row_no  type lvc_s_roid.
  dataes_row_info  type lvc_s_row.
  dataes_col_info  type lvc_s_col.
  datafes_row_no  type lvc_s_roid.
  datafes_row_id  type lvc_s_row.
  datafes_col_id  type lvc_s_col.
  datamt_cells type lvc_t_ceno.
  datamt_rows type lvc_t_row.

  grid->get_scroll_info_via_id(
  importing
    es_row_no   es_row_no
    es_row_info 
es_row_info
    es_col_info 
es_col_info
    
).

  grid->get_current_cell(
    importing
*        e_row     = e_row
*        e_value   = e_value
*        e_col     = e_col
      es_row_id fes_row_id
      es_col_id 
fes_col_id
      es_row_no 
fes_row_no
         
).


  grid->get_selected_rows(
  importing
    et_index_rows mt_rows
*            et_row_no     = et_row_no
    ).
  if mt_rows[] is initial.
    grid->get_selected_cells_id(
    importing  et_cells mt_cells ).
  endif.


  grid->refresh_table_displayi_soft_refresh i_soft ).


  if i_set_selected eq 'X'.
    if mt_cells[] is not initial.
      grid->set_selected_cells_idit_cells mt_cells   ).
    else.
      grid->set_selected_rows(
      it_index_rows            mt_rows
*        it_row_no                = it_row_no
*        is_keep_other_selections = is_keep_other_selections
      ).
    endif.
  endif.

  grid->set_scroll_info_via_id(
  is_row_info es_row_info
  is_col_info 
es_col_info
  is_row_no   
es_row_no
  
).

  if i_set_current eq 'X'.
    grid->set_current_cell_via_idis_row_id fes_row_id
                                    is_column_id 
fes_col_id
                                    is_row_no 
fes_row_no ).
  endif.
  refreshmt_rows[]mt_cells[].
endmethod.

Have fun!