Have you ever had the question if you can port transaction FBL5N (Customer Line Item Display) to Webdynpro? No? Lucky you!
Rebuilding FBL5N is not in my top-5 of favorite things to do, so when I got the question I was quite reluctant to start. Luckily, my colleague pointed me to class CL_SALV_BS_RUNTIME_INFO.

In this blog I will explain how any GUI-based ALV report can be displayed quite easily in ABAP Web Dynpro (WDA). The development is based on two out-of-the-box ABAP-tools: Class CL_SALV_BS_RUNTIME_INFO and the List Viewer for Webdynpro. More information about this class can be found here and some excellent documentation for the List Viewer for Webdynpro can be found here.

Data supply by submitting FBL5N

We start by creating the data provider for the WDA-List Viewer. We need the information from transaction FBL5N, which under the hood is program RFITEMAR. I’ll wrap this in a function module.

FUNCTION z2_alv_output_fbl5n.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(I_R_BUKRS) TYPE  Z2TT_BUKRS OPTIONAL
*"     VALUE(I_KUNNR) TYPE  KUNNR
*"  EXPORTING
*"     VALUE(ET_POS) TYPE  /SAPPCE/RFPOSXEXT
*"  EXCEPTIONS
*"      CUSTOMER_NOT_FOUND
*"      DATA_RETRIEVE_FAILED
*"----------------------------------------------------------------------

* Check if customer exists
  PERFORM check_customer      USING i_kunnr.

* Prepare catching ALV
  cl_salv_bs_runtime_info=>clear_all( ).

* Set No Display/No Metadata and get ALV DATA
  cl_salv_bs_runtime_info=>set( EXPORTING display  = abap_false
                                          metadata = abap_false
                                          data     = abap_true ).

* Init table items
  CLEAR et_pos[].

* Submit report RFITEMAR ie transaction FBL5N
  SUBMIT rfitemar AND RETURN
    WITH dd_bukrs IN i_r_bukrs          " Company
    WITH dd_kunnr EQ i_kunnr            " Customer
    WITH x_opsel  EQ abap_false         " Only open items
    WITH x_aisel  EQ abap_true          " All items
    WITH x_clsel  EQ abap_false         " Cleared items
    WITH pa_vari  EQ  '/AR'.            " Layout

  TRY.
*    Get the output and store in local table
      cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = lr_report ).
      ASSIGN lr_report->* TO <lt_rfitem>.

*    Errors detected ?
    CATCH cx_root.
      RAISE data_retrieve_failed.
  ENDTRY.

* Clear ALV
  cl_salv_bs_runtime_info=>clear_all( ).

* Output (items) available ?
  CHECK <lt_rfitem> IS ASSIGNED.

* Export selected items
  et_pos[] = <lt_rfitem>.

ENDFUNCTION.

In this function module we prepare the class CL_SALV_BS_RUNTIME_INFO, so that the next ALV call is not displayed on screen, but the data is stored in memory. After this preparation, the program for FBL5N is submitted (with the necessary selection-screen parameters) and finally the data generated by the ALV report is retrieved and returned to the caller.

Creation of Webdynpro

Now we have the function module ready that can deliver us the necessary data, we can build a Webdynpro to show the data to the user.

  1. In SE80, create a Webdynpro. Only one view in one window is necessary.
  2. Assign the Webdynpro ALV-usage.
     
  3. Add the component usage group to the attributes of the view.
     
  4. For both the selection and the ALV-data a node in the context for the view is made. For the ALV a supply function is added.
     
  5. The supply function is coded. In this supply function we call the function module we created earlier, to retrieve the data, and we set the data from FBL5N to the context.
    METHOD supply_fbl5n .
    
    ** data declaration
      DATA lt_alv TYPE wd_this->elements_alv.
      DATA lo_el_selection TYPE REF TO if_wd_context_element.
      DATA lv_kunnr TYPE wd_this->element_selection-kunnr.
    
    * Get the value for the customer from the selection on the screen. 
      lo_el_selection = wd_context->get_child_node( name = wd_this->wdctx_selection )->get_element( ).
      lo_el_selection->get_attribute( EXPORTING name =  `KUNNR`
                                      IMPORTING value = lv_kunnr ).
    
    * Check if we have a value for the customer.
      IF lv_kunnr IS INITIAL.
        APPEND INITIAL LINE TO lt_alv.
        EXIT.
      ENDIF.
    
    * Call the functionmodule that will retrieve the ALV info from FBL5N .
      CALL FUNCTION 'Z2_GRAP_ALV_OUTPUT_FBL5N'
        EXPORTING
          i_kunnr              = lv_kunnr
        IMPORTING
          et_pos               = lt_alv
        EXCEPTIONS
          customer_not_found   = 1
          data_retrieve_failed = 2
          OTHERS               = 3.
    
      IF sy-subrc <> 0.
    * Implement suitable error handling here " TODO; generate nice error messages on screen.
        APPEND INITIAL LINE TO lt_alv.
      ENDIF.
    
    * bind all the elements to the context
      node->bind_table(
        new_items            =  lt_alv
        set_initial_elements = abap_true ).
    
    ENDMETHOD.

     

  6. In the view a selection for the customer is added, and a container for the ALV display.
     
  7. Create an action for the OnEnter event of the customer inputfield, and trigger the retrieval of the data.
    METHOD onactionselect_kunnr .
    
    * All we want to do is the start the supply function for the chosen customer.
      wd_context->get_child_node( wd_this->wdctx_alv )->invalidate( ).
    
    ENDMETHOD.

     

  8. And now the fun part: the declaration & assignment of the Webdynpro ALV in methods WWDDOINIT and cleanup in WDDOEXIT.
    METHOD wddoinit .
    
      DATA:
        l_cmp_usage       TYPE REF TO if_wd_component_usage,
        l_intf_controller TYPE REF TO iwci_salv_wd_table.
    
    
      IF wd_this->cmp_usage_group IS INITIAL.
        wd_this->cmp_usage_group = wd_comp_controller->wd_get_api( )->create_cmp_usage_group(
            name           = 'ALV_USAGE_GROUP'
            used_component = 'SALV_WD_TABLE' ).
    
        l_cmp_usage = wd_this->cmp_usage_group->add_component_usage(
             name           = 'ALV_USAGE'
             used_component = 'SALV_WD_TABLE').
    
        l_cmp_usage->create_component( ).
    
        wd_this->wd_get_api( )->do_dynamic_navigation(
            source_window_name          = 'W_MAIN'
            source_vusage_name          = 'V_MAIN_USAGE_0'
            source_plug_name            = 'TO_ALV'
            target_component_name       = 'SALV_WD_TABLE'
            target_component_usage      = 'ALV_USAGE'
            target_view_name            = 'TABLE'
            target_plug_name            = 'DEFAULT'
            target_embedding_position   = 'V_MAIN/CNT_ALV_CONTAINER' ).
    
        l_intf_controller ?= l_cmp_usage->get_interface_controller( ).
        l_intf_controller->set_data( wd_context->get_child_node( 'ALV' ) ).
    
      ENDIF.
    
    * Optional: add some nice features for the end-user.
        l_intf_controller->get_model( )->if_salv_wd_std_functions~set_hierarchy_allowed( ).
        l_intf_controller->get_model( )->if_salv_wd_std_functions~set_aggregation_allowed( abap_true ).
        l_intf_controller->get_model( )->if_salv_wd_std_functions~set_hierarchy_allowed( abap_true ).
        l_intf_controller->get_model( )->if_salv_wd_std_functions~set_count_records_allowed( abap_true ).
        l_intf_controller->get_model( )->if_salv_wd_std_functions~set_group_aggregation_allowed( abap_true ).
    
    ENDMETHOD.
    
    
    
    
    METHOD wddoexit .
    
    * And a nice clean-up after we're finished.
      wd_this->wd_get_api( )->remove_dynamic_meta_data(
            source_window_name          = 'W_MAIN'
            source_vusage_name          = 'V_MAIN_USAGE_0'
            source_plug_name            = 'TO_ALV'
            target_component_name       = 'SALV_WD_TABLE'
            target_component_usage      = 'ALV_USAGE'
            target_view_name            = 'TABLE'
            target_plug_name            = 'DEFAULT'
            target_embedding_position   = 'V_MAIN/CNT_ALV_CONTAINER' ).
    
      IF wd_this->cmp_usage_group IS BOUND.
        wd_this->cmp_usage_group->remove_all_cmp_usages( ).
        CLEAR wd_this->cmp_usage_group.
      ENDIF.
    
      wd_comp_controller->wd_get_api( )->remove_cmp_usage_group( 'ALV_USAGE_GROUP' ).
    
    ENDMETHOD.

     

  9. Finally, create a Webdynpro application and test it.

Results:

FBL5N in SAPGUI:

 

And in Webdynpro:

Please note that I did create a view for the Webdynpro Listviewer, in which I did hide quite a lot of columns to show the similarities between the GUI ALV and the Webdynpro Listviewer.
With minimal coding effort, maximum effect. I’m happy, client happy!

 

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. Tomas Talpa

    And random guy on SDN who learned something new & very usable today is happy as well 🙂

    Thank you for sharing such nice content, Jan-Willem.

     

     

    (1) 

Leave a Reply