Skip to Content
Technical Articles

Simplest Way to Generate a Custom Hierarchy in BW – Without a DataSource & Using Master Data (Attribute/s) Only.

1. Introduction:

Lately, I was asked to design a solution that generates a custom hierarchy for an InfoObject. InfoObject to be used is 0CUSTOMER and 0CUSTOMER has an attribute – ZCCST_GRP (Customer Group). The hierarchy must use various customer groups as text nodes and under those nodes must lay our customers. Essentially a tree structure where all the customers are clubbed under their parent customer groups.

The only object that we will need to achieve this is a self-transformation on 0CUSTOMER (from ATTR to HIERARCHY) (and an expert routine on that transformation). No hierarchy data source is required!

The picture below shows the required result:Expected Output - ABC, TEST1, NE*****, TEST2, TEST3, and TEXT 
are customer groups and they have their respective customers 
underneath them.

 

All the existing solutions tell you to generate an export DataSource on 0CUSTOMER and write a Customer Exit/BAdI for that DataSource and whatnot. That certainly isn’t required anymore with the new Hierarchy framework (BW 7.3 & above) and this solution seems to be the neatest.

2. System Details & Requirements:

I’m working on BW 7.5 but this should work on any system above 7.3. (Irrespective of this blog, my deepest sympathies if you’re below 7.3).

3. Transformation & Routine:

Create a transformation for the hierarchy subtype of 0CUSTOMER.

In source, select Object Type = InfoObject, Name = 0CUSTOMER, and 
Subtype = Attributes.Once the transformation is created, create an expert routine for it. 
From menu bar select: Edit -> Routines -> Expert Routine.

 

Now, all we need to do is write the code in the expert routine and our solution will be complete. But before that, one must understand that the transformations for hierarchies are segmented by default. These segments will be utilized in the expert routine and hence, we need a brief understanding of them. If you already do understand this, skip step 4, and jump to the code.

4. Segments in Hierarchy Transformations:

There are 5 segments in total. You can view them just next to the rule group button.

See the picture below for reference:Segments in a Hierarchy Transformation. Highlighted are the ones that 
are mandatory.

 

Out of the 5 segments, only two are mandatory – Hierarchy Header & Hierarchy Structure. Hierarchy Header is mandatory only if you want to generate multiple hierarchies. It can be excluded for a single hierarchy. In this example, I’m only showcasing a single hierarchy but still have used Hierarchy Header for future-proofing the code. I would recommend using it even for a single hierarchy. I have also used Texts for Text Node to enter the text for the text nodes. This isn’t mandatory at all.

Now, just like in a normal transformation we have a result_package in the end routine; here, all 5 target segments have their own result_package called, respectively, result_package_1, result_package_2, result_package_3, result_package_4 & result_package_6 (yes, there is no result_package_5).

So we’ll need to fill these result_packages manually as it is an expert routine and since we want to use three segments, we’ll have to populate the result packages associated with all three of them. They are listed as below:

  • Hierarchy Header – result_package_1 <- Mandatory for multiple hierarchies. Recommended to be used always.
  • Hierarchy Structure – result_package_3 <- Mandatory. This is where all the magic happens.
  • Texts for Text Node – result_package_4 <- Not mandatory. Used for giving texts to text nodes.

5. The Code:

Right. So this is it, structurally. Moving on to the code which is the heart of this solution.

Below is the complete ABAP code that goes into the expert routine and that you can use directly as long as you have used the same InfoObject(0CUSTOMER) & attribute(ZCCST_GRP). Else, just appropriately replace them in the code with your InfoObject and attribute and the rest of the code can be used as-is.

I’ve added comments throughout to give an understanding of every logic. Although if you need any further help, let me know in the comments.

    IF SOURCE_PACKAGE IS NOT INITIAL.
      " Constants Declaration
      CONSTANTS: lc_hier      TYPE rshienm    VALUE 'HIER_CUST_GRP',
                 lc_act       TYPE rsobjvers  VALUE 'A',
                 lc_hier_node TYPE rsnodename VALUE '0HIER_NODE',
                 lc_customer  TYPE rsiobjnm   VALUE '0CUSTOMER',
                 lc_en        TYPE c LENGTH 2 VALUE 'EN'.
 
      " Data Declaration
      DATA: lv_prnt_id    TYPE rshienodid,
            lv_max_nodeid TYPE rshienodid.

      " Macro to increment a number by 1.
      DEFINE increment.
        &1 = &1 + 1.
      END-OF-DEFINITION.

      " Get technical ID (hieid) of customer group hierarchy
      SELECT SINGLE hieid
        FROM rshiedir
        INTO @DATA(lv_hieid_hier_cust_grp)
        WHERE hienm = @lc_hier.

      " Get the MAX node id. This is important. Simply put,
      " always take the max node id and start creating
      " your nodes by adding 1 to it to make sure you
      " don't end up using a node id that is already
      " being used.
      " Also, never use the "WHERE hieid =" clause here
      " as we want maximum node ID across all hierarchies
      " for 0CUSTOMER.
      SELECT SINGLE MAX( nodeid )
        FROM /bi0/hcustomer
        INTO lv_max_nodeid.

      " Get parents that already exist. This includes
      " everything - the root node & the leaves/leaf.
      " This needs to be selected only from our custom
      " hierarchy. So, use the "WHERE hieid =" clause.
      " In the case of multiple hierarchies, add all of 
      " them here, separated by "AND".
      SELECT hieid, nodeid, nodename
        FROM /bi0/hcustomer
        INTO TABLE @DATA(lt_existing_parents)
        WHERE hieid = @lv_hieid_hier_cust_grp
        AND   objvers = @lc_act.

      SORT lt_existing_parents BY hieid nodename.
      SORT SOURCE_PACKAGE BY customer.

      " lv_index will be used to increment the node ID.
      DATA(lv_index) = 00000000.

      LOOP AT SOURCE_PACKAGE ASSIGNING <source_fields>.
*--------------------------------------------------------------------*
*~~~~~~~~~~~~~~~~~~Process Hierarchy - HIER_CUST_GRP~~~~~~~~~~~~~~~~~*
*--------------------------------------------------------------------*
        IF <source_fields>-/bic/zccst_grp <> space.
          CLEAR RESULT_FIELDS_3.
          " Fill result_package_1 with the technical name
          " for the hierarchy.
          RESULT_PACKAGE_1 = VALUE #( BASE RESULT_PACKAGE_1 (
          objectid = lv_hieid_hier_cust_grp
          h_hienm = CONV char30( lc_hier )
          )  ).

          " Reading result_package_3 to check if we already have a
          " root node (customer group) added. If we have it already,
          " then it's a case of multiple customers per customer group.
          " So skip adding customer group again and keep adding the
          " customers for it.
          " ***(Don't use binary search here.)***
          " Sy-subrc = 0 means customer group already exists.
          READ TABLE RESULT_PACKAGE_3 INTO RESULT_FIELDS_3
          WITH KEY h_hiernode = <source_fields>-/bic/zccst_grp.
          IF sy-subrc <> 0.
            "See if we already have this customer group in hierarchy.
            READ TABLE lt_existing_parents ASSIGNING
            FIELD-SYMBOL(<ep_cust_grp>)
            WITH KEY hieid = lv_hieid_hier_cust_grp
                     nodename = <source_fields>-/bic/zccst_grp
            BINARY SEARCH.
            IF sy-subrc = 0.
              " We have the customer group already. So write its node_id
              " from lt_existing_parents table to result_package_3.
              " T_level will be 1 as it's root node.
              RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
                        objectid = lv_hieid_hier_cust_grp
                        h_nodeid = <ep_cust_grp>-nodeid
                        h_hiernode = <source_fields>-/bic/zccst_grp
                        h_iobjnm = lc_hier_node
                        h_tlevel = 01 "Always 01
                        )  ).
              " Store parent_id. Will be used when adding customers.
              lv_prnt_id = <ep_cust_grp>-nodeid.
            ELSE.
              " Increment lv_index before (manually) adding any node.
              increment lv_index.

              " Customer grp neither already added to result_package_3,
              " nor exists in backend. So, it's a new customer group.
              RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
                        objectid = lv_hieid_hier_cust_grp
                        h_nodeid = lv_max_nodeid + lv_index
                        h_hiernode = <source_fields>-/bic/zccst_grp
                        h_iobjnm = lc_hier_node
                        h_tlevel = 01 "Always 01
                        )  ).
              " Store parent_id. Will be used when adding customers.
              lv_prnt_id = lv_max_nodeid + lv_index.
            ENDIF.
          ELSE.
            " Store parent_id. Will be used when adding customers.
            lv_prnt_id = RESULT_FIELDS_3-h_nodeid.
          ENDIF.

          " Increment lv_index before (manually) adding any node.
          increment lv_index.

          " Check if customer already exists.
          " If it does, copy the node_id from lt_existing_parents to
          " result_package_3.
          " *** But do not copy the parent_id. ***
          " Parent_ID must be entered from lv_prnt_id var.
          " This will take care of the case where a customer is moved
          " from one customer group to another customer group.
          READ TABLE lt_existing_parents ASSIGNING
          FIELD-SYMBOL(<ep_cust_grp_1>)
          WITH KEY hieid = lv_hieid_hier_cust_grp
                   nodename = <source_fields>-customer
          BINARY SEARCH.
          IF sy-subrc = 0.
            RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
            objectid = lv_hieid_hier_cust_grp
            h_nodeid = <ep_cust_grp_1>-nodeid
            h_iobjnm = lc_customer
            customer = <source_fields>-customer
            h_parentid = lv_prnt_id "IMP!
            h_tlevel = 02 "Always 02
            )  ).
          ELSE.
            " New customer. Add to result_package_3.
            RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
            objectid = lv_hieid_hier_cust_grp
            h_nodeid = lv_max_nodeid + lv_index
            h_iobjnm = lc_customer
            customer = <source_fields>-customer
            h_parentid = lv_prnt_id
            h_tlevel = 02 "Always 02
            )  ).
          ENDIF.
          " Fill the Text in result_package_4 table.
          " Key is used as text here.
          " Always give value for langu. Texts only work
          " if a language is supplied.
          RESULT_PACKAGE_4 = VALUE #( BASE RESULT_PACKAGE_4 (
          objectid = lv_hieid_hier_cust_grp
          langu = lc_en
          h_hiernode = <source_fields>-/bic/zccst_grp
          txtlg = <source_fields>-/bic/zccst_grp
          txtmd = <source_fields>-/bic/zccst_grp
          txtsh = <source_fields>-/bic/zccst_grp
          )  ).
        ENDIF.
      ENDLOOP.
    ENDIF.

The code above simply takes all the customer groups in the source_package and creates a text node for each of them. Then it takes all the customers and adds them underneath their respective customer group nodes. result_package_3 is responsible for doing both.

lv_max_nodeid – this variable holds the maximum node id across all the hierarchies for our InfoObject. This will be used to ensure that we never overlap the node IDs of two different nodes.

lt_existing_parents – this internal table holds all the nodes that already exist for this hierarchy. So, for example, if node – ABC is already present, it will be held in this table. This is true for both – customer groups and customers. If you’re running this code for the first time, the internal table will be blank. Using this we can take care of the case when a customer moves from one customer group to another.

Note: Always give value for langu when populating result_package_4. Texts only work if a language is supplied.

6. Test Cases:

I have tested this solution extensively and found it working for all the cases mentioned below:

  1. Hierarchy Tampering – If someone manually deletes any text node or an inner node or anything really, just reload the DTP and all will be good.
  2. Data Update – If master data is updated in any way – a customer is deleted, added, or moved to another customer group, or a customer group is deleted or renamed or anything, reload the DTP and we will have an updated hierarchy as per the updated master data.
  3. Different Levels – I have used a simpler example to keep things straight – but you can change the T_Levels and create different text nodes and levels as per your requirement. Just add them all to result_package_3.
  4. Multiple Hierarchies – I originally wrote this blog showcasing generation of 2 different hierarchies but decided to go with one to keep things simple. I have used and tested 2 hierarchies but you can essentially generate any number of hierarchies using the code given. The code will need to be altered, yes. But once you understand how it works for a single hierarchy, it becomes rather simple to alter it for any further hierarchies.
  5. Performance – I have tested it thoroughly and performance won’t be a problem at all.
A hierarchy with around 25,000 nodes and the DTP loads within 
4 seconds.DTP

 

This brings us to the end of the blog. Let’s summarize:

  1. Create a transformation from ATTR to HIERARCHY and create an expert routine on it.
  2. Copy the code given above into the expert routine and alter it as per your requirements.
  3. ???
  4. Profit.

Do share your thoughts if you made it so far. Thanks.

 

36 Comments
You must be Logged on to comment or reply to a post.
  • Hello Sagar,

    thanks for sharing the information. I recently encountered a 3.x DataSource with a CMOD implementation within the BW which cannot be migrated to BW/4HANA. The way you described, is a possible way to solve this.

    And you made my day with your summary. 🙂

    Best regards,

    Corvin

    • Hi Corvin,

      I recently encountered a 3.x DataSource with a CMOD implementation within the BW which cannot be migrated to BW/4HANA

      Yes, many times we don’t even have a DataSource, especially for custom InfoObjects. This to me is a perfect solution for such cases. And it kind of makes hierarchy DataSources unnecessary, at least for simpler hierarchies (and if you’re comfortable with ABAP).

      The way you described, is a possible way to solve this.

      Please do update if this worked for you or not. Will be very useful for me and others.

      And you made my day with your summary.

      That was the intent. 🙂

      Regards,

      Sagar

  • Hello Sagar,

    great blog post! I was recently developing similar solution. One of the things I struggled with was how to generate an nodeid. I wasn’t able to find any standard functionality (FM, class/method etc) that could generate it. So I ended up with same solution as you -> retrieve the highest nodeid and increase it by one. Any chance that you found something in this regard how to generate it?

    thanks

    • Hello Martin,

      Frankly, I didn’t look for it. I expected SAP to have written a complete How-To guide on this topic but they didn’t. So, disappointedly, I decided to do it myself and go full custom on it as I only had half a day to come up with a working solution.

      It’s possible that there is an FM somewhere that does take care of nodeids for us but also equally possible that SAP like us just incremented the nodeids locally and didn’t release a separate FM for it.

      Regards,

      Sagar

  • Hi Sagar,

    one more thing. I was curious whether you managed to add also short / medium and long description of hierarchy header. I mean the texts that are appearing in hierarchy maintenance screen in SAP GUI.

    I thought that it should be handled by using source_package_1 table but that table has only following fields:

    OBJECTID
    H_HIENM
    H_NORESTNO
    H_STARTLEV
    H_NODEPOS
    H_LEAFNOD
    H_ALEAFNOC
    H_TIMESTMP
    LOGSYS
    RECORD

    So it doesn’t appear to be done that way. Any experience with how could we maintain those texts from the data load? Thanks

    /
    • Hello Marcus,

      The portion of the code below takes care of texts:

                " Fill the Text in result_package_4 table.
                " Key is used as text here.
                RESULT_PACKAGE_4 = VALUE #( BASE RESULT_PACKAGE_4 (
                objectid = lv_hieid_hier_cust_grp
                langu = lc_en
                h_hiernode = <source_fields>-/bic/zccst_grp
                txtlg = <source_fields>-/bic/zccst_grp
                txtmd = <source_fields>-/bic/zccst_grp
                txtsh = <source_fields>-/bic/zccst_grp
                )  ).

      Just fill result_package_4 as shown above. Remember to always give value for ‘langu’.

      Texts seem to work only if we give language. I’ll mention this in the blog itself as well. Let me know if it works.

      Regards.

      • Hi Sagar,

        unfortunately in my case it doesn’t work. The result_package_4 itab seems to carry hierarchy header but in my case that uses expert routine it doesn’t.

        Anyhow thanks!

        • This should work though, Martin. It puzzles me that it doesn’t work for you. Would it be okay for you to share a screenshot of your result_package_4? It will help others who read this blog as well.

          Do you not see the langu, textsh etc. fields in there?

           

          • Well, that’s good. But it’s strange you have texts in result_package_2. May I ask what version of BW you are working on? Because I tested on 3 different systems and all had texts in result_package_4.

  • Hi,

     

    Im not a great abapper so would appreciate you help. I need something like this but for 5 levels of attributes that appear in the infoobject.

     

    So I guess…

     

    Create the top text nodes

    Create more text nodes with respect to parents

    again as above

    again as above

    again as above

    then the infoobject characteristic values, as always, with respect to parents!

     

     

    how does the abap change to accommodate for this… you mention T_LEVELS but to be honest, this abap is over my pay grade. Can you give me any hints?

    • Iksit, the basis of increasing hierarchy levels is to increment the T_LEVELS as stated in the blog. But it isn’t only restricted to that. There are some obvious steps attached to it.

      To get the result similar to shown in the screenshot below, try to understand the sample code that follows. It’s fairly simple.

      In the code below, Please try to understand the usage of first_chilld, second_child, and final_child. You just have to replace them with your respective InfoObjects.

                " TLevel = 2          
                READ TABLE RESULT_PACKAGE_3 INTO RESULT_FIELDS_3
                WITH KEY h_hiernode = <source_fields>-first_child.
                IF sy-subrc <> 0.            
                  READ TABLE lt_existing_parents ASSIGNING
                  FIELD-SYMBOL(<ep1>)
                  WITH KEY hieid = lv_hieid_hier
                           nodename = <source_fields>-first_child
                  BINARY SEARCH.
                  IF sy-subrc = 0.
                    RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
                    objectid = lv_hieid_hier
                    h_nodeid = <ep1>-nodeid
                    h_iobjnm = lc_hier_node
                    h_hiernode = <source_fields>-first_child
                    h_parentid = lv_prnt_id "IMP!
                    h_tlevel = 02 "Always 02
                    )  ).
                  ELSE.         
                    RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
                    objectid = lv_hieid_hier
                    h_nodeid = lv_max_nodeid + lv_index
                    h_iobjnm = lc_hier_node
                    h_hiernode = <source_fields>-first_child
                    h_parentid = lv_prnt_id
                    h_tlevel = 02 "Always 02
                    )  ).
                  ENDIF.
                  lv_prnt_id = lv_max_nodeid + lv_index.
                  increment lv_index.
                ELSE.
                  lv_prnt_id = RESULT_FIELDS_3-h_nodeid.
                ENDIF.
      
                " TLevel = 3
                READ TABLE RESULT_PACKAGE_3 INTO RESULT_FIELDS_3
                WITH KEY h_hiernode = <source_fields>-second_child.
                IF sy-subrc <> 0.
                  READ TABLE lt_existing_parents ASSIGNING
                  FIELD-SYMBOL(<ep2>)
                  WITH KEY hieid = lv_hieid_hier
                           nodename = <source_fields>-second_child
                  BINARY SEARCH.
                  IF sy-subrc = 0.
                    RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
                    objectid = lv_hieid_hier
                    h_nodeid = <ep2>-nodeid
                    h_iobjnm = lc_hier_node
                    h_hiernode = <source_fields>-second_child
                    h_parentid = lv_prnt_id "IMP!
                    h_tlevel = 03 "Always 03
                    )  ).
                  ELSE.
                    " New gl_account. Add to result_package_3.
                    RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
                    objectid = lv_hieid_hier
                    h_nodeid = lv_max_nodeid + lv_index
                    h_iobjnm = lc_hier_node
                    h_hiernode = <source_fields>-second_child
                    h_parentid = lv_prnt_id
                    h_tlevel = 03 "Always 03
                    )  ).
                  ENDIF.
                  lv_prnt_id = lv_max_nodeid + lv_index.
                  increment lv_index.
                ELSE.
                  lv_prnt_id = RESULT_FIELDS_3-h_nodeid.
                ENDIF.
      
                " TLevel = 4
                READ TABLE lt_existing_parents ASSIGNING
                FIELD-SYMBOL(<ep3>)
                WITH KEY hieid = lv_hieid_hier
                         nodename = <source_fields>-final_child
                BINARY SEARCH.
                IF sy-subrc = 0.
                  RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
                  objectid = lv_hieid_hier
                  h_nodeid = <ep3>-nodeid
                  h_iobjnm = 'final_child'
                  final_child = <source_fields>-final_child
                  h_parentid = lv_prnt_id "IMP!
                  h_tlevel = 04 "Always 04
                  )  ).
                ELSE.
                  RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
                  objectid = lv_hieid_hier
                  h_nodeid = lv_max_nodeid + lv_index
                  h_iobjnm = 'final_child'
                  final_child = <source_fields>-final_child
                  h_parentid = lv_prnt_id
                  h_tlevel = 04 "Always 04
                  )  ).
                ENDIF.

      I don’t have any time to update the blog right now, so have given an example code here. Later, I’ll update the blog with more complex scenarios.

      /
  • Hi Sagar,

    Thanks for sharing. We’re facing unexpectable issue with this method. While creating HIER transformation from ATTR of the same infoobject the system doesn’t popup the screen of chose whether we want to create an ABAP expert routine or AMDP script and creates AMDP by default. Have you faced this problem anyhow? All transformations to ADSO have the option to chose. We’re on 7.5sp16 on HANA.

    Thanks,

    Pavel

    • That’s a strange problem, Pavel, I must say. I’ve always had the popup come up with the option to choose ABAP or to create an AMDP. Not sure what went awry. Try asking this as a question on answers.sap.com.

       

    • Hi Pavel,

       

      if it is still relevant: We had the same problem on another issue.

      If you used AMDP scripts before in this trasnsformation and deleted them to switch to ABAP, it is possible, that the routine is not deleted correctly, and lurks invisibly in the transformation. With CL_RSTRAN_STAT->DELTE_RULE_FROM_DB these invisible routines can be deleted.

  • Hi Sagar,

    First of all appreciate for the great blog.I too facing the same issue. I have a cost center and SITE is an attribute for the Cost Center.I followed the same process.

    I am not a great ABAPer But reading the table RSHIEDIR i didnt find an entry for SITE.Could you please help me on this.

    Regards,

    Pamarthy.

     

    • Pamarthy,

      Thanks for your appreciation. You don’t need an entry in the table RSHIEDIR. Firstly, copy the whole code from the blog and paste it into your expert routine. And then, do the following:,

      Change “lc_hier” constant to whatever technical name of hierarchy you want. Example below:

      lc_hier = 'HIER_COST_CENTER'

      Now, change “lc_customer” to “lc_cost_center” and change its value as well. Example below:

      lc_cost_center  TYPE rsiobjnm   VALUE '0COSTCENTER'

      Now, just do some find and replace (ctrl + H in windows).

      • Throughout the code, replace lc_customer with lc_cost_center.
      • Throughout the code, replace /bic/zccst_grp with SITE. “SITE” for standard IO and “/BIC/ZSITE” for custom. (Assuming ZSITE is the technical name of custom IO.)

      This should be it. Try this and let me know if you get any errors.

        • Hi Sagar,

          I am getting the error with source fields does not have component called /BIC.Could you please look into the code and suggest me if I am in right track. I am not an ABAPer.I am very thankful to you

           

          • Kindly edit your comment and remove all the code. Add only these things:

            • Screenshot of error
            • Technical name of SITE Infoobject
            • Technical name of CostCenter infoobject.

            This error is related to incorrect naming.

            Remember the naming convention: “/bic/“zinfoobject for custom IO and “infoobject” for standard.

            Example for ZCOSTCENTER, use /BIC/ZCOSTCENTER. For 0COSTCENTER, use COSTCENTER (without the 0).

          • Hi Sagar,

            Thanks for the reply. Now I found there were no syntax errors. But one problem I am facing is I loaded the data and didn’t find any Hierarchy for SITE in Cost center. Appreciate your comments.

             

          • Hi Sagar,

            Good Morning. The code is working now and I ran the dtp.I have a small doubt. My code is

             CONSTANTSlc_hier      TYPE rshienm    VALUE 'HIER_COST_CENTER',
                             lc_act       TYPE rsobjvers  VALUE 'A',
                             lc_hier_node TYPE rsnodename VALUE '0HIER_NODE',
                             lc_cost_center TYPE rsiobjnm   VALUE 'COCCOSCTR',
                             lc_en        TYPE LENGTH VALUE 'EN'.
            what is the first select will do.
            SELECT SINGLE hieid
                    FROM rshiedir
                    INTO @DATA(lv_hieid_hier_site_grp)
                    WHERE hienm @lc_hier.
            Do I need to declare my LC_Hier as the existing cost center Hierarchy name? When I debug I am not getting any value into LV_HIEID_HIER_SITE_GRP.

            Regards,

            Neel.

          • Output of the first select is used in third select to check if the hierarchy already exists. If it does, we’ll update the hierarchy later on with the changes.

            This handles the delta changes. For ex, if a cost center is moved from one site to another, lv_hieid_hier_site_grp is going to be used for handling it.

          • Hi Sagar,

            Thanks for your kind support and very nice of your explanation. I tried loading the data but getting errors. attached is the screenshot of my debug reference and the error that I am getting while updating the Hierarchy. Once again thanks a lot for all you done to me.

             

          • I see you are using time dependent master data. That’s where the problem is. My bad, should’ve mentioned the code I used is for time-independent only.

            For your case, do the following:

            • In Infoobject’s Hierarchy tab, select the Time-Dependent radio button as shown below.

            radio

            • Wherever result_package_3 is used, append the following lines:
            datefrom = <source_fields>-datefrom
            dateto = <source_fields>-dateto

            Example:

            RESULT_PACKAGE_3 = VALUE #( BASE RESULT_PACKAGE_3 (
            objectid = lv_hieid_hier
            h_nodeid = <ep2>-nodeid
            h_iobjnm = lc_hier_node
            h_hiernode = <source_fields>-second_child
            " Capture Time Dependency by using dateto and datefrom
            datefrom = <source_fields>-datefrom
            dateto = <source_fields>-dateto
            h_parentid = lv_prnt_id "IMP!
            h_tlevel = 03 "Always 03

            Try and let me know if it works.

            /
            radio
          • Hi Sagar,

            Sorry for delay in my reply.Today I am off. Thanks for the advice and I think I need to do some analysis on the property change and also look at the permissions from the concern teams. I will let you know once I can change the hierarchy property. just to inform you that I will remove the link.

            Once again thanks for your kind help.

             

             

          • Hi Sagar,

            Sorry  for delay. Today I am off. I wrote a mail to concern team to change the property.I will update you once I got the response.

            Just to inform you that I will remove the link. Thanks and really thankful to you for your extended help.

            Regards,

            Neel.

  • Hello Sagar,

     

    Thank you for the post, it has made creating hierarchy much simpler.
    However I wanted to know, if we want to load more than one hierarchy, what changes should we make in the code.
    Both the hierarchies will be created using the same code.

     

    Thanks

    Prasanna.

    • Prasanna,

      More than one hierarchies will be created using the same code. Yes. Unfortunately, you’ll need to completely understand how the code works for it. Once you do, it’s just a matter of doing the same stuff again for the second hierarchy and again for the third and so on.

      In short changes would be:

      • Select queries – where ever the hierarchy’s tech name is used – should be changed.
      • Similarly, all the result packages – result_package_1, _3, & _4 would need to be appended for the additional hierarchy.
      • Max_node_id must be handled for every hierarchy that you add to the solution.

      In other words, it’s like doing the same thing over and over again for every additional hierarchy. You can create a class and have different methods for different hierarchies in it. All of them doing the same thing by having different loops over source_package for every hierarchy. This would keep the code much cleaner. But will degrade the performance ever so slightly. The performance hit should be negligible though and I’d prefer it to have a cleaner code. Doing it inside the same loop is also possible but can get a bit complex to understand.

      But again, understanding the code and the hierarchy concepts is crucial to replicate it.