2013 Oct 20 3:17 AM
How to check the changed rows and update database in editable ALV?
As far as I consider, if the numbers of ALV rows is large, you don't need update all the rows but changed ones.
Is there any easy way to do that?
2013 Oct 20 6:15 AM
You can copy the contents to a table and then update the ALV output table. Compare the two tables. In case of change, update to database.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
IS_LAYOUT = L_LAYOUT
I_CALLBACK_USER_COMMAND = 'USER_COMMAND'
IT_FIELDCAT = IT_FIELDCAT
TABLES
T_OUTTAB = ITAB
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
FORM USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
RS_SELFIELD TYPE SLIS_SELFIELD.
DATA: GD_REPID LIKE SY-REPID,
REF_GRID TYPE REF TO CL_GUI_ALV_GRID.
ITAB1[ ] = ITAB.
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.
LOOP AT ITAB INTO WA_ITAB.
READ ITAB1 INTO WA_ITAB1 KEY "provide the key using the key non editable columns .
if wa_itab1 <> wa_itab.
perform save_to_database.
endif.
endloop.
RS_SELFIELD-refresh = 'X'.
ENDFORM. "USER_COMMAND
2013 Oct 20 4:33 AM
Hi Ming,
Are you using CL_GUI_ALV_GRID. I thought so since you mentioned editable ALV.
If so, you might be able to do it this way.
Approach-1:
Step-1: Before you output the content of final internal table (itab_final) into ALV, duplicate it into another internal table (say: itab_copy).
Step-2: After the data is displayed on the output, user changes the data and saves it. Through method GET_GRID_MODIFIED (class: CL_GUI_ALV_GRID), you can verify if the data on the grid was actually changed.
Step-3: If it is modified, you can use the method SAVE_DATA (of same class) to transfer the data from the grid back to your internal table itab_final.
Now, you can compare both old and new data and determine the delta i.e. the rows that were actually changed.
Approach-2:
Alternatively, there is also a method GET_MODIFIED_CELLS (in same class) that will return you which rows & columns were changed. This will be returned in a table format, so it should contain a list of all different cells (rows/columns) that were changed.
You can use to information to update your table.
HTH.
Saurabh
2013 Oct 20 5:21 AM
Actually I didn't use OO ALV, I just used "REUSE_ALV_GRID_DISPLAY_LVC" and set column attribute as 'editable' in layout.
So is it still possible to know which rows are changed and update the lastest contents into the db.
2013 Oct 20 6:00 AM
I am not aware of how this can be accomplished using REUSE_ALV_GRID_DISPLAY_LVC.
There might be way but I don't think it would be easy. Since, the function module based ALV grids doesn't support the concept of transferring data back from Output table to internal table.
Also, is there any specific reason that you want to implement this functionality using REUSE function module.
The reason I ask this is because this approach is not used any more. I am not aware of the system that you are using and your familiarity with different ALVs.
After REUSE_ALV_GRID_DISPLAY, SAP came out with ALV Grid Control (Object Oriented ALV or CL_GUI_ALV_GRID). This supports editing and saving data back to internal table.
But, even the ALV Grid Control is obsolete now. The newest approach is SALV (SAP List Viewer). This doesn't support editing and saving data through ALV.
From what I know, SAP doesn't recommend using ALV to modify data rather it is just a UI tool to display list information.
Simplicity of Usage:
ALV grid control is much simpler to use than REUSE_ALV_GRID_DISPLAY_LVC
And SALV is much simpler than ALV Grid Control. In SALV, you don't event have to create field-catalog or layout. Once you have data in your final internal table, you can just display it.
However, if there is any specific reason that you want to edit it using REUSE_ALV_GRID_DISPLAY_LVC, please let me know and I will be happy to research it from my end.
HTH.
Saurabh
2013 Oct 22 2:55 AM
Hi,
thank you very much for you reply.
The reason that I use "REUSE_ALV_GRID_DISPLAY_LVC" is that I am more familiar with that and I have a code pattern for this kind of ALV output method.
If I choose OO ALV rather than ALV LVC, I have to change a lot of coding.
The reply written by susmitha susan thomas seems like to offer an alternative solution.
LOOP AT ITAB INTO WA_ITAB.
READ ITAB1 INTO WA_ITAB1 KEY "provide the key using the key non editable columns .
if wa_itab1 <> wa_itab.
perform save_to_database.
endif.
ENDLOOP.
I have used this coding and it seems to work.
But as far as I tried, if you set column attribute as "editable" in layout setting, change the value of any cell in ALV output and then double click, the changed value does transfer to the internal table. This is why I can compare two internal tables and know which rows are changed.
I am wondering if you can explain more detail for me with it.
2013 Oct 20 6:15 AM
You can copy the contents to a table and then update the ALV output table. Compare the two tables. In case of change, update to database.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
IS_LAYOUT = L_LAYOUT
I_CALLBACK_USER_COMMAND = 'USER_COMMAND'
IT_FIELDCAT = IT_FIELDCAT
TABLES
T_OUTTAB = ITAB
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
FORM USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
RS_SELFIELD TYPE SLIS_SELFIELD.
DATA: GD_REPID LIKE SY-REPID,
REF_GRID TYPE REF TO CL_GUI_ALV_GRID.
ITAB1[ ] = ITAB.
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.
LOOP AT ITAB INTO WA_ITAB.
READ ITAB1 INTO WA_ITAB1 KEY "provide the key using the key non editable columns .
if wa_itab1 <> wa_itab.
perform save_to_database.
endif.
endloop.
RS_SELFIELD-refresh = 'X'.
ENDFORM. "USER_COMMAND
2013 Oct 22 2:58 AM
Thank you for the coding. It helps.
But the problem is that what does followed coding actually do
RS_SELFIELD TYPE SLIS_SELFIELD.
DATA: GD_REPID LIKE SY-REPID,
REF_GRID TYPE REF TO CL_GUI_ALV_GRID.
ITAB1[ ] = ITAB.
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.
because If you just compare two internal tables and transfer the changed data into the db, you DO NOT have to write something like "CL_GUI_ALV_GRID" or "CALL METHOD REF_GRID->CHECK_CHANGED_DATA .".
2013 Oct 22 5:40 AM
Hi Ming,
What the method Check_changed_data does is, it updates the changes that were made in the ALV to the output table.
IF NOT REF_GRID IS INITIAL.
CALL METHOD REF_GRID->CHECK_CHANGED_DATA .
ENDIF.
So what we have done here is, first copy the old internal table contents itab into another table itab1.
itab1[] = itab[].
Then we call the above method to update the internal table.
Now the we have the initial ALV data in itab1 and updated ALV data in itab. After comparing the tables, if the contents dont match for any row, it means data was changed for that row and hence update the same to database.
Hope its clear now.
2013 Oct 22 6:28 AM
But after trying, I found the changed data CAN be transferred to output table when some events being triggered like double clicking or clicking save button.
So I am asking why you need "CALL METHOD REF_GRID->CHECK_CHANGED_DATA ."?
2013 Oct 22 6:47 AM
You are using the normal classic ALV right? Just check if you are using this method in other function codes that you mentioned like the function code for save or double click (&IC1). You must have called this method somewhere to transfer the changes. If not, I would really love to see your code to know how you transferred the changes without using this method at all. For all the ALV programs I have written so far, I was not able to transfer the changes without using this method and your new method would be very informative and helpful. 🙂
2013 Oct 22 7:26 AM
FORM FRM_EVENT .
I found the reason. That is because there is 'IT_EVENT' in the pattern code.
DATA L_EVENTS TYPE SLIS_ALV_EVENT.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
I_LIST_TYPE = 0
IMPORTING
ET_EVENTS = IT_EVENTS
EXCEPTIONS
LIST_TYPE_WRONG = 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.
CLEAR L_EVENTS.
READ TABLE IT_EVENTS WITH KEY NAME = SLIS_EV_USER_COMMAND INTO L_EVENTS.
IF SY-SUBRC = 0.
MOVE 'USER_COMMAND' TO L_EVENTS-FORM.
MODIFY IT_EVENTS INDEX SY-TABIX FROM L_EVENTS.
ENDIF.
ENDFORM. " FRM_EVENT
As showed above, if you have this code and set parameter IT_EVENTS in
"REUSE_ALV_GRID_DISPLAY_LVC", the double clicking or save button do save changed values into the output table(internal table).
2014 Mar 14 10:14 AM
Hi Sushmitha,
Could you Please Publish the code Details form First to Last.So that it would be easy to Undesrstand.
Br,
Amar
2013 Oct 20 7:25 AM
2024 Mar 06 5:24 AM
Hi everyone,
Please explain the code written in "perform save_to_database".
Thanks.
2013 Oct 21 12:58 PM
HI Ming,
Try executing the below code. I have used DATA_CHANGED event to capture the modified data only.
TYPE-POOLS: SLIS.
data: er_data_changed type ref to cl_alv_changed_data_protocol.
FIELD-SYMBOLS: <zfield> TYPE ANY.
DATA: T_SFLIGHT TYPE STANDARD TABLE OF SFLIGHT.
DATA: IS_LAYOUT_LVC TYPE LVC_S_LAYO.
DATA: IT_EVENTS TYPE SLIS_T_EVENT.
DATA: LT_EVENT TYPE SLIS_ALV_EVENT.
DATA: L_REPORT TYPE SY-REPID.
START-OF-SELECTION.
IS_LAYOUT_LVC-EDIT = 'X'.
LT_EVENT-NAME = 'DATA_CHANGED'.
LT_EVENT-FORM = 'ALV_DATA_CHANGED'.
APPEND LT_EVENT TO IT_EVENTS.
L_REPORT = SY-REPID.
SELECT * UP TO 10 ROWS INTO TABLE T_SFLIGHT
FROM SFLIGHT.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
I_CALLBACK_PROGRAM = L_REPORT
I_STRUCTURE_NAME = 'SFLIGHT'
IS_LAYOUT_LVC = IS_LAYOUT_LVC
IT_EVENTS = IT_EVENTS
TABLES
T_OUTTAB = T_SFLIGHT.
FORM ALV_DATA_CHANGED USING
ER_DATA_CHANGED TYPE REF TO CL_ALV_CHANGED_DATA_PROTOCOL.
DATA: LS_GOOD TYPE LVC_S_MODI.
ASSIGN er_data_changed->mp_mod_rows->* TO <zfield>.
LOOP AT ER_DATA_CHANGED->MT_GOOD_CELLS INTO LS_GOOD.
MESSAGE I208(00) WITH 'Data changed'.
EXIT.
ENDLOOP.
ENDFORM. "ALV_DATA_CHANGED
Regards,
Sivaganesh
2013 Nov 06 3:47 PM
Sorry for late reply, I've tried this again these days.
I am now assure that you DO NOT need some code like:
DATA: GD_REPID LIKE SY-REPID,
REF_GRID TYPE REF TO CL_GUI_ALV_GRID.
ITAB1 = ITAB.
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.
to transfer the changed data into the internal table.
What you need is just write code in user_command form like:
FORM USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
RS_SELFIELD TYPE SLIS_SELFIELD .
// your code here
ENDFORM.
And this Form comes from either "I_CALLBACK_USER_COMMAND = 'USER_COMMAND'"
or "IT_EVENTS = IT_EVENTS" which are the parameter of ALV FM.
However, this method does not work very good, sometimes the data on the table changed, but does not transfer to the internal table if you don't double click or click save button strictly.