Skip to Content
Author's profile photo E. Neuenschwander

Mapping of InfoProvider fields in CompositeProvider

When creating CompositeProviders in the new BW modeling tools in Eclipse it may become difficult to get a good overview of which InfoObjects from which InfoProviders are mapped in the Union or Join part, especially when your CompositeProvider contains many objects.

For MultiProviders we can use table RSDICMULTIIOBJ to get an overview of the mapping between source and target fields. However, since the definition of a CompositeProvider is stored as XML such a table does not exist for CompositeProviders. Although the XML of a CompositeProvider can be displayed in RSA1, ít’s difficult to read, even when you export the XML definition to Excel.

By making use of the attached program, it’s possible to display the mapping between InfoProvider fields and the CompositeProvider on your screen.

Example CompositeProvider

For this example I created a simple CompositeProvider containting two Advanced Datastore Objects;

WCP__001.png

The CompositeProvider contains the InfoObjects 0DOC_NUMBER and 0CALDAY from ADSO 01 as well as the InfoObjects 0DOC_NUMBER, 0DOC_ITEM, 0AMOUNT and 0CURRENCY from ADSO 02. The InfoProviders are joined on 0DOC_NUMBER.

The XML definition that has been created when activating the CompositeProvider, is stored in table RSOHCPR, field XML_UI:

/wp-content/uploads/2016/03/rsohcpr_900495.png

This XML-string is displayed in the ‘hierachical view’ when you use the ‘Dispay XML’ button in RSA1 (partially shown below):

XML.png

In this definition the <entity> part contains the name of the involved InfoProviders, whereas the <mapping xsi:> part contains the mapping between the source and target fields.

In order to ‘breakdown’ this hierachical view we need to put the XML definition into an internal table. One way to this, is to make use of the the function module SMUM_XML_PARSE, a guide with more information on this function can be found here.

This function parses the XML definition to and internal table containing 4 columns:

HIER – the hierarchy ‘node’

TYPE – A for ‘header’ and ‘V’ for value nodes

CNAME – the name of a node

CVALUE – the value of a node

/wp-content/uploads/2016/03/lt_1_900518.png

To display the InfoProvider name and the source and target fields on our screen, we need to collect these values from the internal table into an output table. As seen above, the <element> part contains the name of the InfoProvider. So we check the column CNAME for the value ‘entity’ and get the tecnhical name in column CVALUE (minus the addition ‘.composite’.).

After that we get the values of the source and target fields by checking CNAME for ‘sourceName’ and ‘targetName’:

/wp-content/uploads/2016/03/lt_2_900520.png

When all values have been checked, the values are displayed by making use of the SAP class cl_salv_table:

/wp-content/uploads/2016/03/screen_900521.png

/wp-content/uploads/2016/03/output_900516.png

Note: the XML definition also contains information about the type of join and the properties of the CompositerProvider, which could also be added to the program output in order to create a ‘documentation program’.

Assigned Tags

      16 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Sjoerd van Middelkoop
      Sjoerd van Middelkoop

      Hi Mr. Neuenschwander!

      Thanks for the info, this should come in handy!

      Alles goed verder?

      Sjoerd

      Author's profile photo Harish Allachervu
      Harish Allachervu

      Hello,

      Good piece of document thanks for sharing 🙂

      Regards,

      Harish

      Author's profile photo Markus Ganser
      Markus Ganser

      Thanks Edwin,

      very good explanation and very useful report.

      But one small correction is necessary. For HCPRs with HANA Views you will get a the short-dump "Invalid subfield access: Length negative" in line 68:

      010 Runtime Error Long Text.png

      My corretion:

      ....

      IF <fs_xml_info>-cname = 'entity'.

             l_cvalue = <fs_xml_info>-cvalue.

             SEARCH l_cvalue FOR 'composite'.

             l_offset = sy-fdpos.

             l_offset = l_offset - 1.

             TRY.

                 l_output-infoprovider = <fs_xml_info>-cvalue(l_offset). "CompositeProvider

               CATCH cx_sy_range_out_of_bounds.

                 l_output-infoprovider = <fs_xml_info>-cvalue.

             ENDTRY.

           ELSEIF

      ....


      best regards

      markus

      Author's profile photo E. Neuenschwander
      E. Neuenschwander
      Blog Post Author

      Hi Markus,

      Thanks for the addition, I've updated the code with your correction!

      Regards,

      Edwin

      Author's profile photo Former Member
      Former Member

      Thanks Edwin 😉

      Author's profile photo Former Member
      Former Member

      Handig voor RSDODSOIOBJ <-> ADSO ook?

      Author's profile photo Former Member
      Former Member

      I slightly adjusted it so it can generate a list of InfoObjects that is part of the ADSO.

      REPORT zbw_hcpr_mapping.

      ************************************************************************

      * DATA DECLARATION

      ***********************************************************************

      TYPES: BEGIN OF ty_output,

                infoprovider TYPE rsdodsobject,

                source       TYPE rsdiobjnm,

                target       TYPE rsohcprcolnm,

              END OF ty_output.

      TYPES: BEGIN OF ty_output2,

                iobj TYPE rsdiobjnm,

              END OF ty_output2.

      DATA: l_hobj_xml_def TYPE xstring,

             lt_xml_info    TYPE TABLE OF smum_xmltb INITIAL SIZE 0,

             lt_return      TYPE STANDARD TABLE OF bapiret2,

             lt_output      TYPE STANDARD TABLE OF ty_output,

             lt_output2     TYPE STANDARD TABLE OF ty_output2,

             l_cvalue       TYPE char255,

             l_offset       TYPE i,

             l_output       TYPE ty_output,

             l_output2      TYPE ty_output2,

             lv_flg_hcpr    TYPE flag VALUE 'X'.

      ************************************************************************

      * ALV REFERENCES

      ***********************************************************************

      DATA: go_alv     TYPE REF TO cl_salv_table,

             go_columns TYPE REF TO cl_salv_columns,

             go_funcs   TYPE REF TO cl_salv_functions,

             go_ex      TYPE REF TO cx_root.

      FIELD-SYMBOLS: <fs_xml_info> TYPE smum_xmltb,

                      <fs_any_tab>      TYPE any.

      ************************************************************************

      * SELECTION SCREEN DETAILS

      ************************************************************************

      SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE text-001.

      PARAMETERS: p_hobj TYPE rsohcprnm.

      SELECTION-SCREEN END OF BLOCK blk1.

      ************************************************************************

      * DATA PROCESSSING

      ************************************************************************

      * Select XML definition of CompositeProvider

      SELECT SINGLE xml_ui

         FROM rsohcpr

         INTO l_hobj_xml_def

         WHERE hcprnm = p_hobj

         AND objvers = 'A'.

      IF sy-subrc <> 0.

         CLEAR lv_flg_hcpr.

      * Check if input is an Advacned DSO

         SELECT SINGLE xml_ui

         FROM rsoadso

         INTO l_hobj_xml_def

         WHERE adsonm = p_hobj

         AND objvers = 'A'.

         IF sy-subrc <> 0.

           MESSAGE 'Novalid or inactive CompositeProvider/ADSO or CompositeProvider/ADSO not of type HCPR/ADSO' TYPE 'I'.

           EXIT.

         ENDIF.

      ENDIF.

      IF lv_flg_hcpr EQ 'X'.

         ASSIGN lt_output TO <fs_any_tab> .

      * Parse XML string to XML table

         CALL FUNCTION 'SMUM_XML_PARSE'

           EXPORTING

             xml_input = l_hobj_xml_def

           TABLES

             xml_table = lt_xml_info

             return    = lt_return.

      * Internal table with mapping

         LOOP AT lt_xml_info ASSIGNING <fs_xml_info>.

           IF <fs_xml_info>-cname = 'entity'.

             l_cvalue = <fs_xml_info>-cvalue.

             SEARCH l_cvalue FOR 'composite'.

             l_offset = sy-fdpos.

             l_offset = l_offset - 1.

             TRY.

                 l_output-infoprovider = <fs_xml_info>-cvalue(l_offset). "CompositeProvider

               CATCH cx_sy_range_out_of_bounds.

                 l_output-infoprovider = <fs_xml_info>-cvalue.

             ENDTRY.

           ELSEIF

            <fs_xml_info>-cname = 'targetName'.

             l_output-target = <fs_xml_info>-cvalue.

           ELSEIF

             <fs_xml_info>-cname = 'sourceName'.

             l_output-source = <fs_xml_info>-cvalue.

             APPEND l_output TO lt_output.

           ENDIF.

         ENDLOOP.

      ELSE.

         ASSIGN lt_output2 TO <fs_any_tab> .

      * Parse XML string to XML table

         CALL FUNCTION 'SMUM_XML_PARSE'

           EXPORTING

             xml_input = l_hobj_xml_def

           TABLES

             xml_table = lt_xml_info

             return    = lt_return.

      * Internal table with mapping

         LOOP AT lt_xml_info ASSIGNING <fs_xml_info>.

           IF <fs_xml_info>-cname = 'infoObjectName'.

             l_output2-iobj = <fs_xml_info>-cvalue.

             APPEND l_output2 TO lt_output2.

           ENDIF.

         ENDLOOP.

      ENDIF.

      * Output to ALV

      TRY.

           cl_salv_table=>factory(

           IMPORTING

           r_salv_table = go_alv

           CHANGING

           t_table = <fs_any_tab> ).

           " set column optimized

           go_columns = go_alv->get_columns( ).

           go_columns->set_optimize( ).

           " set functions

           go_funcs = go_alv->get_functions( ).

           go_funcs->set_all( ).

           go_alv->display( ).

         CATCH cx_salv_msg INTO go_ex.

           MESSAGE go_ex TYPE 'E'.

      ENDTRY.

      Author's profile photo E. Neuenschwander
      E. Neuenschwander
      Blog Post Author

      Hi Mathijs,

      Good one, thanks!

      Author's profile photo Jeffrey Tobin
      Jeffrey Tobin

      Hello.. what is the original program?  I don't see an attachment.

      Author's profile photo Ravi shankar Reddy Chintakunta
      Ravi shankar Reddy Chintakunta

      Hello, I am unable to see the attachment. Please post the code.

      Author's profile photo E. Neuenschwander
      E. Neuenschwander
      Blog Post Author

      Hi,

      The attachment has been removed after the migration of the old Community, please find the code below:

      REPORT zbw_hcpr_mapping.
      
      ************************************************************************
      * DATA DECLARATION
      ***********************************************************************
      TYPES: BEGIN OF ty_output,
               infoprovider TYPE rsdodsobject,
               source       TYPE rsdiobjnm,
               target       TYPE rsohcprcolnm,
             END OF ty_output.
      
      DATA: l_hcpr_xml_def TYPE xstring,
            lt_xml_info    TYPE TABLE OF smum_xmltb INITIAL SIZE 0,
            lt_return      TYPE STANDARD TABLE OF bapiret2,
            lt_output      TYPE STANDARD TABLE OF ty_output,
            l_cvalue       TYPE char255,
            l_offset       TYPE i,
            l_output       TYPE ty_output.
      
      ************************************************************************
      * ALV REFERENCES
      ***********************************************************************
      DATA: go_alv     TYPE REF TO cl_salv_table,
            go_columns TYPE REF TO cl_salv_columns,
            go_funcs   TYPE REF TO cl_salv_functions,
            go_ex      TYPE REF TO cx_root.
      
      
      FIELD-SYMBOLS: <fs_xml_info> TYPE smum_xmltb.
      
      ************************************************************************
      * SELECTION SCREEN DETAILS
      ************************************************************************
      SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE text-001.
      PARAMETERS: p_cp TYPE rsohcprnm.
      SELECTION-SCREEN END OF BLOCK blk1.
      
      ************************************************************************
      * DATA PROCESSSING
      ************************************************************************
      * Select XML definition of CompositeProvider
      SELECT SINGLE xml_ui
        FROM rsohcpr
        INTO l_hcpr_xml_def
        WHERE hcprnm = p_cp
        AND objvers = 'A'.
      
      IF sy-subrc <> 0.
        MESSAGE 'No valid or inactive CompositeProvider or CompositeProvider not of type HCPR' TYPE 'I'.
        EXIT.
      ELSE.
      
      * Parse XML string to XML table
        CALL FUNCTION 'SMUM_XML_PARSE'
          EXPORTING
            xml_input = l_hcpr_xml_def
          TABLES
            xml_table = lt_xml_info
            return    = lt_return.
      
      * Internal table with mapping
        LOOP AT lt_xml_info ASSIGNING <fs_xml_info>.
          IF <fs_xml_info>-cname = 'entity'.
            l_cvalue = <fs_xml_info>-cvalue.
            SEARCH l_cvalue FOR 'composite'.
            l_offset = sy-fdpos.
            l_offset = l_offset - 1.
            TRY.
                l_output-infoprovider = <fs_xml_info>-cvalue(l_offset). "CompositeProvider
              CATCH cx_sy_range_out_of_bounds.
                l_output-infoprovider = <fs_xml_info>-cvalue.
            ENDTRY.
          ELSEIF
           <fs_xml_info>-cname = 'targetName'.
            l_output-target = <fs_xml_info>-cvalue.
          ELSEIF
            <fs_xml_info>-cname = 'sourceName'.
            l_output-source = <fs_xml_info>-cvalue.
            APPEND l_output TO lt_output.
          ENDIF.
        ENDLOOP.
      
      * Output to ALV
        TRY.
            cl_salv_table=>factory(
            IMPORTING
            r_salv_table = go_alv
            CHANGING
            t_table = lt_output ).
            " set column optimized
            go_columns = go_alv->get_columns( ).
            go_columns->set_optimize( ).
            " set functions
            go_funcs = go_alv->get_functions( ).
            go_funcs->set_all( ).
            go_alv->display( ).
          CATCH cx_salv_msg INTO go_ex.
            MESSAGE go_ex TYPE 'E'.
        ENDTRY.
      
      ENDIF.

       

      Author's profile photo Murali Kandimalla
      Murali Kandimalla

      Hi,

      It's a nice explanation. I need to display the description the infoobjects which been used in composite provider. please provide the relevant code adjustment in the above one.

      Author's profile photo George Dedas
      George Dedas

      thanks a lot for this post.

      Author's profile photo Marcus Preis
      Marcus Preis

      Thank you for your tutorial, Mr. Neuenschwander.

      It might work, but from my point of view this is rather complicated.

      Isn`t it a little strange that there is no solution that is closer to SAP standard and easier to achieve?

      I think that many ppl need this functionality?

      I was also thinking about the good, old BW metadata repository. The information is basically there, but I have not yet discovered how to access it (on table basis).

      Has anyone in the meantime had some new findings?

       

      Thank you!

      Marcus

      Author's profile photo Luc VANROBAYS
      Luc VANROBAYS

      Thanks for this blog.

      I just added support for transformation with id that one can pick in RSTRANGUI tcode.

       

      * DATA DECLARATION
      
      ***********************************************************************
      
      TYPES: BEGIN OF ty_output,
                infoprovider TYPE rsdodsobject,
                source       TYPE rsdiobjnm,
                target       TYPE rsohcprcolnm,
              END OF ty_output.
      
      TYPES: BEGIN OF ty_output2,
                iobj TYPE rsdiobjnm,
              END OF ty_output2.
      
      TYPES: BEGIN OF ty_output3,
                object TYPE rsdodsobject,
                source       TYPE rsdiobjnm,
                target       TYPE rsohcprcolnm,
              END OF ty_output3.
      
      DATA: l_hobj_xml_def TYPE xstring,
             lt_xml_info    TYPE TABLE OF smum_xmltb INITIAL SIZE 0,
             lt_return      TYPE STANDARD TABLE OF bapiret2,
             lt_output      TYPE STANDARD TABLE OF ty_output,
             lt_output2     TYPE STANDARD TABLE OF ty_output2,
             lt_output3     TYPE STANDARD TABLE OF ty_output3,
             l_cvalue       TYPE char255,
             l_offset       TYPE i,
             l_output       TYPE ty_output,
             l_output2      TYPE ty_output2,
             l_output3      TYPE ty_output3,
             lv_flg_hcpr    TYPE flag VALUE 'X',
             lv_flg_adso    TYPE flag VALUE '',
             lv_flg_haap    TYPE flag VALUE '',
             lv_idx_collect_haap TYPE sy-tabix.
      
      ************************************************************************
      
      * ALV REFERENCES
      
      ***********************************************************************
      
      DATA: go_alv     TYPE REF TO cl_salv_table,
             go_columns TYPE REF TO cl_salv_columns,
             go_funcs   TYPE REF TO cl_salv_functions,
             go_ex      TYPE REF TO cx_root.
      
      FIELD-SYMBOLS: <fs_xml_info> TYPE smum_xmltb,
                      <fs_any_tab>      TYPE any.
      ************************************************************************
      
      * SELECTION SCREEN DETAILS
      
      ************************************************************************
      
      SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE TEXT-001.
      
      PARAMETERS: p_hobj TYPE rsohcprnm.
      SELECTION-SCREEN END OF BLOCK blk1.
      ************************************************************************
      * DATA PROCESSSING
      ************************************************************************
      * Select XML definition of CompositeProvider
      SELECT SINGLE xml_ui
         FROM rsohcpr
         INTO l_hobj_xml_def
         WHERE hcprnm = p_hobj
         AND objvers = 'A'.
      
      IF sy-subrc <> 0.
         CLEAR lv_flg_hcpr.
      * Check if input is an Advanced DSO
         SELECT SINGLE xml_ui
         FROM rsoadso
         INTO l_hobj_xml_def
         WHERE adsonm = p_hobj
         AND objvers = 'A'.
      IF sy-subrc <> 0.
         CLEAR: lv_flg_hcpr, lv_flg_adso.
         SELECT SINGLE xml
         FROM rsdhamap
         INTO l_hobj_xml_def
         WHERE haapnm = p_hobj
         AND objvers = 'A'.
      
         IF sy-subrc <> 0.
           MESSAGE 'Invalid or Inactive CompositeProvider/ADSO /HAAP or CompositeProvider/ADSO/HAAP not of type HCPR/ADSO/HAAP' TYPE 'I'.
           EXIT.
         ELSE.
           lv_flg_haap = 'X'.
         ENDIF.
       ELSE. "lv_flg_adso
       lv_flg_adso = 'X'.
       ENDIF.
      ENDIF.
      
      IF lv_flg_hcpr EQ 'X'.
      BREAK bb5827.
         ASSIGN lt_output TO <fs_any_tab> .
      * Parse XML string to XML table
      
         CALL FUNCTION 'SMUM_XML_PARSE'
           EXPORTING
             xml_input = l_hobj_xml_def
           TABLES
             xml_table = lt_xml_info
             return    = lt_return.
      * Internal table with mapping
      
         LOOP AT lt_xml_info ASSIGNING <fs_xml_info>.
      
           IF <fs_xml_info>-cname = 'entity'.
      
             l_cvalue = <fs_xml_info>-cvalue.
             SEARCH l_cvalue FOR 'composite'.
             l_offset = sy-fdpos.
             l_offset = l_offset - 1.
             TRY.
                 l_output-infoprovider = <fs_xml_info>-cvalue(l_offset). "CompositeProvider
               CATCH cx_sy_range_out_of_bounds.
                 l_output-infoprovider = <fs_xml_info>-cvalue.
             ENDTRY.
      
           ELSEIF
            <fs_xml_info>-cname = 'targetName'.
             l_output-target = <fs_xml_info>-cvalue.
           ELSEIF
             <fs_xml_info>-cname = 'sourceName'.
             l_output-source = <fs_xml_info>-cvalue.
             APPEND l_output TO lt_output.
           ENDIF.
         ENDLOOP.
      
      ELSEIF lv_flg_adso = 'X'.
      
         ASSIGN lt_output2 TO <fs_any_tab> .
      * Parse XML string to XML table
         CALL FUNCTION 'SMUM_XML_PARSE'
           EXPORTING
             xml_input = l_hobj_xml_def
           TABLES
             xml_table = lt_xml_info
             return    = lt_return.
      * Internal table with mapping
      
         LOOP AT lt_xml_info ASSIGNING <fs_xml_info>.
           IF <fs_xml_info>-cname = 'infoObjectName'.
             l_output2-iobj = <fs_xml_info>-cvalue.
             APPEND l_output2 TO lt_output2.
           ENDIF.
         ENDLOOP.
      ELSEIF lv_flg_haap = 'X'.
      
         ASSIGN lt_output3 TO <fs_any_tab> .
      * Parse XML string to XML table
         CALL FUNCTION 'SMUM_XML_PARSE'
           EXPORTING
             xml_input = l_hobj_xml_def
           TABLES
             xml_table = lt_xml_info
             return    = lt_return.
      * Pick-Up index for
      CLEAR:lv_idx_collect_haap.
         READ TABLE lt_xml_info ASSIGNING <fs_xml_info> WITH KEY cvalue = '0BW_TGT_INFOSOURCE'.
      
         IF sy-subrc = 0.
          lv_idx_collect_haap = sy-tabix.
         ENDIF.
      * Internal table with mapping
      l_output3-object = '0BW_TGT_INFOSOURCE'.
         LOOP AT lt_xml_info ASSIGNING <fs_xml_info>.
          IF sy-tabix > lv_idx_collect_haap.
           IF <fs_xml_info>-cname = 'sourceFieldName'.
             l_output3-source = <fs_xml_info>-cvalue.
           ELSEIF <fs_xml_info>-cname = 'targetFieldName'.
             l_output3-target = <fs_xml_info>-cvalue.
                 APPEND l_output3 TO lt_output3.
           ENDIF.
      
          ENDIF.
         ENDLOOP.
         DELETE ADJACENT DUPLICATES FROM lt_output3.
      ENDIF.
      
      * Output to ALV
      TRY.
           cl_salv_table=>factory(
           IMPORTING
           r_salv_table = go_alv
           CHANGING
           t_table = <fs_any_tab> ).
           " set column optimized
           go_columns = go_alv->get_columns( ).
           go_columns->set_optimize( ).
           " set functions
           go_funcs = go_alv->get_functions( ).
           go_funcs->set_all( ).
           go_alv->display( ).
         CATCH cx_salv_msg INTO go_ex.
           MESSAGE go_ex TYPE 'E'.
      ENDTRY.
      Author's profile photo B. Struijk
      B. Struijk

      Thank you very much for sharing Edwin and others.
      Very helpful.