‎2007 Jan 31 8:33 AM
Hi All,
I am having an ALV Grid . I want to save the data from the grid into the database table which is a z table.
Can anybody please tell me how to do it.
I am using object based programming here.
Pls help.
‎2007 Jan 31 10:20 AM
Hello Manik,
To modify database or ztable from the ALV grid,you need to do the following:
---You have to modify the field Catalog fields (fields that you want to make editable).Set the field EDIT as 'X'.For example if you want to make the field below editable:
ls_fcat-fieldname = 'CARRID'.
...
...
<b>ls_fcat-edit = 'X'.</b>
APPEND ls_fcat TO pt_fieldcat.
---Call the method below before you call the set_table_for_first_display.
<b>CALL METHOD ALV_GRID_INSTANCE->set_ready_for_input
EXPORTING
i_ready_for_input = 0. ( For Display ) and ('1' for Edit )</b>
After this put the set_table_for_first_display.
Now if the ALV data has changed,and you want to change the database or ztable,then in <b>your pf status give a function code for SAVE button in the GUI</b>.
In the PAI of the screen,in user command module write the following:
<b>WHEN 'SAVE'.
call method gr_alvgrid->check_changed_data
importing e_valid = l_valid.
if l_valid = 'X'.
MODIFY spfli FROM TABLE itab_spfli.
endif.</b>
(l_valid is a flag.
<b>DATA:l_valid type c.</b>
If you want to check if the user has entered any value on the grid, use the Method : CALL METHOD gr_alvgrid->check_changed_data.
This method returns a flag l_valid which can be checked to see if the data on the ALV grid has been changed or not.)
Regards,
Beejal
**Reward if this helps
‎2007 Jan 31 8:40 AM
‎2007 Jan 31 9:13 AM
hi,
If your internal table structure that you are sending to the ALV function module is same as that of the structure of the Z- table, u have created,then loop through the internal table and then append or insert records to your z-table.
reward points if useful,
Regards,
Pavithra
‎2007 Jan 31 9:37 AM
Hi Pavitra,
Thanks for ur reply, yes my table is of the same structure as that of the internal table , but how the modified values will come in the internal table?
‎2007 Jan 31 9:19 AM
Hi Manik,
Refer to this code snippet.
Hope this helps you. Reward points if it does.
Rgds,
Prashanth.
SAP.
DATA:
lt_toolbar_exc TYPE ui_functions,
ls_toolbar_exc TYPE ui_func,
lt_ucomm TYPE ui_functions,
* ALV
gv_pay_lk_grid TYPE REF TO cl_gui_alv_grid, "ALV Grid
gv_cust_cont TYPE REF TO cl_gui_custom_container, "Custom Cont
gv_cont_error_log TYPE REF TO cl_gui_custom_container, "Cont for Error
gs_layout TYPE lvc_s_layo, "Layout
gt_fieldcat TYPE lvc_t_fcat. "FieldCatalog tab
IF gv_pay_lk_grid IS INITIAL.
* Create Custom Container
CREATE OBJECT gv_cust_cont
EXPORTING
container_name = con_cont_0300
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
OTHERS = 6.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
* Create Custom Container for error log
CREATE OBJECT gv_cont_error_log
EXPORTING
container_name = con_cont_err_log
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
OTHERS = 6.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* Create ALV Grid
CREATE OBJECT gv_pay_lk_grid
EXPORTING
i_parent = gv_cust_cont
i_applogparent = gv_cont_error_log
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
OTHERS = 5.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.
* Register the edit event
CALL METHOD gv_pay_lk_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter
EXCEPTIONS
error = 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.
CALL METHOD gv_pay_lk_grid->set_ready_for_input
EXPORTING
i_ready_for_input = 1.
gs_layout-sel_mode = 'D'.
* Call ALV Grid
CALL METHOD gv_pay_lk_grid->set_table_for_first_display
EXPORTING
is_layout = gs_layout
it_toolbar_excluding = lt_toolbar_exc
CHANGING
it_outtab = gt_payment
it_fieldcatalog = gt_fieldcat
EXCEPTIONS
invalid_parameter_combination = 1
program_error = 2
too_many_lines = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* User commands to be processed on invalid input
ELSE.
* If alv is already displayed, refresh the alv table.
PERFORM refresh_table_display.
ENDIF.
* Flush
CALL METHOD cl_gui_cfw=>flush.
‎2007 Jan 31 9:34 AM
Hi Prashanth,
Thanks for ur help, but can you please tell me where in this code ur inserting the records in the database table,
I want to store the contents of the ALV grid in the database table.
‎2007 Jan 31 9:40 AM
Hi Manik,
That previous code was for editable ALV basically.
Here it is for saving. (in addition ot the previous code)
Rgds,
Prashanth.
SAP Labs.
PAI of the screen, call module user_command_0300.
MODULE user_command_0300 INPUT.
PERFORM handle_user_command_0300.
ENDMODULE. " USER_COMMAND_0300 INPUT
FORM handle_user_command_0300 .
DATA:
lv_ans.
CALL METHOD cl_gui_cfw=>dispatch.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN con_save.
PERFORM prepare_to_save.
PERFORM save_to_db.
...
ENDCASE.
ENDFORM. " handle_user_command_0300
FORM prepare_to_save .
DATA:
ls_pay_lk TYPE /nam/pay_lk,
ls_payment_old TYPE /nam/pay_lk,
ls_payment_del TYPE /nam/pay_lk,
ls_payment_buffer TYPE epay_pay_lk_str,
lt_msg_tab TYPE epay_msg_tab,
ls_msg TYPE epay_msg_str,
lv_pay_tabix TYPE sy-tabix,
lv_entry_date TYPE sy-datum,
lv_entry_time TYPE sy-uzeit.
If any data has been entered, get this into gt_payment
IF gv_pay_lk_grid IS NOT INITIAL.
CALL METHOD gv_pay_lk_grid->check_changed_data.
ENDIF.
PERFORM validate_all_records USING gt_payment_buffer
con_checked
gt_payment_old
CHANGING lt_msg_tab.
If any error messages, throw on screen.
READ TABLE lt_msg_tab INTO ls_msg
WITH KEY msgty = con_msg_ty_for_err.
IF sy-subrc = 0.
MESSAGE ID ls_msg-msgid TYPE ls_msg-msgty NUMBER ls_msg-msgno
WITH ls_msg-msgv1 ls_msg-msgv2 ls_msg-msgv3 ls_msg-msgv4.
ENDIF.
Set the date and time for entries to be saved to database.
lv_entry_date = sy-datum.
lv_entry_time = sy-uzeit.
LOOP AT gt_payment_buffer INTO ls_payment_buffer WHERE assignment IS
NOT INITIAL.
lv_pay_tabix = sy-tabix.
IF ls_payment_buffer-flg_data_changed = con_checked.
Add the changed data to Internal table
ls_pay_lk-mandt = sy-mandt.
ls_pay_lk-bukrs = ls_payment_buffer-bukrs.
ls_pay_lk-assignment = ls_payment_buffer-assignment.
ls_pay_lk-entry_date = lv_entry_date.
ls_pay_lk-entry_time = lv_entry_time.
ls_pay_lk-payment_amount = ls_payment_buffer-payment_amount.
ls_pay_lk-tip_amount = ls_payment_buffer-tip_amount.
ls_pay_lk-nie_amount = ls_payment_buffer-nie_amount.
ls_pay_lk-waers = ls_payment_buffer-currency.
ls_pay_lk-xposted = space.
ls_pay_lk-keyz1 = space.
APPEND ls_pay_lk TO gt_pay_lk.
Its an old record
CLEAR ls_payment_old.
IF ls_payment_buffer-old_rec = con_checked.
READ TABLE gt_payment_old INTO ls_payment_old
WITH KEY bukrs = ls_payment_buffer-bukrs
assignment = ls_payment_buffer-assignment
entry_date = ls_payment_buffer-entry_date
entry_time = ls_payment_buffer-entry_time.
IF sy-subrc = 0.
Add this record to internal table to delete the rec from DB.
ls_payment_del = ls_payment_old.
APPEND ls_payment_del TO gt_payment_del.
ENDIF.
ENDIF.
Mark OLD_REC flg in alv table, update date/time in ALV tables.
ls_payment_buffer-old_rec = con_checked.
ls_payment_buffer-entry_date = lv_entry_date.
ls_payment_buffer-entry_time = lv_entry_time.
MODIFY gt_payment_buffer FROM ls_payment_buffer INDEX lv_pay_tabix
TRANSPORTING old_rec entry_date entry_time.
MODIFY gt_payment FROM ls_payment_buffer INDEX lv_pay_tabix
TRANSPORTING old_rec entry_date entry_time.
CLEAR:
lv_pay_tabix,
ls_pay_lk.
ENDIF.
ENDLOOP.
ENDFORM. " prepare_to_save
FORM save_to_db.
DATA:
ls_payment TYPE epay_pay_lk_str.
IF gt_pay_lk[] IS NOT INITIAL OR gt_payment_del[] IS NOT INITIAL.
Insert/Modify records in DB
IF gt_pay_lk IS NOT INITIAL.
MODIFY /nam/pay_lk FROM TABLE gt_pay_lk.
REFRESH gt_pay_lk[].
ENDIF.
IF gt_payment_del[] IS NOT INITIAL.
Delete records from DB
DELETE /nam/pay_lk FROM TABLE gt_payment_del.
REFRESH gt_payment_del[].
ENDIF.
COMMIT WORK.
Status: The entries have been saved to database.
MESSAGE s013(/nam/nae_messages).
Reload old records.
SELECT * FROM /nam/pay_lk
INTO TABLE gt_payment_old
WHERE bukrs = gs_pay_header-bukrs
AND entry_date BETWEEN gs_pay_header-entry_date_low
AND gs_pay_header-entry_date_high.
Reset Flg_Data_Changed for alv tables => fresh start
CLEAR ls_payment-flg_data_changed.
MODIFY gt_payment FROM ls_payment
TRANSPORTING flg_data_changed
WHERE assignment IS NOT INITIAL.
MODIFY gt_payment_buffer FROM ls_payment
TRANSPORTING flg_data_changed
WHERE assignment IS NOT INITIAL.
ELSE.
*Status: No changes have been made, and hence nothing saved to database.
MESSAGE s020(/nam/nae_messages).
ENDIF.
ENDFORM. " save_to_db
‎2007 Jan 31 10:03 AM
Hi Prashanth.
Thanks a lot for ur code,
But I am not able to get come things in the code like
1> What is gt_pay_lk
2> What is gt_payment_buffer
3>Can u please send the code for the following subroutine
PERFORM validate_all_records USING gt_payment_buffer
con_checked
gt_payment_old
CHANGING lt_msg_tab.
4> not able to get these
ls_pay_lk TYPE /nam/pay_lk,
ls_payment_old TYPE /nam/pay_lk,
ls_payment_del TYPE /nam/pay_lk,
ls_payment_buffer TYPE epay_pay_lk_str,
‎2007 Jan 31 10:26 AM
Gt_pay_lk is the table which has the actual data for ALV.
No use giving you the structure of that because it is typed to a custom table.
you have to just have it as ur own data table,
U can ignore the logic of buffer, etc.
Obviously i have not sent you the entire code because it is voluminous.
I have concept of buffering, Db records, etc.
gt_payment_buffer is the buffer - u can ignore.
validate_all_records is also not important. just comment it for now. It is the vlaidation routine.
ls_pay_lk is a structure of the same type as gt_pay_lk.
ls_payment_old TYPE /nam/pay_lk,
ls_payment_del TYPE /nam/pay_lk,
ls_payment_buffer TYPE epay_pay_lk_str,
=> all 3 u can currently ignore.
Also comment out that part of code, because it is hte buffering and comparison against the old/Db record to see what data has changed.
con_checked is a constant. Value = 'X'.
hope it helps.
Message was edited by:
Prashanth Prabhu
‎2007 Jan 31 10:20 AM
Hello Manik,
To modify database or ztable from the ALV grid,you need to do the following:
---You have to modify the field Catalog fields (fields that you want to make editable).Set the field EDIT as 'X'.For example if you want to make the field below editable:
ls_fcat-fieldname = 'CARRID'.
...
...
<b>ls_fcat-edit = 'X'.</b>
APPEND ls_fcat TO pt_fieldcat.
---Call the method below before you call the set_table_for_first_display.
<b>CALL METHOD ALV_GRID_INSTANCE->set_ready_for_input
EXPORTING
i_ready_for_input = 0. ( For Display ) and ('1' for Edit )</b>
After this put the set_table_for_first_display.
Now if the ALV data has changed,and you want to change the database or ztable,then in <b>your pf status give a function code for SAVE button in the GUI</b>.
In the PAI of the screen,in user command module write the following:
<b>WHEN 'SAVE'.
call method gr_alvgrid->check_changed_data
importing e_valid = l_valid.
if l_valid = 'X'.
MODIFY spfli FROM TABLE itab_spfli.
endif.</b>
(l_valid is a flag.
<b>DATA:l_valid type c.</b>
If you want to check if the user has entered any value on the grid, use the Method : CALL METHOD gr_alvgrid->check_changed_data.
This method returns a flag l_valid which can be checked to see if the data on the ALV grid has been changed or not.)
Regards,
Beejal
**Reward if this helps
‎2007 Feb 02 8:52 AM
Hi Beejal,
Thanks for ur help but can you please tell me from where the modified data from the grid will come in to the internal table itab_spfli.
Thanks.
Regards
Manik
‎2007 Feb 03 9:28 AM
Hi Manik,
We pass the internal table itab_spfli in the alv method SET_TABLE_FOR_FIRST_DISPLAY.What you see on the grid(at the user interface) is the contents of the internal table.<b>Internal table behaves like a work area.Any changes made to the grid is actually changing the internal table itself.</b><b>Even if you have only an editable ALV and no method to make changes at the database level,and keep a breakpoint on itab_spfli,you will notice that the contents of itab_spfli are automatically changed.</b>But these changes are not made at the database level.So if you execute your program again,the program will fetch data from the database table (not from the internal table) and you dont get the modified data.
In this code:
WHEN 'SAVE'.
call method gr_alvgrid->check_changed_data
importing e_valid = l_valid.
if l_valid = 'X'.
MODIFY spfli FROM TABLE itab_spfli.<<<BREAK-POINT
endif.
The method check_changed_data checks if there is a change in the internal table and then we can modify DB table as well.
You can keep a break point at the internal table itab_spfli and see that contents of itab_spfli are changed(at the GUI) when you edit the ALV but SPFLI is not changed till the "modify" statement is executed.
Regards,
Beejal