overview | << previous | next >> |
The concept of a selection screen variant is something that most SAP users have come to expect, yet this feature is unavailable in standard Web Dynpro. Below is the next in a series of posts detailing how to bring this necessary feature back to Web Dynpro. Start here to see the full requirements.
Let’s wrap this series up – we’re getting close. Below is the flow of the Save operation. When the user clicks the button, the BTN_SAVE_CLICK event is fired:
1: METHOD onactionbtn_save_click . " PLM8034
2:
3: wd_comp_controller->fire_before_save_evt( ).
4: wd_comp_controller->m_clear_msgs = abap_true.
5: me->prompt_to_save( ).
6:
7: ENDMETHOD.
The PROMPT_TO_SAVE method then displays the W_SAVE_VARIANT window and waits for the [OK] button.
1: METHOD prompt_to_save . " PLM8034
2:
3: DATA: lo_window_manager TYPE REF TO if_wd_window_manager,
4: lo_api_component TYPE REF TO if_wd_component,
5: lo_window TYPE REF TO if_wd_window,
6: lo_api TYPE REF TO if_wd_view_controller.
7:
8: lo_api = wd_this->wd_get_api( ).
9: lo_api_component = wd_comp_controller->wd_get_api( ).
10: lo_window_manager = lo_api_component->get_window_manager( ).
11:
12: wd_comp_controller->refresh_variant_fields( ).
13:
14: lo_window = lo_window_manager->create_window(
15: window_name = 'W_SAVE_VARIANT'
16: title = 'Save Variant'
17: button_kind = if_wd_window=>co_buttons_okcancel
18: close_button = abap_true ).
19: lo_window->subscribe_to_button_event(
20: button = if_wd_window=>co_button_ok
21: action_name = 'SAVE_OK'
22: action_view = lo_api
23: is_default_button = abap_true ).
24:
25: lo_window->open( ).
26:
27: ENDMETHOD.
The neat thing about this selection screen variant implementation is that it offers the user the ability to save dynamic date parameters. The W_SAVE_VARIANT window uses ALV (usage 2) to display a list of fields for this purpose. We’ll go into more detail on that in the next post. For now, let’s focus on saving the variant.
The view V_SAVE_VARIANT shows the variant name and description. Also available is the ability to “lock” the variant for use only by a single user id. Finally the list of fields from all attached selection screens.
Again, the view has an INIT_ALV routine to set up ALV2. It is called from the WDDOINIT method. Here’s a better look at the “clear messages” mentioned back in the Get Variant section:
1: METHOD wddoinit . " PLM8034
2:
3: wd_this->init_alv( ).
4:
5: DATA: lr_controller TYPE REF TO if_wd_controller,
6: lr_msgman TYPE REF TO if_wd_message_manager,
7: l_msg TYPE string.
8: IF wd_comp_controller->m_clear_msgs = abap_true.
9: lr_controller ?= wd_this->wd_get_api( ).
10: lr_msgman = lr_controller->get_message_manager( ).
11: lr_msgman->clear_messages( ).
12: ENDIF.
13:
14: ENDMETHOD.
After the variant name and description are entered, the user presses the [OK] button. Once pressed, the MAIN view SAVE_OK action is fired. In the ONACTIONSAVE_OK routine, we need to check for validity and existence and react accordingly.
1: METHOD onactionsave_ok . " PLM8034
2:
3: DATA: l_exists TYPE xfeld,
4: l_invalid TYPE xfeld.
5: wd_comp_controller->check_save_variant( IMPORTING: e_invalid = l_invalid
6: e_exists = l_exists ).
7:
8: IF l_invalid = abap_true.
9: wd_comp_controller->m_clear_msgs = abap_false.
10: me->prompt_to_save( ).
11: ELSEIF l_exists = abap_true.
12: me->prompt_overwrite( ).
13: ELSE.
14: me->save_variant( ).
15: ENDIF.
16:
17: ENDMETHOD.
The PROMPT_OVERWRITE routine uses a popup window for user confirmation.
1: METHOD prompt_overwrite . " PLM8034
2:
3: DATA: lo_nd_in TYPE REF TO if_wd_context_node.
4: lo_nd_in = wd_context->get_child_node( name = wd_this->wdctx_in ).
5:
6: DATA: l_variant_name TYPE variant.
7: lo_nd_in->get_attribute( EXPORTING: name = 'VARIANT_NAME'
8: IMPORTING: value = l_variant_name ).
9:
10: DATA: lo_window_manager TYPE REF TO if_wd_window_manager,
11: lo_api_component TYPE REF TO if_wd_component,
12: lo_window TYPE REF TO if_wd_window,
13: lo_api TYPE REF TO if_wd_view_controller.
14:
15: lo_api = wd_this->wd_get_api( ).
16: lo_api_component = wd_comp_controller->wd_get_api( ).
17: lo_window_manager = lo_api_component->get_window_manager( ).
18:
19: DATA: lt_msgs TYPE string_table,
20: l_msg TYPE string.
21: MESSAGE i627(db) INTO l_msg WITH l_variant_name.
22: APPEND l_msg TO lt_msgs.
23: MESSAGE i041(sapbc_global) INTO l_msg.
24: APPEND l_msg TO lt_msgs.
25:
26: lo_window = lo_window_manager->create_popup_to_confirm(
27: text = lt_msgs
28: window_title = 'Overwrite Variant?'
29: button_kind = if_wd_window=>co_buttons_okcancel
30: close_button = abap_true ).
31: lo_window->subscribe_to_button_event(
32: button = if_wd_window=>co_button_ok
33: action_name = 'SAVE_CONFIRM'
34: action_view = lo_api
35: is_default_button = abap_true ).
36:
37: lo_window->open( ).
38:
39: ENDMETHOD.
After a valid variant name has been identified, the component controller’s SAVE_VARIANT routine does the real work. First, we update a few header fields: program, variant, change date, etc. Then we get the field values in GET_FIELDS. Finally, we save it to storage with the EXPORT TO DATABASE statement.
1: METHOD save_variant . " PLM8034
2:
3: **********************************************************************
4: * Used a combination of the following two posts for variants.
5: * http://www.sdn.sap.com/irj/scn/index?rid=/library/uuid/f028c2b9-1730-2d10-71ae-ce300ea00573
6: * http://wiki.sdn.sap.com/wiki/display/Snippets/Variant+with+Web+dynpro+application+(+Save+or++Read+)
7: **********************************************************************
8:
9: TYPES: BEGIN OF ty_dbkey,
10: prog_name TYPE zes_wdvari-prog_name,
11: vari_name TYPE zes_wdvari-vari_name,
12: END OF ty_dbkey.
13:
14: DATA: lr_controller TYPE REF TO if_wd_controller,
15: lr_msgman TYPE REF TO if_wd_message_manager,
16: l_msg TYPE string.
17: lr_controller ?= wd_this->wd_get_api( ).
18: lr_msgman = lr_controller->get_message_manager( ).
19:
20: DATA: lo_nd_in TYPE REF TO if_wd_context_node.
21: lo_nd_in = wd_context->get_child_node( name = wd_this->wdctx_in ).
22:
23: DATA: l_repid TYPE repid.
24: lo_nd_in->get_attribute( EXPORTING: name = 'REPID'
25: IMPORTING: value = l_repid ).
26:
27: DATA: l_variant_name TYPE variant.
28: lo_nd_in->get_attribute( EXPORTING: name = 'VARIANT_NAME'
29: IMPORTING: value = l_variant_name ).
30:
31: DATA: ls_wdvari TYPE zes_wdvari.
32:
33: SELECT SINGLE prog_name vari_name protected
34: ename edat etime
35: aename aedat aetime
36: INTO CORRESPONDING FIELDS OF ls_wdvari
37: FROM zes_wdvari
38: WHERE relid = 'WD'
39: AND prog_name = l_repid
40: AND vari_name = l_variant_name.
41: IF sy-subrc = 0.
42: ls_wdvari-aename = sy-uname.
43: ls_wdvari-aedat = sy-datum.
44: ls_wdvari-aetime = sy-uzeit.
45: ELSE.
46: ls_wdvari-ename = sy-uname.
47: ls_wdvari-edat = sy-datum.
48: ls_wdvari-etime = sy-uzeit.
49: ENDIF.
50:
51: IF ls_wdvari-protected = abap_true AND
52: ls_wdvari-ename NE sy-uname.
53: MESSAGE e647(db) INTO l_msg WITH l_variant_name.
54: lr_msgman->report_error_message( l_msg ).
55: RETURN.
56: ENDIF.
57:
58: lo_nd_in->get_attribute( EXPORTING: name = 'VARIANT_DESC'
59: IMPORTING: value = ls_wdvari-vtext ).
60: lo_nd_in->get_attribute( EXPORTING: name = 'PROTECTED'
61: IMPORTING: value = ls_wdvari-protected ).
62:
63: DATA: lt_values TYPE TABLE OF zes_vuvvalues.
64: lt_values = me->get_fields( ).
65:
66: DATA: ls_key TYPE ty_dbkey.
67: ls_wdvari-prog_name = l_repid.
68: ls_wdvari-vari_name = l_variant_name.
69: MOVE-CORRESPONDING ls_wdvari TO ls_key.
70:
71: EXPORT datatable = lt_values
72: TO DATABASE zes_wdvari(wd)
73: FROM ls_wdvari
74: ID ls_key.
75:
76: IF sy-subrc = 0.
77: MESSAGE s617(db) INTO l_msg WITH l_variant_name.
78: lr_msgman->report_success( l_msg ).
79: ELSE.
80: MESSAGE s621(db) INTO l_msg WITH l_variant_name.
81: lr_msgman->report_error_message( l_msg ).
82: ENDIF.
83:
84: ENDMETHOD.
The GET_FIELDS routine has the job of retrieving all field values from all attached selection screens.
1: METHOD get_fields . " PLM8034
2:
3: DATA: lo_selopt TYPE REF TO if_wd_select_options.
4: DATA: lt_fields TYPE if_wd_select_options=>tt_selection_screen_item,
5: ls_field LIKE LINE OF lt_fields.
6: DATA: lt_all_fields LIKE lt_fields.
7: DATA: lr_param_value TYPE REF TO data.
8: DATA: lt_range_table TYPE REF TO data.
9: FIELD-SYMBOLS: <l_param_value> TYPE ANY.
10: FIELD-SYMBOLS: <lt_range_table> TYPE STANDARD TABLE.
11: FIELD-SYMBOLS: <ls_range> TYPE ANY.
12: FIELD-SYMBOLS: <ls_field> LIKE LINE OF rt_result.
13:
14: CLEAR: lt_all_fields[].
15:
16: LOOP AT wd_assist->selopt_screens INTO lo_selopt.
17:
18: CLEAR: lt_fields.
19: lo_selopt->get_parameter_fields( IMPORTING et_fields = lt_fields ).
20: LOOP AT lt_fields INTO ls_field.
21: lr_param_value = lo_selopt->get_value_of_parameter_field( ls_field-m_id ).
22: ASSIGN lr_param_value->* TO <l_param_value>.
23: CHECK sy-subrc = 0.
24:
25: APPEND INITIAL LINE TO rt_result ASSIGNING <ls_field>.
26: <ls_field>-paramid = ls_field-m_id.
27: <ls_field>-kind = 'P'.
28: <ls_field>-sign = 'I'.
29: <ls_field>-option = 'EQ'.
30: <ls_field>-low = <l_param_value>.
31: wd_this->get_field_params( CHANGING ct_field = <ls_field> ).
32:
33: ENDLOOP.
34:
35: CLEAR: lt_fields.
36: lo_selopt->get_selection_fields( IMPORTING et_fields = lt_fields ).
37: LOOP AT lt_fields INTO ls_field.
38: lt_range_table = lo_selopt->get_range_table_of_sel_field( ls_field-m_id ).
39: ASSIGN lt_range_table->* TO <lt_range_table>.
40: CHECK sy-subrc = 0.
41:
42: LOOP AT <lt_range_table> ASSIGNING <ls_range>.
43: APPEND INITIAL LINE TO rt_result ASSIGNING <ls_field>.
44: <ls_field>-paramid = ls_field-m_id.
45: <ls_field>-kind = 'S'.
46: MOVE-CORRESPONDING <ls_range> TO <ls_field>.
47: wd_this->get_field_params( CHANGING ct_field = <ls_field> ).
48: ENDLOOP.
49:
50: ENDLOOP.
51:
52: ENDLOOP.
53:
54: ENDMETHOD.
The last couple routines that get called are:
- REFRESH_VARIANT_LIST – so that the Get Variant screen is up-to-date.
- (Optionally) FIRE_AFTER_SAVE_EVT – to let the calling application know that a variant has just been saved.
That’s all there is to saving a selection screen variant in Web Dynpro!
overview | << previous | next >> |
No comments:
Post a Comment