Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

ALV Grid data changed

Former Member
0 Kudos
3,615

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

1 ACCEPTED SOLUTION

former_member188685
Active Contributor
0 Kudos
371

<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_command

Regards

Vijay

8 REPLIES 8

Former Member
0 Kudos
371

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 .

Former Member
0 Kudos
371

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.

Former Member
0 Kudos
371

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.

former_member188685
Active Contributor
0 Kudos
372

<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_command

Regards

Vijay

0 Kudos
371

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

0 Kudos
371

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

Former Member
0 Kudos
371

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.

albert_israel2
Explorer
0 Kudos
371

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.