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;
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:
This XML-string is displayed in the ‘hierachical view’ when you use the ‘Dispay XML’ button in RSA1 (partially shown below):
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
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’:
When all values have been checked, the values are displayed by making use of the SAP class cl_salv_table:
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’.
Hi Mr. Neuenschwander!
Thanks for the info, this should come in handy!
Alles goed verder?
Sjoerd
Hello,
Good piece of document thanks for sharing 🙂
Regards,
Harish
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:
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
Hi Markus,
Thanks for the addition, I've updated the code with your correction!
Regards,
Edwin
Thanks Edwin 😉
Handig voor RSDODSOIOBJ <-> ADSO ook?
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.
Hi Mathijs,
Good one, thanks!
Hello.. what is the original program? Â I don't see an attachment.
Hello, I am unable to see the attachment. Please post the code.
Hi,
The attachment has been removed after the migration of the old Community, please find the code below:
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.
thanks a lot for this post.
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
Thanks for this blog.
I just added support for transformation with id that one can pick in RSTRANGUI tcode.
Thank you very much for sharing Edwin and others.
Very helpful.