*&---------------------------------------------------------------------* *& Module pool ZFIVE_002 *& *&---------------------------------------------------------------------* *& *& *&---------------------------------------------------------------------*
INCLUDE zfive_002top. INCLUDE . " global Data
START-OF-SELECTION. data: l_index TYPE i. SELECT * FROM sflight INTO CORRESPONDING FIELDS OF wa_info WHERE carrid IN p_car order by primary key. wa_info-free = wa_info-seatsmax - wa_info-seatsocc. IF wa_info-seatsmax < wa_info-seatsocc. wa_info-free_icon = icon_red_light. ELSE. wa_info-free_icon = icon_green_light. ENDIF. APPEND wa_info TO it_info. ENDSELECT.
* loop at it_info into wa_info. * if wa_info-seatsmax > 300. ** wa_info-checkbox = 'X'." can't combine with get_style. value. * ls_stylerow-fieldname = 'CHECKBOX' . * ls_stylerow-style. = cl_gui_alv_grid=>mc_style_disabled. * APPEND ls_stylerow TO wa_info-field_style. * modify it_info from wa_info. * endif. * if wa_info-seatsmax < 300. * wa_info-checkbox = 'X'." can't combine with get_style. value. * modify it_info from wa_info. * endif. * endloop. LOOP AT it_info . l_index = sy-tabix. refresh lt_celltab. if wa_info-seatsmax > 300. perform. fill_celltab using 'RW' changing lt_celltab. else. perform. fill_celltab using 'RO' changing lt_celltab. endif. *§2c.Copy your celltab to the celltab of the current row of gt_outtab. INSERT LINES OF lt_celltab INTO TABLE it_info-field_style. MODIFY it_info INDEX l_index. ENDLOOP. CALL SCREEN 100.
INCLUDE zfive_002_status_0100o01.
*&---------------------------------------------------------------------* *& Include ZFIVE_002TOP Module pool ZFIVE_002 *& *&---------------------------------------------------------------------*
PROGRAM zfive_002 no standard page heading line-count 10.
types: begin of info, checkbox type c, carrid like sflight-carrid, connid like sflight-connid, fldate like sflight-fldate, price like sflight-price, currency like sflight-currency, seatsmax like sflight-seatsmax, seatsocc like sflight-seatsocc, free like sflight-seatsmax, free_icon(30), field_style. type lvc_t_styl, end of info.
DATA:wa_info type info, it_info type standard table of info with header line.
* Field position data: pos_free type i value 8, pos_icon type i value 9.
* Fieldcatalog data: p_fieldcat type lvc_t_fcat, w_fieldcat like line of p_fieldcat, wa_sbook like sbook.
*control DATA: p_control_contianter TYPE REF TO cl_gui_custom_container, alv_grid TYPE REF TO cl_gui_alv_grid.
DATA:ok_code LIKE sy-ucomm. *layout DATA:gs_layout TYPE lvc_s_layo.
DATA: GS_REPORT TYPE DISVARIANT, P_SAVE.
data :lt_celltab TYPE lvc_t_styl.
* Local class class list_d definition. public section. methods on_dblclick for event double_click of cl_gui_alv_grid importing e_row e_column. endclass. "list_d DEFINITION
*local class to handle semantic checks class lcl_event_receiver definition deferred.
data: g_verifier type ref to lcl_event_receiver.
*---------------------------------------------------------------------* * CLASS lcl_event_receiver DEFINITION *---------------------------------------------------------------------* * ........ * *---------------------------------------------------------------------* class lcl_event_receiver definition.
*.............
public section.
types: begin of sflight_key. types: carrid type s_carr_id. types: connid type s_conn_id. types: fldate type s_date. types: end of sflight_key.
types: sflight_keys type standard table of sflight_key, sflight_table type standard table of sflight.
methods: handle_data_changed for event data_changed of cl_gui_alv_grid importing er_data_changed.
methods: get_inserted_rows exporting inserted_rows type sflight_keys.
methods: get_deleted_rows exporting deleted_rows type sflight_table.
methods: refresh_delta_tables.
methods: set_table_is_initial.
methods: set_table_is_not_initial.
methods: table_is_initial returning value(initial) type char01.
*..............
private section.
* §4.Define internal tables to remember inserted and deleted lines, * thus the delta between input made after the last saving.
data: inserted_rows type sflight_keys, deleted_rows type standard table of sflight.
* This flag is set if any error occured in one of the * following methods: data: error_in_data type c.
* This flag signals that no records were read for the flight * table initially: data: initial_table type c. ** Methods to modularize event handler method HANDLE_DATA_CHANGED: * methods: update_delta_tables importing pr_data_changed type ref to cl_alv_changed_data_protocol.
methods: perform_semantic_checks importing pr_data_changed type ref to cl_alv_changed_data_protocol.
methods: get_cell_values importing row_id type int4 pr_data_changed type ref to cl_alv_changed_data_protocol exporting key type sflight_key.
endclass.
**--------------------------------------------------------- class lcl_event_receiver implementation. method handle_data_changed. * data: ls_good type lvc_s_modi, l_price type s_price, ls_new type lvc_s_moce.
error_in_data = space.
* remember new or deleted lines for saving call method update_delta_tables( er_data_changed ).
* check mt_good_cells semantically call method perform_semantic_checks( er_data_changed ).
if error_in_data = 'X'. call method er_data_changed->display_protocol. endif.
endmethod.
*------------------------------------------------------- method update_delta_tables. data: l_ins_row type lvc_s_moce, l_del_row type lvc_s_moce, ls_key type sflight_key, ls_sflight type sflight, ls_outtab like line of it_info.
* §6.Use protocol attributes MT_DELETED_ROWS and MT_INSERTED_ROWS * to remember which lines where deleted or inserted. Save this * information in your internal tables.
*.......... * deleted rows *............. loop at pr_data_changed->mt_deleted_rows into l_del_row. read table it_info into ls_outtab index l_del_row-row_id. if sy-subrc ne 0. message i000(0k) with text-e01."Fehler beim Löschen else. move-corresponding ls_outtab to ls_sflight. * It should no be possible that the same line is deleted twice, * so we just add the new key line to 'deleted_rows'. append ls_sflight to deleted_rows. * If this line was inserted just before it is deleted: delete me->inserted_rows where carrid = ls_outtab-carrid and connid = ls_outtab-connid and fldate = ls_outtab-fldate. endif. endloop.
*.......... * inserted rows * At this point ALV has not added new lines * to it_info, so you can not access their values * by reading it_info. * Table MT_GOOD_CELLS holds new values that can be * referenced using the ROW_ID. *.......... if me->table_is_initial( ) eq 'X'. * No flights were selected initially. This is the first new line. call method get_cell_values exporting row_id = 1 pr_data_changed = pr_data_changed importing key = ls_key.
append ls_key to inserted_rows. call method me->set_table_is_not_initial. endif.
loop at pr_data_changed->mt_inserted_rows into l_ins_row. call method get_cell_values exporting row_id = l_ins_row-row_id pr_data_changed = pr_data_changed importing key = ls_key. * READ TABLE it_info INTO ls_outtab INDEX l_ins_row-row_id.
* Just insert the new row regardless if the input is wrong append ls_key to inserted_rows. endloop.
endmethod. *--------------------------------------------------------- method get_cell_values. * get values of key cells of row ROW_ID
* CARRIER call method pr_data_changed->get_cell_value exporting i_row_id = row_id i_fieldname = 'CARRID' importing e_value = key-carrid.
if sy-subrc ne 0. message i000(0k) with text-e02. "Fehler beim Einfügen endif. * CONNID call method pr_data_changed->get_cell_value exporting i_row_id = row_id i_fieldname = 'CONNID' importing e_value = key-connid.
if sy-subrc ne 0. message i000(0k) with text-e02. "Fehler beim Einfügen endif.
* FLDATE call method pr_data_changed->get_cell_value exporting i_row_id = row_id i_fieldname = 'FLDATE' importing e_value = key-fldate.
if sy-subrc ne 0. message i000(0k) with text-e02. "Fehler beim Einfügen endif.
endmethod.
*--------------------------------------------------------- method perform_semantic_checks. data: ls_good type lvc_s_modi, l_planetype type s_planetye, l_seatsmax type s_seatsmax.
loop at pr_data_changed->mt_good_cells into ls_good. case ls_good-fieldname. when 'PLANETYPE'. call method pr_data_changed->get_cell_value exporting i_row_id = ls_good-row_id i_fieldname = ls_good-fieldname importing e_value = l_planetype.
select single seatsmax from saplane into l_seatsmax where planetype = l_planetype.
if sy-subrc ne 0. call method pr_data_changed->add_protocol_entry exporting i_msgid = '0K' i_msgno = '000' i_msgty = 'E' i_msgv1 = text-m02 i_fieldname = ls_good-fieldname i_row_id = ls_good-row_id.
error_in_data = 'X'. else.
call method pr_data_changed->modify_cell exporting i_row_id = ls_good-row_id i_fieldname = 'SEATSMAX' i_value = l_seatsmax. endif. endcase. endloop. endmethod.
*------------------------------------------------------
method get_inserted_rows. inserted_rows = me->inserted_rows. endmethod. *------------------------------------------------------
method get_deleted_rows. deleted_rows = me->deleted_rows. endmethod. *------------------------------------------------------ method refresh_delta_tables. clear me->inserted_rows[]. clear me->deleted_rows[]. endmethod. *------------------------------------------------------ method set_table_is_initial. initial_table = 'X'. endmethod. *------------------------------------------------------ method set_table_is_not_initial. initial_table = space. endmethod. *------------------------------------------------------ method table_is_initial. if initial_table = 'X'. initial = 'X'. else. initial = space. endif. endmethod.
endclass.
* Double Click data: p_double type ref to list_d.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME. SELECT-OPTIONS:p_car FOR wa_info-carrid. SELECTION-SCREEN END OF BLOCK b2.
*----------------------------------------------------------------------* ***INCLUDE ZFIVE_002_STATUS_0100O01 . *----------------------------------------------------------------------* *&---------------------------------------------------------------------* *& Module STATUS_0100 OUTPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE status_0100 OUTPUT. SET PF-STATUS 'S100'. SET TITLEBAR 'T100' WITH 'five'.
ENDMODULE. " STATUS_0100 OUTPUT *&---------------------------------------------------------------------* *& Module CREATE_OBJECTS OUTPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE create_objects OUTPUT. IF p_control_contianter IS INITIAL. CREATE OBJECT p_control_contianter EXPORTING container_name = 'P_CONTROL'. CREATE OBJECT alv_grid EXPORTING i_parent = p_control_contianter.
CREATE OBJECT p_double. set handler p_double->on_dblclick for alv_grid. ENDIF.
ENDMODULE. " CREATE_OBJECTS OUTPUT *&---------------------------------------------------------------------* *& Module TRANSFER_DATA OUTPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE transfer_data OUTPUT. CALL METHOD alv_grid->set_table_for_first_display EXPORTING i_structure_name = 'SFLIGHT' is_layout = gs_layout is_variant = gs_report i_save = p_save CHANGING it_outtab = it_info[] it_fieldcatalog = p_fieldcat.
ENDMODULE. " TRANSFER_DATA OUTPUT *&---------------------------------------------------------------------* *& Module exit INPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE exit INPUT. LEAVE PROGRAM. ENDMODULE. " exit INPUT *&---------------------------------------------------------------------* *& Module USER_COMMAND_0100 INPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE user_command_0100 INPUT. CASE ok_code. WHEN 'BACK'. CALL METHOD p_control_contianter->free. SET SCREEN 0. WHEN 'EXIT'. PERFORM. switch_edit_mode. when 'SAVE'. perform. save_data. ENDCASE. ENDMODULE. " USER_COMMAND_0100 INPUT *&---------------------------------------------------------------------* *& Module layout_data OUTPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE layout_data OUTPUT. gs_layout-grid_title = 'five test'. gs_layout-detailtitl = 'test'. gs_layout-zebra = 'X'. gs_layout-cwidth_opt = 'X'. * gs_layout-EDIT = 'X'. gs_layout-SEL_MODE = 'C'. gs_layout-stylefname = 'FIELD_STYLE'. ENDMODULE. " layout_data OUTPUT *&---------------------------------------------------------------------* *& Module field_catalog OUTPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE field_catalog OUTPUT. CLEAR w_fieldcat. w_fieldcat-fieldname = 'CHECKBOX'. w_fieldcat-coltext = 'select'. w_fieldcat-seltext = 'select'. w_fieldcat-checkbox = 'X'. w_fieldcat-col_pos = 0 . w_fieldcat-tooltip = 'sdfasg'. * w_fieldcat-edit = 'X'. APPEND w_fieldcat TO p_fieldcat.
CLEAR w_fieldcat. w_fieldcat-fieldname = 'FREE'. w_fieldcat-ref_table = 'SFILGHT'. w_fieldcat-ref_field = 'SEATSMAX'. w_fieldcat-coltext = 'FIVE TEST'. w_fieldcat-seltext = 'FIVE TEST'. w_fieldcat-col_pos = pos_free. APPEND w_fieldcat TO p_fieldcat.
CLEAR w_fieldcat. w_fieldcat-fieldname = 'FREE_ICON'. w_fieldcat-icon = 'X'.
w_fieldcat-coltext = 'FREE_ICON'. w_fieldcat-seltext = 'FREE_ICON'. w_fieldcat-col_pos = pos_icon. APPEND w_fieldcat TO p_fieldcat. ENDMODULE. " field_catalog OUTPUT *&---------------------------------------------------------------------* *& Module VARIANT OUTPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE variant OUTPUT. gs_report-report = sy-repid. p_save = 'A'. ENDMODULE. " VARIANT OUTPUT *&---------------------------------------------------------------------* *& Module list OUTPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE list OUTPUT. SUPPRESS DIALOG. SET PF-STATUS space. WRITE:'basic'. LEAVE TO LIST-PROCESSING AND RETURN TO SCREEN 0. FORMAT COLOR COL_NORMAL. SELECT * FROM sbook INTO CORRESPONDING FIELDS OF wa_sbook WHERE carrid = wa_info-carrid AND connid = wa_info-connid AND fldate = wa_info-fldate. WRITE:/ sy-vline, wa_sbook-carrid, wa_sbook-connid, wa_sbook-fldate, wa_sbook-customid, wa_sbook-bookid, 83 sy-vline. ENDSELECT. ENDMODULE. " list OUTPUT *&---------------------------------------------------------------------* *& Class (Implementation) list_d *&---------------------------------------------------------------------* * Text *----------------------------------------------------------------------* CLASS list_d IMPLEMENTATION. METHOD on_dblclick. * valid line check IF e_row-rowtype = space AND NOT e_row-index IS INITIAL. READ TABLE it_info INDEX e_row-index INTO wa_info. CALL SCREEN 101. ELSE. MESSAGE 'no data' TYPE 'I'. ENDIF. ENDMETHOD. "dbclick ENDCLASS. "list_d
FORM. fill_celltab using value(p_mode) CHANGING pt_celltab TYPE lvc_t_styl. DATA: ls_celltab TYPE lvc_s_styl, l_mode type raw4. * This forms sets the style. of column 'PRICE' editable * according to 'p_mode' and the rest to read only either way.
IF p_mode EQ 'RW'. *§2a.Use attribute CL_GUI_ALV_GRID=>MC_STYLE_ENABLED to set a cell * to status "editable". l_mode = cl_gui_alv_grid=>mc_style_enabled. ELSE. "p_mode eq 'RO' *§2b.Use attribute CL_GUI_ALV_GRID=>MC_STYLE_DISABLED to set a cell * to status "non-editable". l_mode = cl_gui_alv_grid=>mc_style_disabled. ENDIF.
ls_celltab-fieldname = 'CARRID'. ls_celltab-style. = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'CONNID'. ls_celltab-style. = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'FLDATE'. ls_celltab-style. = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'PRICE'. ls_celltab-style. = l_mode. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'CURRENCY'. ls_celltab-style. = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'SEATSMAX'. ls_celltab-style. = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'SEATSOCC'. ls_celltab-style. = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab.
ENDFORM. " FILL_CELLTAB
FORM. switch_edit_mode.
IF alv_grid->is_ready_for_input( ) eq 0. * set edit enabled cells ready for input CALL METHOD alv_grid->set_ready_for_input EXPORTING i_ready_for_input = 1.
ELSE. * lock edit enabled cells against input CALL METHOD alv_grid->set_ready_for_input EXPORTING i_ready_for_input = 0. ENDIF. ENDFORM. " SWITCH_EDIT_MODE
form. save_data. data: l_valid type c. * §7.Check if any errors exist in protocol by using method * CHECK_CHANGED_DATA of your ALV Grid instance.
* The method CHECK_CHANGED_DATA checks all new cells syntactically, * raises event DATA_CHANGED and looks then for any entries * in the error protocol. If any exist the parameter e_valid * is initial ('X' in the other case). * *DATA: ANSWER(1) TYPE C. * * *CALL FUNCTION 'POPUP_TO_CONFIRM_WITH_MESSAGE' *EXPORTING TITLE = 'Make selection' * DIAGNOSISTEXT1 = 'No plan alternative' * DIAGNOSISTEXT2 = 'exists for the specified' * DIAGNOSISTEXT3 = 'selection criteria.' * TEXTLINE1 = 'Do you want to create a' * TEXTLINE2 = 'new plan alternative?' *IMPORTING ANSWER = ANSWER.
call method ALV_GRID->check_changed_data importing e_valid = l_valid.
if l_valid is initial. call function 'POPUP_TO_INFORM' exporting titel = 'pls choose the data' txt1 = text-i07 txt2 = text-i08 txt3 = text-i09.
else. perform. update_database. message s000(0k) with text-s01. endif. endform.
form. update_database. data: lt_del_rows type table of sflight, lt_ins_keys type g_verifier->sflight_keys, l_ins_key type g_verifier->sflight_key, ls_sflight type sflight, ls_outtab like line of it_info, lt_instab type table of sflight.
* §8.When all values are valid, use your internal tables * to update your table on the database.
*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * IMPORTANT: This method has been disabled, as the program logic * was erroneous: if a user doubled a line (insert with copied values) * the data is not accepted by alv, so the line inserted in the table * had initial values. If he then deleted the line, the deleted line * also had initial values. On the other hand, the line stored as * inserted was the line with the original, copied values. So the * data base was updated with hte copied values which lead to a * short dump. *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* First delete lines in data base according to the * keys you remembered within 'g_verifier'. * Imagine a user deleted a row and then entered one with * the same key fields like the deleted ones. * Then both tables (deleted_rows, inserted_rows) have got * an entry of this row. * So if you first inserted the new rows in the data base * and then deleted rows according to 'deleted_rows' * The reentered rows would be lost. * * 1.Delete Lines: call method g_verifier->get_deleted_rows importing deleted_rows = lt_del_rows.
delete sflight from table lt_del_rows.
* 2.Insert Lines: call method g_verifier->get_inserted_rows importing inserted_rows = lt_ins_keys.
loop at lt_ins_keys into l_ins_key. read table it_info into ls_outtab with key carrid = l_ins_key-carrid connid = l_ins_key-connid fldate = l_ins_key-fldate. if sy-subrc eq 0. move-corresponding ls_outtab to ls_sflight. append ls_sflight to lt_instab. endif. endloop.
insert sflight from table lt_instab.
* §9.Refresh your internal tables.
call method g_verifier->refresh_delta_tables.
endform.