Registration

Dear SAP Community Member,
In order to fully benefit from what the SAP Community has to offer, please register at:
http://scn.sap.com
Thank you,
The SAP Community team.
Skip to end of metadata
Go to start of metadata

ScenarioDisplay Material Details based on the plant provided by the user on the selection screen.

Requirement: It was required to provide the basic variant functionality in WD application as it available in SAP ABAP report. 

In the below WD example application I am creating a variant by saving the select-options data along with the records that are selected in the ALV list.

The application has a Main view which contains selection parameter Plant.  The user provides the Plant and clicks on ‘Get Details’ button to display the materials and its relevant master data based on the plant entered. The user then selects the records from the ALV list that contains all the materials and does ‘Save Variant’ accordingly all the selection records and parameter details are saved in a variant. 

Again the user loads the application and clicks on ‘Display Variant’ and navigates to view ‘Variant_Table’  that contains list of variants created by the user in the application _ _now the details are fetched from the variant and the plant and material details are automatically displayed from the variant.

Step 1 : Create your application with select options using used component WDR_SELECT_OPTIONS. .
 
METHOD wddoinit.

DATA:  lt_range_table TYPE REF TO data,
       rt_range_table TYPE REF TO data,
       read_only      TYPE abap_bool,
       typename       TYPE string.

  DATA: lr_componentcontroller TYPE REF TO ig_componentcontroller,
        l_ref_cmp_usage        TYPE REF TO if_wd_component_usage.

* create the used component
  l_ref_cmp_usage = wd_this->wd_cpuse_select_option ( ).

  IF l_ref_cmp_usage->has_active_component( ) IS INITIAL.
    l_ref_cmp_usage->create_component( ).
  ENDIF.

  wd_this->m_wd_select_options = wd_this->wd_cpifc_select_option( ).

* init the select screen
  wd_this->m_handler = wd_this->m_wd_select_options->init_selection_screen( ).
  wd_this->m_handler->set_global_options(
                              i_display_btn_cancel  = abap_false
                              i_display_btn_check   = abap_false
                              i_display_btn_reset   = abap_false
                              i_display_btn_execute = abap_false ).

* create a range table that consists of this new data element
  lt_range_table = wd_this->m_handler->create_range_table

                                      (i_typename = 'WERKS’).

* add a new field to the selection
  wd_this->m_handler->add_selection_field( i_id = 'WERKS'
  it_result       = lt_range_table
  i_read_only     = read_only
  i_no_intervals  = abap_true
  i_no_extension  = abap_true ).

ENDMETHOD.

 Step 2. After user provides the input on the selection screen (i.e. Plant) and clicks on “Get Details” an ALV list is displayed that contains all the materials belonging to the corresponding plant.

 METHOD onactionget_details.

* Field Symbol Declarations
  DATA: BEGIN OF wa_mard,
           matnr TYPE mard-matnr,
           werks TYPE mard-werks,
           lgort TYPE mard-lgort,
         END OF wa_mard.

  DATA: s_werks   TYPE REF TO data. 

* Field Symbols declarations
  FIELD-SYMBOLS: <s_werks> TYPE table.

* Local Data Declarations
  DATA lo_nd_header TYPE REF TO if_wd_context_node.
  DATA ls_header    TYPE wd_this->element_header.
  DATA wa_mara      TYPE mara.
  DATA li_mard      LIKE TABLE OF wa_mard.
  DATA wa_marc      TYPE marc.
  DATA wa_makt      TYPE makt.

lo_api_controller ?= wd_this->wd_get_api( ).
  s_aufnr  = wd_this->m_handler->get_range_table_of_sel_field

                                ( i_id = 'WERKS').
  ASSIGN s_werks->* TO <s_werks>.

  READ TABLE <s_werks> INTO ls_werks INDEX 1.

  CHECK ls_werks-low IS NOT INITIAL.

* Constants Declarations
  CONSTANTS: c_x    TYPE c VALUE 'X'.
  CONSTANTS: c_text TYPE string VALUE 'Select'.

  DATA lo_el_context TYPE REF TO if_wd_context_element.
  DATA li_marc       TYPE TABLE OF marc.
  DATA li_mara       TYPE TABLE OF mara.
  DATA li_makt       TYPE TABLE OF makt.
  DATA ls_context    TYPE wd_this->element_context.
  DATA lv_visible    LIKE ls_context-visible.

*   get element via lead selection
  lo_el_context = wd_context->get_element(  ).

*   get single attribute
  lo_el_context->set_attribute(
    EXPORTING
      value =  c_x
      name  = 'VISIBLE' ).

  SELECT *
    FROM marc
    INTO TABLE li_marc
    WHERE werks EQ ls_werks-low .

  IF li_marc IS NOT INITIAL.

    SELECT *
      FROM mara
      INTO TABLE li_mara
      FOR ALL ENTRIES IN li_marc
      WHERE matnr EQ li_marc-matnr.

    CHECK li_mara IS NOT INITIAL.

* Get Material Description
    SELECT *
      FROM makt
      INTO TABLE li_makt
      FOR ALL ENTRIES IN li_mara
      WHERE spras EQ sy-langu
        AND matnr EQ li_mara-matnr.

* Fetch Material Storage Locations Details
    SELECT matnr
           werks
           lgort
      FROM mard
      INTO TABLE li_mard
      FOR ALL ENTRIES IN li_mara
      WHERE matnr EQ li_mara-matnr
        AND werks EQ ls_werks-low .

      CHECK li_mard IS NOT INITIAL.

    DATA lo_nd_item_details TYPE REF TO if_wd_context_node.
    DATA ls_item_details    TYPE wd_this->element_item_details.
    DATA li_item_details    TYPE wd_this->elements_item_details.

*   navigate from <CONTEXT> to <ITEM_DETAILS> via lead selection
    lo_nd_item_details = wd_context->get_child_node (name = wd_this->wdctx_item_details).

    LOOP AT li_marc INTO wa_marc.
      READ TABLE li_mara INTO wa_mara WITH KEY matnr = wa_marc-matnr.
      IF sy-subrc EQ 0.
        MOVE-CORRESPONDING wa_mara TO ls_item_details.
        READ TABLE li_mard INTO wa_mard WITH KEY matnr = wa_mara-matnr.
        IF sy-subrc EQ 0.
          MOVE-CORRESPONDING wa_mard TO ls_item_details.
        ENDIF.
        READ TABLE li_makt INTO wa_makt WITH KEY matnr = wa_mara-matnr.
        IF sy-subrc EQ 0.
          MOVE-CORRESPONDING wa_makt TO ls_item_details.
        ENDIF.
      ENDIF.

      MOVE space TO ls_item_details-select.
      APPEND ls_item_details TO li_item_details.
      CLEAR  ls_item_details.

    ENDLOOP.

    lo_nd_item_details->bind_table (li_item_details).

  ENDIF.

  DATA lr_nd_mcc_follow_up    TYPE REF TO if_wd_context_node.
  DATA lo_interfacecontroller TYPE REF TO iwci_salv_wd_table.
  DATA lo_value               TYPE REF TO cl_salv_wd_config_table.
  DATA lo_cmp_usage           TYPE REF TO if_wd_component_usage.
  DATA: lr_column_settings    TYPE REF TO if_salv_wd_column_settings,
        lr_table_settings     TYPE REF TO if_salv_wd_table_settings,
        lr_input_field        TYPE REF TO cl_salv_wd_uie_input_field,
        lr_column             TYPE REF TO cl_salv_wd_column,
        lr_col_header         TYPE REF TO cl_salv_wd_column_header,
        lr_checkbox           TYPE REF TO cl_salv_wd_uie_checkbox.

  lo_cmp_usage =   wd_this->wd_cpuse_material_data_alv( ).

  IF lo_cmp_usage->has_active_component ( ) IS INITIAL.
    lo_cmp_usage->create_component( ).
  ENDIF.

* Navigate from <CONTEXT> to <ALV_CHGDLR> via lead selection
  lr_nd_mcc_follow_up = wd_context->get_child_node( name = wd_this->wdctx_item_details ).

  lo_interfacecontroller =   wd_this->wd_cpifc_material_data_alv( ).
  lo_interfacecontroller->set_data( r_node_data = lr_nd_mcc_follow_up ).

  lo_value = lo_interfacecontroller->get_model( ).

  lr_table_settings ?= lo_value.
  lr_table_settings->set_visible_row_count( '20' ).

*sets column as a checkbox
  lr_column_settings ?= lo_value.
* Set required text
  lr_column = lr_column_settings->get_column( 'SELECT' ).

  CREATE OBJECT lr_checkbox
    EXPORTING
      checked_fieldname = 'SELECT'.

  lr_checkbox->set_enabled( abap_true ).
  lr_column->set_cell_editor( lr_checkbox ).

  lr_column = lr_column_settings->get_column( 'SELECT' ).
  lr_col_header = lr_column->get_header( ).
  lr_col_header->set_ddic_binding_field( if_salv_wd_c_column_settings=>ddic_bind_none ).
  lr_col_header->set_text( EXPORTING value = c_text ).

* initially when output is displayed, cursor is on first row.
* By below statement index is set to 0
  CALL METHOD lr_nd_mcc_follow_up->set_lead_selection_index
    EXPORTING
      index = '0'.

  lo_value->if_salv_wd_table_settings~set_read_only( abap_false ).

ENDMETHOD. 

Step 3. The user then selects few entries from the list and press on “Save Variant” button.
 
Step 4. The program stores the variant data in system table INDX using (EXPORT TO *...*DATABASE). Using table INDX places a restriction that the WDA component name can't be more than 20 char. Cluster table is created with same table fields as INDX (with more wide SRTFD field) or VARI to store variants. The variants are stored as following in this example. 

  • Area (INDX-RELID) is populated with ‘YW'.
  • The first 20 characters of user defined key (INDX-SRTFD) contains the WD component name. The last 2 characters are used to store the unique variant sequence number.
  • The first 4 characters of INDX-PGMID contains the variant name (plant), the 6th character contains ‘/'.  This is a separator indicator.
  • The rest 8(10) chars are the creation date of variant.
  • The field USERA contains the name of the user who created the variant.
  • The program checks if there is no already existing variant this the same name.
  • The range tables plant are referencing to data. They are made dereference and store the data in range internal tables (... type range of WERKS_D because referenced data can't be exported to database).
  • The both tables are exported to database to ID ‘YW' with key prepared in previous steps.

METHOD onactionsave_variant .

* Local Data Declarations
  DATA lo_nd_header TYPE REF TO if_wd_context_node.
  DATA ls_header    TYPE wd_this->element_header.

* navigate from <CONTEXT> to <HEADER> via lead selection
  lo_nd_header = wd_context->get_child_node( name = wd_this->wdctx_header ).

* get all declared attributes
  lo_nd_header->get_static_attributes(
    IMPORTING
      static_attributes = ls_header ).

  DATA: BEGIN OF w_variant_rec_key,
            relid TYPE indx-relid,
            srtfd TYPE indx-srtfd,
            srtf2 TYPE indx-srtf2,
            pgmid TYPE indx-pgmid,
            begdt TYPE indx-begdt,
          END OF w_variant_rec_key.

  DATA : i_variant_rec_key LIKE TABLE OF w_variant_rec_key.

  DATA lo_componentcontroller     TYPE REF TO ig_componentcontroller .
  DATA lo_api_componentcontroller TYPE REF TO if_wd_component.
  DATA my_comp_info               TYPE REF TO if_wd_rr_component.
  DATA my_comp_name               TYPE string.

  DATA l_len        TYPE i.
  DATA l_next_count TYPE i.
  DATA l_pgmid      TYPE char14.
  DATA l_indx       TYPE indx.
  DATA l_program    TYPE indx-srtfd.

  DATA: my_message_manager TYPE REF TO if_wd_message_manager,
      my_selection_items TYPE if_wd_select_options=>tt_selection_screen_item.

  lo_componentcontroller     = wd_this->get_componentcontroller_ctr( ).
  lo_api_componentcontroller = lo_componentcontroller->wd_get_api( ).

*-----Get component controller infor
  my_comp_info = lo_api_componentcontroller->get_component_info( ).
*----Get name of the component
  my_comp_name = my_comp_info->get_name( ).

*-----Program name is first 20 characters of component name
*-----Last 2 characters are being used for variant sequence #
  l_len = STRLEN( my_comp_name ).
  IF l_len GT 20.
    l_program = my_comp_name+0(20).
  ELSE.
    l_program = my_comp_name.
  ENDIF.

  CONCATENATE l_program '%' INTO l_program.

*Read DB to fetch the variant data
* Check if the variant is already present in the database
  SELECT relid
         srtfd
         srtf2
         pgmid
         begdt
    INTO TABLE i_variant_rec_key
    FROM indx
    WHERE relid EQ 'YW'
      AND srtfd LIKE l_program.

  IF sy-subrc = 0.
    l_next_count = sy-dbcnt + 1.
    LOOP AT i_variant_rec_key INTO w_variant_rec_key.
      IF w_variant_rec_key-pgmid+0(4) EQ ls_header-plant.

* Overwrite the existing variant
        CONCATENATE ls_header-plant '%' INTO l_pgmid .
        DELETE FROM indx WHERE pgmid LIKE l_pgmid.
        l_next_count = l_next_count - 1.
        EXIT.
      ENDIF.
    ENDLOOP.
  ENDIF.

*----Now start making the w_index_key to save the variant
  REPLACE FIRST OCCURRENCE OF '%' IN l_program WITH space IN CHARACTER MODE.
  MOVE  l_next_count TO l_program+20(2).

  CLEAR w_variant_rec_key.
  w_variant_rec_key-relid = 'YW'.
  w_variant_rec_key-srtfd = l_program.
  w_variant_rec_key-pgmid+0(4)  = ls_header-plant.
  w_variant_rec_key-pgmid+6(1)  = '/'.
  w_variant_rec_key-pgmid+8(10) = sy-datum.

  CLEAR l_indx.
  MOVE-CORRESPONDING w_variant_rec_key TO l_indx.
  l_indx-usera = sy-uname.
  l_indx-begdt = sy-datum.
  save_indx( EXPORTING in_indx = l_indx ).

ENDMETHOD. 

Step 5. The retrieval process takes the following steps.

  • Reload the application.
  • Click on "Display Variant" button on Main view
  • The control will navigate to Variant_Table view that holds the table with variants.
  • METHOD onactiondisplay_variant.

* Navigate to Variant Table View
  wd_this->fire_to_variant_table_plg ( ).

ENDMETHOD.

  • Read all the records from table INDX for area ‘YW' and key having a pattern of 20 characters of WD component name.
  • Get the variant name from first 4 characters of INDX-PGMID field.

METHOD wddomodifyview.

* Local Data Declarations
  DATA lo_nd_variant_table TYPE REF TO if_wd_context_node.
  DATA ls_variant_table    TYPE wd_this->element_variant_table.
  DATA li_variant_table    TYPE wd_this->elements_variant_table.

* navigate from <CONTEXT> to <VARIANT_TABLE> via lead selection
  lo_nd_variant_table = wd_context->get_child_node( name = wd_this->wdctx_variant_table ).

  DATA: my_component       TYPE REF TO if_wd_component,
        my_component_info  TYPE REF TO if_wd_rr_component,
        my_component_name  TYPE string.

  DATA : BEGIN OF w_variant_rec_key,
            relid TYPE indx-relid,
            srtfd TYPE indx-srtfd,
            srtf2 TYPE indx-srtf2,
            pgmid TYPE indx-pgmid,
            usera TYPE indx-usera,
            begdt TYPE indx-begdt,
          END OF w_variant_rec_key.

  DATA : i_variant_rec_key LIKE TABLE OF w_variant_rec_key,
         l_prog            TYPE indx-srtfd,
         l_len             TYPE i.

* Constants Declarations
  CONSTANTS: c_x     TYPE c VALUE 'X',
             c_yw(2) TYPE c VALUE 'YW'.

  CHECK first_time IS NOT INITIAL.

*----get component name
  my_component = view->if_wd_controller~get_component( ).
  my_component_info = my_component->get_component_info( ).
  my_component_name = my_component_info->get_name( ).

*----Read all the variants for this component
  l_len = STRLEN( my_component_name ).
  IF l_len GT 20.
    l_prog = my_component_name+0(20).
  ELSE.
    l_prog = my_component_name.
  ENDIF.

  CONCATENATE l_prog '%' INTO l_prog.

  SELECT relid
         srtfd
         srtf2
         pgmid
         usera
         begdt
    INTO TABLE i_variant_rec_key
    FROM indx
    WHERE relid EQ c_yw
      AND srtfd LIKE l_prog.

  CLEAR li_variant_table.

*----Only keep global or user's variant
  LOOP AT i_variant_rec_key INTO w_variant_rec_key.
    IF w_variant_rec_key-usera NE sy-uname AND
       w_variant_rec_key-pgmid+6(1) NE '/'.
      DELETE i_variant_rec_key INDEX sy-tabix.

    ELSE.
      CLEAR ls_variant_table.

      MOVE : w_variant_rec_key-pgmid+0(4)  TO ls_variant_table-variant_name,
             w_variant_rec_key-pgmid+8(10) TO ls_variant_table-variant_desp.
      ls_variant_table-user   = w_variant_rec_key-usera.
      ls_variant_table-created_on   = w_variant_rec_key-begdt.

      APPEND ls_variant_table TO li_variant_table.
      CLEAR  ls_variant_table.

    ENDIF.
  ENDLOOP.

  SORT li_variant_table BY created_on.

* Delete duplicate entries
  DELETE ADJACENT DUPLICATES FROM li_variant_table COMPARING ALL FIELDS.
  CALL METHOD lo_nd_variant_table->bind_table
    EXPORTING
      new_items = li_variant_table.

ENDMETHOD. 

  • The variant fetched from table INDX is displayed in a variant table that contains the variant name, variant description, user name and variant creation date.
  • Select the variant from the variant table and click on “Proceed” button.

METHOD onactionproceed.

* Local Data Declarations
  DATA lo_nd_variant_table TYPE REF TO if_wd_context_node.
  DATA ls_variant_table    TYPE wd_this->element_variant_table.

* navigate from <CONTEXT> to <VARIANT_TABLE> via lead selection
  lo_nd_variant_table = wd_context->get_child_node( name = wd_this->wdctx_variant_table ).

* get all declared attributes
  lo_nd_variant_table->get_static_attributes(
    IMPORTING
      static_attributes = ls_variant_table ).

  CHECK ls_variant_table IS NOT INITIAL.

  DATA: my_component       TYPE REF TO if_wd_component,
        my_component_info  TYPE REF TO if_wd_rr_component,
        my_component_name  TYPE string,
        l_prog             TYPE indx-srtfd,
        l_id               TYPE indx-srtfd,
        l_pgmid            TYPE indx-pgmid,
        l_len              TYPE i.

  DATA lo_nd_header TYPE REF TO if_wd_context_node.
  DATA ls_header    TYPE wd_this->element_header.

* navigate from <CONTEXT> to <HEADER> via lead selection
  lo_nd_header = wd_context->get_child_node( name = wd_this->wdctx_header ).

  DATA lo_nd_item_details TYPE REF TO if_wd_context_node.
  DATA ls_item_details    TYPE wd_this->element_item_details.
  DATA li_item_details    TYPE wd_this->elements_item_details.

*   navigate from <CONTEXT> to <ITEM_DETAILS> via lead selection
  lo_nd_item_details = wd_context->get_child_node( name = wd_this->wdctx_item_details ).

*----Get component name
  my_component = wd_comp_controller->wd_get_api( ).
  my_component_info = my_component->get_component_info( ).
  my_component_name = my_component_info->get_name( ).

*----Read all the variants for this component
  l_len = STRLEN( my_component_name ).
  IF l_len GT 20.
    l_prog = my_component_name+0(20).
  ELSE.
    l_prog = my_component_name.
  ENDIF.

  CONCATENATE  : l_prog '%' INTO l_prog,
                 ls_variant_table-variant_name '%' INTO l_pgmid.

  SELECT  srtfd
    INTO l_id
    UP TO 1 ROWS
    FROM indx
    WHERE relid EQ 'YW'
      AND srtfd LIKE l_prog
      AND pgmid LIKE l_pgmid.
    EXIT.
  ENDSELECT.

  IF sy-subrc EQ 0.
* navigate from <CONTEXT> to <PO_HEADER> via lead selection
    lo_nd_header = wd_context->get_child_node( name = wd_this->wdctx_header ).
    IMPORT ls_header = ls_header
           li_item_details  = li_item_details FROM DATABASE indx(yw) ID l_id.

    IF sy-subrc EQ 0.

      CALL METHOD lo_nd_header->set_static_attributes
        EXPORTING
          static_attributes = ls_header.
    ENDIF.
  ENDIF.

  CALL METHOD lo_nd_item_details->bind_table
    EXPORTING
      new_items = li_item_details.

  wd_this->fire_to_main_plg( ).

ENDMETHOD. 

  • Navigate to the “Main” view from “Variant_Table” view.

METHOD handlefrom_variant_table .

* Initialize selection screen
  wddoinit( ).

* Constants Declarations
  CONSTANTS: c_x    TYPE c VALUE 'X'.
  CONSTANTS: c_text TYPE string VALUE 'Select'.

  DATA lo_el_context TYPE REF TO if_wd_context_element.
  DATA ls_context    TYPE wd_this->element_context.
  DATA lv_visible    LIKE ls_context-visible.

*   get element via lead selection
  lo_el_context = wd_context->get_element(  ).

*   get single attribute
  lo_el_context->set_attribute(
    EXPORTING
      value =  c_x
      name  = 'VISIBLE' ).

  DATA lr_nd_mcc_follow_up    TYPE REF TO if_wd_context_node.
  DATA lo_interfacecontroller TYPE REF TO iwci_salv_wd_table .
  DATA lo_value               TYPE REF TO cl_salv_wd_config_table.
  DATA lo_cmp_usage           TYPE REF TO if_wd_component_usage.
  DATA: lr_column_settings    TYPE REF TO if_salv_wd_column_settings,
        lr_table_settings     TYPE REF TO if_salv_wd_table_settings,
        lr_input_field        TYPE REF TO cl_salv_wd_uie_input_field,
        lr_column             TYPE REF TO cl_salv_wd_column,
        lr_col_header         TYPE REF TO cl_salv_wd_column_header,
        lr_checkbox           TYPE REF TO cl_salv_wd_uie_checkbox.

  lo_cmp_usage =   wd_this->wd_cpuse_material_data_alv( ).

  IF lo_cmp_usage->has_active_component( ) IS INITIAL.
    lo_cmp_usage->create_component( ).
  ENDIF.

* Navigate from <CONTEXT> to <ALV_CHGDLR> via lead selection
  lr_nd_mcc_follow_up = wd_context->get_child_node( name = wd_this->wdctx_item_details ).

  lo_interfacecontroller =   wd_this->wd_cpifc_material_data_alv( ).
  lo_interfacecontroller->set_data( r_node_data = lr_nd_mcc_follow_up ).

  lo_value = lo_interfacecontroller->get_model ( ).

  lr_table_settings ?= lo_value.
  lr_table_settings->set_visible_row_count (‘20’).

*sets column as a checkbox
  lr_column_settings ?= lo_value.
* Set required text
  lr_column = lr_column_settings->get_column( 'SELECT' ).

  CREATE OBJECT lr_checkbox
    EXPORTING
      checked_fieldname = 'SELECT'.

  lr_checkbox->set_enabled( abap_true ).
  lr_column->set_cell_editor( lr_checkbox ).

  lr_column = lr_column_settings->get_column( 'SELECT' ).
  lr_col_header = lr_column->get_header( ).
  lr_col_header->set_ddic_binding_field( if_salv_wd_c_column_settings=>ddic_bind_none ).
  lr_col_header->set_text( EXPORTING value = c_text ).

* initially when output is displayed, cursor is on first row.
* By below statement index is set to 0
  CALL METHOD lr_nd_mcc_follow_up->set_lead_selection_index
    EXPORTING
      index = '0'.

  lo_value->if_salv_wd_table_settings~set_read_only( abap_false ).

ENDMETHOD. 

  • Populate the Plant range table and the ALV list with the material data along with selected entries.
     
    Finally the ALV list is loded with the previous selected entries.
  • No labels