Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

According to business requirement, the hierarchy is being created on the BI side with the help of a custom program is executed on the ECC side to extract the data from the tables present in the ECC. We are creating a program in source system i.e. ECC to create flat file (.CSV format) in hierarchy format (as required by BW7.3 hierarchy DataSource), which will be uploaded at application server. The program will directly upload the file to the Application server, and the generic flat data source in BW 7.3 will pick up the file from the application server and load it into our InfoObject.

Business Scenario:

The standard business content supports number of main hierarchies such as Cost Center hierarchy, Material, Plant, Work Center, GL Account, etc. We might come across some custom requests which require us to extract the data on the basis of database tables and generate a custom hierarchy based on that in BW. In current scenario, let us consider a generic Work Center Hierarchy. Work centers belonging to different region, department and division can be grouped into a work center hierarchy. Apart from the top of the hierarchy - the hierarchy root - every work center in the hierarchy is subordinate to another work center. In our requests, for this, we try to use customized generic hierarchies.

Applies to: SAP ECC 6.0, SAP BI 7.3.

Configure DataSource in BI:

To create a generic work center hierarchy, we need to create a generic data source in BI with type ‘hierarchies’. For this, we need to login to BI and go to RSA1 T-code.

To create a hierarchy data source, we need to follow the below steps:

1.       Select DataSources from the Modeling section.

2.       Select the DataSource icon from the top menu or press Ctrl+F8.

3.       Enter the DataSource hierarchy name, select the source system as FILE, select the DataSource Data Type as Hierarchies and press Enter.

4.       Enter the description and Application component details where the DataSource will be placed.

5.       Now in the Extraction tab, specify the Target InfoObject in which you wish to associate the Work Center Hierarchy into.

6.       In the File Structure tab, we will be able to see the structure of the hierarchy automatically created. This is same as the hierarchy attributes.

7.       Activate the DataSource.

Configuring ECC:

The Work Center Hierarchy is of the below mentioned structure.

To get the data in the attributes associated in the hierarchy, follow the steps:

1.       Go to SE38 T-code to create a custom program.

 

2.       In this, specify a Program name and the SubObjects as Source Code and click on create.

3.       Enter the title for the program and within the attributes section, select the Attribute type as Executable program and status as SAP Standard Production Program.  You can also specify the package for all your BW requests. Press Enter.

4.       The ABAP Editor opens up which allows us to write a program. The following program is extracting the work center data from the HRP9002 table.

Prerequisites:

Create a custom infotype hrp9002 to get the data for location, region, district and division.The InfoType hrp9002 is shown as the following:

       

REPORT  <Program Name>.
INCLUDE
zi_workcenter_top.
INCLUDE
zi_workcenter_sub.
START-OF-SELECTION.
*Perform to fetch data from HRP9002
  PERFORM
f_fetch_data_hrp9002.
*Perform to fill YDIVISION node in internal table
  PERFORM
f_fill_table.
*Perform to fill Hierarchy in internal table
  PERFORM
f_create_hierarchy.
  PERFORM
f_final_hierarchy_table.
  IF gt_hierarchy1 IS NOT INITIAL.
    PERFORM
f_get_text.
    PERFORM
f_file_application_server.
  ELSE.
    MESSAGE TEXT-004 TYPE 'E'. "error message
    LEAVE LIST-PROCESSING.
  ENDIF.

5.       The custom Include zi_workcenter_top is created in order to provide all the declarations related to the hierarchy. While creating an include program, select the Attribute type as “Include”. The following code explains the declarations made within zi_workcenter_top.

TABLES: hrp9002.

TYPES: BEGIN OF ty_hrp9002,
        yy_DIVISION       TYPE ze_division,
        plvar             TYPE plvar,
        otype             TYPE otype,
        objid             TYPE hrobjid,
        subty             TYPE subtyp,
        begda             TYPE begdatum,
        endda             TYPE enddatum,
        YY_REGION         TYPE ze_region,
        YY_DISTRICT       TYPE ze_district,
       END OF ty_hrp9002,

       BEGIN OF ty_hierarchy,
         nodid    TYPE rsshnodeid,
         iobjnm   TYPE rsiobjnm,
         nodename TYPE rsshnodename,
         link     TYPE rslink,
         parentid TYPE rsparent,
         langu    TYPE sy-langu,
         txtsh    TYPE text20,
         txtmd    TYPE text40,
         txtlg    TYPE text60,
         tlevel   TYPE rstlevel,
         childid  TYPE rschild,
         nextid   TYPE rsnext,
       END OF ty_hierarchy.

DATA: gt_hrp9002    TYPE STANDARD TABLE OF ty_hrp9002,
      gt_hierarchy  TYPE STANDARD TABLE OF ty_hierarchy,
      gt_hierarchy1 TYPE STANDARD TABLE OF ty_hierarchy,
      gw_hrp9002    TYPE ty_hrp9002,
      gw_hierarchy  TYPE ty_hierarchy.

DATA: gv_count        TYPE char03,
      gv_nodename     TYPE rsshnodename,
      gv_filepath     TYPE rlgrap-filename,
      gv_error        TYPE string,
      gv_exception    TYPE REF TO cx_root.

FIELD-SYMBOLS: <gfs_hierarchy>  TYPE ty_hierarchy.

CONSTANTS: gc_plvar    TYPE plvar         VALUE '01',
           gc_otype    TYPE otype         VALUE 'A',
           gc_subty    TYPE subtyp        VALUE '0001',
           gc_division TYPE rsiobjnm      VALUE 'YDIVISION',
           gc_district TYPE rsiobjnm      VALUE 'YDISTRICT',
           gc_region   TYPE rsiobjnm      VALUE 'YREGION',
           gc_workcen  TYPE rsiobjnm      VALUE 'YWORKCENTER',
           gc_loctype  TYPE rsiobjnm      VALUE 'YLOCATION',
           gc_nodename TYPE rsshnodename  VALUE 'ROOT',
           gc_one      TYPE rsparent      VALUE '1',
           gc_level01  TYPE rstlevel      VALUE '1',
           gc_level02  TYPE rstlevel      VALUE '2',
           gc_level03  TYPE rstlevel      VALUE '3',
           gc_level04  TYPE rstlevel      VALUE '4',
           gc_level05  TYPE rstlevel      VALUE '5',
           gc_level06  TYPE rstlevel      VALUE '6',
           gc_lang     TYPE sylangu       VALUE 'E',
           gc_err      TYPE c             VALUE 'E'.

6.       The custom Include zi_workcenter_sub is created in order to write all the perform codes (functions) related to the hierarchy. While creating an include program, select the Attribute type as “Include”. The following code explains the declarations made within zi_workcenter_sub.

FORM f_fetch_data_hrp9002 .

  DATA: lv_date TYPE sy-datum.
  lv_date = sy-datum.

  SELECT plvar otype objid subty begda endda
         YY_REGION
         YY_DISTRICT yy_DIVISION
    FROM hrp9002
    INTO CORRESPONDING FIELDS OF TABLE gt_hrp9002
    WHERE plvar = gc_plvar
    AND   otype = gc_otype
    AND   subty = gc_subty
    AND   begda =< lv_date
    AND   endda >= lv_date.
  IF sy-subrc NE 0.
    REFRESH gt_hrp9002.
  ELSE.
    SORT gt_hrp9002 BY plvar otype objid subty begda endda
                       YY_REGION YY_DISTRICT yy_DIVISION.
    DELETE ADJACENT DUPLICATES FROM gt_hrp9002 COMPARING ALL FIELDS.
    SORT gt_hrp9002 BY plvar otype objid subty endda DESCENDING
                                               begda DESCENDING.
    DELETE ADJACENT DUPLICATES FROM gt_hrp9002 COMPARING plvar otype
                                                         objid subty.
  ENDIF.
ENDFORM.                    " F_FETCH_DATA_HRP9002
*&---------------------------------------------------------------------*
*&      Form  F_FILL_TABLE
*&---------------------------------------------------------------------*
FORM f_fill_table .

  DATA: lc_node     TYPE rsiobjnm VALUE '0HIER_NODE',
        lc_parentid TYPE rsparent VALUE '0'.

  CLEAR gv_count.
  SORT gt_hrp9002 BY yy_DIVISION.

  PERFORM f_fill_final_table USING lc_node
                                   gc_nodename
                                   gc_level01
                                   lc_parentid.

  LOOP AT gt_hrp9002 INTO gw_hrp9002 WHERE yy_DIVISION IS NOT INITIAL.
*Append YDIVISION Node to the final table
    AT NEW yy_DIVISION.
      gv_nodename = gw_hrp9002-yy_DIVISION.
      PERFORM f_fill_final_table USING gc_division
                                       gv_nodename
                                       gc_level02
                                       gc_one.
      CLEAR gv_nodename.
    ENDAT.
  ENDLOOP.

ENDFORM.                    " F_FILL_TABLE
*&---------------------------------------------------------------------*
*&      Form  F_CREATE_HIERARCHY
*&---------------------------------------------------------------------*
FORM f_create_hierarchy.

  DATA: lv_blank TYPE rsshnodename.

  CLEAR: gw_hierarchy, gw_hrp9002.
  SORT   gt_hrp9002 BY yy_DIVISION "yy_location_type
                       YY_REGION YY_DISTRICT objid.

  IF gt_hierarchy1 IS NOT INITIAL.
    gt_hierarchy[] = gt_hierarchy1[].
*--When Division is present
    LOOP AT gt_hierarchy INTO gw_hierarchy.
      PERFORM f_set_hierarchy USING gw_hierarchy-nodename
                                    gw_hierarchy-nodid.
    ENDLOOP.
  ENDIF.

*when division is not present
  PERFORM f_set_hierarchy USING lv_blank
                                gc_one.

ENDFORM.                    " F_CREATE_HIERARCHY
*&---------------------------------------------------------------------*
*&      Form  F_FINAL_HIERARCHY_TABLE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM f_final_hierarchy_table .

  DATA: lv_tabix TYPE sy-tabix.

  SORT gt_hierarchy1 BY iobjnm nodename nodid ASCENDING.
  LOOP AT gt_hierarchy1 INTO gw_hierarchy.
    lv_tabix = sy-tabix + 1.
    READ TABLE gt_hierarchy1 ASSIGNING <gfs_hierarchy> INDEX lv_tabix.
    IF sy-subrc EQ 0.
      IF  gw_hierarchy-iobjnm   = <gfs_hierarchy>-iobjnm
      AND gw_hierarchy-nodename = <gfs_hierarchy>-nodename.
        <gfs_hierarchy>-link = 'X'.
      ENDIF.
    ENDIF.
  ENDLOOP.

  SORT gt_hierarchy1 BY nodid.
  CLEAR: lv_tabix, gw_hierarchy.
  UNASSIGN <gfs_hierarchy>.

ENDFORM.                    " F_FINAL_HIERARCHY_TABLE
*&---------------------------------------------------------------------*
*&      Form  F_FILL_FINAL_TABLE
*&---------------------------------------------------------------------*
FORM f_fill_final_table  USING p_iobjnm   TYPE rsiobjnm
                               p_nodename TYPE rsshnodename
                               p_level    TYPE rstlevel
                               p_parentid TYPE rsparent.

  DATA: lw_hierarchy TYPE ty_hierarchy.

  gv_count = gv_count + 1.
  lw_hierarchy-nodid    = gv_count.
  lw_hierarchy-iobjnm   = p_iobjnm.
  lw_hierarchy-nodename = p_nodename.
  lw_hierarchy-tlevel   = p_level.
  lw_hierarchy-parentid = p_parentid.
  lw_hierarchy-langu    = gc_lang.

  APPEND lw_hierarchy TO gt_hierarchy1.
  CLEAR: lw_hierarchy.

ENDFORM.                    " F_FILL_FINAL_TABLE
*&---------------------------------------------------------------------*
*&      Form  F_SET_HIERARCHY
*&---------------------------------------------------------------------*
FORM f_set_hierarchy  USING p_nodname TYPE rsshnodename
                            p_nodid   TYPE rsshnodeid.

  DATA: lv_parentid      TYPE rsparent,
        lw_hierarchy1    TYPE ty_hierarchy,
        lv_location_type TYPE ye_location_type.

  LOOP AT gt_hrp9002 INTO gw_hrp9002 WHERE yy_DIVISION = p_nodname.
    lv_parentid = p_nodid.


*Update Region Node at 4th Level
    IF gw_hrp9002-YY_REGION IS NOT INITIAL.
*Check if the region is already present
      READ TABLE gt_hierarchy1 INTO lw_hierarchy1
      WITH KEY iobjnm   = gc_region
               nodename = gw_hrp9002-YY_REGION
               parentid = lv_parentid.
      IF sy-subrc NE 0.
        gv_nodename = gw_hrp9002-YY_REGION.
        PERFORM f_fill_final_table USING gc_region
                                         gv_nodename
                                         gc_level03
                                         lv_parentid.
        CLEAR: lv_parentid, gv_nodename.
        lv_parentid = gv_count.
      ELSE.
        lv_parentid = lw_hierarchy1-nodid.
      ENDIF.
    ENDIF.

*Update District Node at 5th Level
    IF gw_hrp9002-YY_DISTRICT IS NOT INITIAL.
*Check if the district is already present
      READ TABLE gt_hierarchy1 INTO lw_hierarchy1
      WITH KEY iobjnm   = gc_district
               nodename = gw_hrp9002-YY_DISTRICT
               parentid = lv_parentid.
      IF sy-subrc NE 0.
        gv_nodename = gw_hrp9002-YY_DISTRICT.

        PERFORM f_fill_final_table USING gc_district
                                         gv_nodename
                                         gc_level04
                                         lv_parentid.
        CLEAR: lv_parentid, gv_nodename.
        lv_parentid = gv_count.
      ELSE.
        lv_parentid = lw_hierarchy1-nodid.
      ENDIF.
    ENDIF.

*Update work center Node at 6th Level
    IF gw_hrp9002-objid IS NOT INITIAL.
*Check if the workcenter is already present
      READ TABLE gt_hierarchy1 INTO lw_hierarchy1
      WITH KEY iobjnm   = gc_workcen
               nodename = gw_hrp9002-objid
               parentid = lv_parentid.
      IF sy-subrc NE 0.
        gv_nodename = gw_hrp9002-objid.
        PERFORM f_fill_final_table USING gc_workcen
                                         gv_nodename
                                         gc_level05
                                         lv_parentid.
        CLEAR: lv_parentid, gv_nodename.
      ELSE.
        lv_parentid = lw_hierarchy1-nodid.
      ENDIF.
    ENDIF.
  ENDLOOP.

ENDFORM.                    " F_SET_HIERARCHY
*&---------------------------------------------------------------------*
*&      Form  F_FILE_APPLICATION_SERVER
*&---------------------------------------------------------------------*
FORM f_file_application_server .

  DATA: lv_logical_filename   TYPE fileintern,
        lv_physical_filename  TYPE string,
        lv_output             TYPE string,
        lv_sysid_uc           TYPE sysid,
        lv_sysid_lc           TYPE sysid.

  CONSTANTS: lc_semicolon TYPE c VALUE ';'.

  lv_logical_filename = '<LOGICAL_PATH_NAME'.
*get the file from logical path
  CALL FUNCTION 'FILE_GET_NAME'
    EXPORTING
      logical_filename        = lv_logical_filename
      use_presentation_server = 'X'
    IMPORTING
      file_name               = lv_physical_filename
    EXCEPTIONS
      file_not_found          = 1
      OTHERS                  = 2.
  .
  IF sy-subrc <> 0.
    MESSAGE text-001 TYPE 'E'. "DISPLAY LIKE gc_err. "folder path is not maintained
    LEAVE LIST-PROCESSING.
  ELSE.

*Open the filepath / dataset on the application server for writing
    TRY.
        OPEN DATASET lv_physical_filename FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
      CATCH cx_dynamic_check INTO gv_exception.
        gv_error = gv_exception->get_text( ).
        MESSAGE gv_error TYPE 'E'.
    ENDTRY.
*Check if the OPEN has been successful
    IF sy-subrc EQ 0.
      LOOP AT gt_hierarchy1 INTO gw_hierarchy.
        CONCATENATE gw_hierarchy-nodid
         gw_hierarchy-iobjnm
         gw_hierarchy-nodename
         gw_hierarchy-link
         gw_hierarchy-parentid
         gw_hierarchy-langu
         gw_hierarchy-txtsh
         gw_hierarchy-txtmd
         gw_hierarchy-txtlg
         gw_hierarchy-tlevel
         gw_hierarchy-childid
         gw_hierarchy-nextid  INTO lv_output SEPARATED BY lc_semicolon.
        TRANSFER lv_output TO lv_physical_filename.
        CLEAR: lv_output, gw_hierarchy.
      ENDLOOP.
    ENDIF.

    TRY.
        CLOSE DATASET lv_physical_filename.
      CATCH cx_dynamic_check INTO gv_exception.
        gv_error = gv_exception->get_text( ).
        MESSAGE gv_error TYPE 'E'.
    ENDTRY.
    IF sy-subrc EQ 0.
      MESSAGE text-003 TYPE 'S'.
    ENDIF.

  ENDIF.

ENDFORM.                    " F_FILE_APPLICATION_SERVER
*&---------------------------------------------------------------------*
*&      Form  F_GET_TEXT
*&---------------------------------------------------------------------*
FORM f_get_text .

  DATA: lt_div_text  TYPE STANDARD TABLE OF zthrom_division,
        lt_reg_text  TYPE STANDARD TABLE OF zthrom_region,
        lt_dist_text TYPE STANDARD TABLE OF zthrom_district,
        lw_div_text  TYPE zthrom_division,
        lw_reg_text  TYPE zthrom_region,
        lw_dist_text TYPE zthrom_district.

*get the text of division
  SELECT * FROM zthrom_division
    INTO TABLE lt_div_text
    FOR ALL ENTRIES IN gt_hrp9002
    WHERE yy_DIVISION EQ gt_hrp9002-yy_DIVISION.
  IF sy-subrc EQ 0.
    SORT lt_div_text BY yy_DIVISION.
  ELSE.
    REFRESH lt_div_text.
  ENDIF.

*get the text of district
  SELECT * FROM zthrom_district
    INTO TABLE lt_dist_text
    FOR ALL ENTRIES IN gt_hrp9002
    WHERE YY_DISTRICT EQ gt_hrp9002-YY_DISTRICT.
  IF sy-subrc EQ 0.
    SORT lt_dist_text BY YY_DISTRICT.
  ELSE.
    REFRESH lt_dist_text.
  ENDIF.

*get the text of region
  SELECT * FROM zthrom_region
    INTO TABLE lt_reg_text
    FOR ALL ENTRIES IN gt_hrp9002
    WHERE YY_REGION EQ gt_hrp9002-YY_REGION.
  IF sy-subrc EQ 0.
    SORT lt_reg_text BY YY_REGION.
  ELSE.
    REFRESH lt_reg_text.
  ENDIF.

  LOOP AT gt_hierarchy1 ASSIGNING <gfs_hierarchy>.
    CASE <gfs_hierarchy>-iobjnm.
      WHEN gc_division.
        READ TABLE lt_div_text INTO lw_div_text
        WITH KEY yy_DIVISION = <gfs_hierarchy>-nodename.
        IF sy-subrc EQ 0.
          <gfs_hierarchy>-txtsh = lw_div_text-yy_DIVISION_text.
          <gfs_hierarchy>-txtmd = lw_div_text-yy_DIVISION_text.
          <gfs_hierarchy>-txtlg = lw_div_text-yy_DIVISION_text.
        ENDIF.
        <gfs_hierarchy>-iobjnm = '0HIER_NODE'.
      WHEN gc_district.
        READ TABLE lt_dist_text INTO lw_dist_text
        WITH KEY YY_DISTRICT = <gfs_hierarchy>-nodename.
        IF sy-subrc EQ 0.
          <gfs_hierarchy>-txtsh = lw_dist_text-YY_DISTRICT_text.
          <gfs_hierarchy>-txtmd = lw_dist_text-YY_DISTRICT_text.
          <gfs_hierarchy>-txtlg = lw_dist_text-YY_DISTRICT_text.
        ENDIF.
        <gfs_hierarchy>-iobjnm = '0HIER_NODE'.
      WHEN gc_region.
        READ TABLE lt_reg_text INTO lw_reg_text
        WITH KEY YY_REGION = <gfs_hierarchy>-nodename.
        IF sy-subrc EQ 0.
          <gfs_hierarchy>-txtsh = lw_reg_text-YY_REGION_text.
          <gfs_hierarchy>-txtmd = lw_reg_text-YY_REGION_text.
          <gfs_hierarchy>-txtlg = lw_reg_text-YY_REGION_text.
        ENDIF.
        <gfs_hierarchy>-iobjnm = '0HIER_NODE'.
        <gfs_hierarchy>-iobjnm = '0HIER_NODE'.
    ENDCASE.

  ENDLOOP.

  UNASSIGN <gfs_hierarchy>.
  REFRESH: lt_div_text, lt_dist_text, lt_reg_text. "lt_loc_text,
  CLEAR:   lw_div_text, lw_dist_text, lw_reg_text. "lw_loc_text,

ENDFORM.                    " F_GET_TEXT

Configuring Logical File Path:

Create a logical path to physical path mapping in FILE T-Code. Below is the configuration for setting the physical path of the Hierarchy.

Data Extraction Settings:

               

To extract the data from the physical file stored on the application server into BI, we need to make changes to the Hierarchy DataSource of the Work Center. For this, go to RSA1 T-code in the BI Development server.

Select the Work Center Hierarchy DataSource and go to extraction tab. Change the Adapter settings to “Load Test-Type File from Application Server”. Set the File Name by selecting the appropriate logical file name present on the application server.

Once the File Name is selected, activate the DataSource and create an InfoPackage corresponding to the Hierarchy DataSource.

Now create a transformation with the following rule groups:

a.       Hierarchy Header

                   

b.      Hierarchy Description

                    

c.       Hierarchy Structure

                    

                    Write a routine on the Workcenter InfoObject as following:

                       

d.      Descriptions for Text Nodes

                    

Now, create a DTP for the corresponding Hierarchy DataSource and execute it to move the contents to the Work Center InfoObject.

Note: Please check the Activate Hierarchy check box in the Update tab to activate the hierarchy whenever the DTP is executed.

To see the hierarchy, right click on the Workcenter (Hierarchies) section and select Maintain Hierarchies.

This will open the initial screen of the hierarchy maintenance.

Double click on the Workcenter hierarchy to get the Active version of the Hierarchy ‘Workcenter’ display.

Labels in this area