SAP: How to create Data Source based on InfoSet

SAPIf you want to create a new datasource based on InfoSet where data is retrieved by your own Z-program, then walk through this tutorial and use it as an example or guide during creation of your own data source.

Go to SE11 and create new structure with fields you would like to have in the data source
Structure for Datasource

Go to SE38 and create new Cutomer executable program

REPORT  zis_incmd_data .
*
*---------------------------------------------------------------------*
*   declarations
*   (insert your declarations in this section)
*---------------------------------------------------------------------*
DATA:
  zds_incmd_data                 TYPE zds_incmd_data,
  it_data TYPE STANDARD TABLE OF zds_incmd_data.

DATA:
  lt_prod TYPE TABLE OF /incmd/bapiproductintrange,
  lt_loc TYPE TABLE OF /incmd/bapilocationintrange,
  lt_header TYPE TABLE OF /incmd/bapigrphdr02,
  lt_header_text TYPE TABLE OF /incmd/bapigrphdrtext02,
  l_header_text TYPE /incmd/bapigrphdrtext02,
  lt_items TYPE TABLE OF /incmd/bapigrpitem02,
  lt_add_info TYPE TABLE OF /incmd/bapigrpaddinfotext02,
  lt_group_models TYPE TABLE OF /incmd/bapigrpmodel02,
  lt_grp_loc TYPE TABLE OF /incmd/bapigrplocassign02,
  l_grp_loc TYPE /incmd/bapigrplocassign02,
  lt_return TYPE TABLE OF bapiret2,
  lt_fixvalues TYPE ddfixvalues,
  ls_fixvalue  TYPE ddfixvalue,
  ls_data    TYPE zds_incmd_data.

FIELD-SYMBOLS: <fs_data> TYPE zds_incmd_data,
               <fs_prod> TYPE /incmd/bapiproductintrange,
               <fs_loc> TYPE /incmd/bapilocationintrange,
               <fs_add_info> TYPE /incmd/bapigrpaddinfotext02,
               <fs_return> TYPE bapiret2,
               <fs_header> TYPE /incmd/bapigrphdr02,
               <fs_item> TYPE /incmd/bapigrpitem02,
               <fs_addinfo> TYPE /incmd/bapigrpaddinfotext02,
               <fs_group_model> TYPE /incmd/bapigrpmodel02.

*-------------------------------------------------------------------*
*   selection screen statements
*-------------------------------------------------------------------*
*   (define your selection-screen here)

* !! the following comment MUST NOT BE CHANGED !!
*<QUERY_HEAD>

*-------------------------------------------------------------------*
*   read data into IT_DATA
*-------------------------------------------------------------------*
*  (select your data here into internal table IT_DATA)

APPEND INITIAL LINE TO lt_prod ASSIGNING <fs_prod>.
<fs_prod>-sign = 'I'.
<fs_prod>-option = 'BT'.
<fs_prod>-low =  '000000000000000000'.
<fs_prod>-high = '999999999999999999'.

LOOP AT lt_prod ASSIGNING <fs_prod>.
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = <fs_prod>-low
    IMPORTING
      output = <fs_prod>-low.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = <fs_prod>-high
    IMPORTING
      output = <fs_prod>-high.
ENDLOOP.

APPEND INITIAL LINE TO lt_loc ASSIGNING <fs_loc>.
<fs_loc>-sign = 'I'.
<fs_loc>-option = 'BT'.
<fs_loc>-low =  '0000'.
<fs_loc>-high = '9999'.

CALL FUNCTION '/INCMD/BAPI_GROUP_GETLIST'
  TABLES
    product_int_selection      = lt_prod
    location_int_selection     = lt_loc
    group_header_data          = lt_header
    group_header_text_data     = lt_header_text
    group_item_data            = lt_items
    group_add_info_text_data   = lt_add_info
    group_location_assign_data = lt_grp_loc
    group_models_data          = lt_group_models
    return                     = lt_return.

READ TABLE lt_return ASSIGNING <fs_return> WITH KEY type = 'E' .
IF sy-subrc = 0.
  MESSAGE ID <fs_return>-id
    TYPE 'E'
    NUMBER <fs_return>-number
    WITH <fs_return>-message_v1
         <fs_return>-message_v2
         <fs_return>-message_v3
         <fs_return>-message_v4.
ELSE.
  LOOP AT lt_header ASSIGNING <fs_header>.
    CLEAR l_header_text.
    READ TABLE lt_header_text
      INTO l_header_text
      WITH KEY group_number = <fs_header>-group_number
               language     = sy-langu.

    CLEAR l_grp_loc.
    READ TABLE lt_grp_loc
      INTO l_grp_loc
      WITH KEY group_number = <fs_header>-group_number.

    READ TABLE lt_group_models TRANSPORTING NO FIELDS WITH KEY group_number = <fs_header>-group_number.
    IF sy-subrc <> 0.
      APPEND INITIAL LINE TO lt_group_models ASSIGNING <fs_group_model>.
      <fs_group_model>-group_number = <fs_header>-group_number.
    ENDIF.
    LOOP AT lt_group_models ASSIGNING <fs_group_model> WHERE group_number = <fs_header>-group_number.
      LOOP AT lt_items ASSIGNING <fs_item> WHERE group_number = <fs_header>-group_number.
        APPEND INITIAL LINE TO it_data ASSIGNING <fs_data>.
        <fs_data>-model = <fs_group_model>-model.
        <fs_data>-icno = <fs_item>-group_number.
        <fs_data>-icdesc = l_header_text-group_description.
        <fs_data>-item_no = <fs_item>-item_number.
        CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
          EXPORTING
            input  = <fs_item>-preceding_productid_int
          IMPORTING
            output = <fs_data>-preceding_productid_int.

        CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
          EXPORTING
            input  = <fs_item>-succeeding_productid_int
          IMPORTING
            output = <fs_data>-succeeding_productid_int.

        READ TABLE lt_add_info ASSIGNING <fs_add_info>
          WITH KEY group_number = <fs_item>-group_number
                   item_number  = <fs_item>-item_number.
        IF sy-subrc = 0.
          <fs_data>-freetext = <fs_add_info>-additional_information.
        ENDIF.

        <fs_data>-datefr = <fs_item>-valid_from_date.
        <fs_data>-istat = <fs_header>-status.
        <fs_data>-reltype = <fs_item>-direction_of_interchange.
        <fs_data>-reptype = <fs_item>-replacement_type.
        <fs_data>-useupflg = <fs_item>-useup_strategy.
        <fs_data>-denquant = <fs_item>-preceding_quantity_factor.
        <fs_data>-numquant = <fs_item>-succeeding_quantity_factor.
        CASE <fs_header>-group_type.
          WHEN '1'.  " Product-Product
            <fs_data>-preceding_location = l_grp_loc-location.
            <fs_data>-succeeding_location = l_grp_loc-location.
          WHEN '8'.  " Location product-Location product
            <fs_data>-preceding_location = <fs_item>-preceding_location.
            <fs_data>-succeeding_location = <fs_item>-succeeding_location.
        ENDCASE.
      ENDLOOP.
    ENDLOOP.
  ENDLOOP.
  SORT it_data BY model icno item_no.

* Update ISTAT / STATUS
    CLEAR lt_fixvalues.
    CALL FUNCTION 'DDIF_FIELDINFO_GET'
      EXPORTING
        tabname        = '/INCMD/LKUP'
        fieldname      = 'ISTAT'
        langu          = sy-langu
        lfieldname     = 'ISTAT'
      TABLES
        fixed_values   = lt_fixvalues
      EXCEPTIONS
        not_found      = 1
        internal_error = 2
        OTHERS         = 3.
    IF sy-subrc <> 0.
*     Error in system
    ENDIF.

    LOOP AT it_data ASSIGNING <fs_data>.
      CHECK <fs_data>-status IS INITIAL.

      READ TABLE lt_fixvalues INTO ls_fixvalue WITH KEY low = <fs_data>-istat.
      IF sy-subrc = 0.
        CLEAR ls_data.
        ls_data-istat = <fs_data>-istat.
        ls_data-status = ls_fixvalue-ddtext.
        MODIFY it_data FROM ls_data TRANSPORTING status WHERE istat = ls_data-istat.
      ENDIF.
    ENDLOOP.
ENDIF.

*------------------------------------------------------------*
*   output of the data
*   (this section can be left unchanged)
*------------------------------------------------------------*
LOOP AT it_data ASSIGNING <fs_data>.
  MOVE-CORRESPONDING <fs_data> TO zds_incmd_data                .
* !! the following comment MUST NOT BE CHANGED !!
*<QUERY_BODY>
ENDLOOP.

Please note the commented lines with *<QUERY_HEAD> and *<QUERY_BODY>. These lines MUST NOT BE DELETED and must be present in the program. These are considered as markup tags used by the info set.

This program can also be incorporated into the query itself but its further maintenance is a bit of pain so I prefer to have the query and program for data retrieval separated.

Now go to SQ02 and create new query. Enter a name for the query and select radio “Data retrieval by program” where you enter your “Data structure” and you select that you want to use “External program” where you enter the name of your data retrieval program that you created at beginning of this article.
Infoset creation

After saving the new infoset, press the Generate button.
Infoset code generation

Infoset can be tested in transaction SQ01 but before this you need to assign your infoset to some user group (Menu – Environment – user Groups, section User group assignment). If you have assigned your infoset to a group you can go back to SQ01 and press the “InfoSet Query” button where you select your infoset.
Testing infoset
In the displayed window you can play with data selection and retrieval. If you have written the data retrieval program correctly you’ll see some results.
Infoset test results

Now go to transaction RSO2 where you create a new datasource with data “Extraction from Query” where you enter the name of your new query.
Creation of new Data source
Press SAVE and define which fields will be available for selection and which of them will be visible.
New Datasource field selection
Press SAVE again and your data source should be created.

You can test the functionality using transaction RSA3 where you enter the name of your new datasource and press F8 (Extraction). If everything goes well a popup with number of retrieved items is displayed together with buttons “ALV Grid”, “List” and “Log” where you can view the selected results.
Testing datasource in RSA3

Leave a Reply