Multi level Employee Hierarchy Report in Tree Format (Top- To-Down)

A+ A-

Hi All,

recently i got a scenario to biuld a Multilevel Employee Hierarchy report, i posted it on SCN because i was not getting how could i achieve it through custom program (There are some function modules available for the same purpose e.g. RH_STRUC_GET, but alone it was not fulfilling my requirements). Although it is something like as in standard transaction PPOME, but what i was expecting  is something different from what you can see in PPOME transaction. After posted the query on SCN , i was not able to get a single reply (strange for me , i don't know why). Then i decided to create a Custom Program to show Multilevel Hierarchy Report for Employees, in which you can see all those employee under any level along with its designation , Name, its id, and so on. I have hided the name of Concerned person in this screenshot, and anyone can edit this program to make a good use of Custom Multilevel Hierarchy report.

Although i have searched for the same on SCN, but i got all the answer which was related to the Hierarchy of one person. And it was not my requirement. So, here i am posting this whole code alongwith the screenshot of Output, so that it will benifit all those members or new persons who wants to create a Multilevel Hierarchy Report.

(There may be some correction in this program, which might help in creating a more benificial list, i will appreciate all those suggestions which will come to me to add within my custom code.)

 

Step By Step Process i have implemented in getting this List.

 

 

Let us assume that i have to show all the concerned person under CMD, let us assume that will have many GM, HR head, Purchase Head, Sales Head like persons who are directly reporting to the CMD, again for each department head we will have persons with different positions, and this hierarchy will be from Top - To - Bottom and can be spreaded upto any level. Now the problem is through RH_STRUC_GET we can get all the concerned person details which has a immediate reporting structure.

A user needs to see the hierarchy details at any level, means he could see either starting for a GM , or for a Executive.

 

Checking for initial entry, if a avalid person has been entered or not.

 

AT SELECTION-SCREEN.

 

   IF p_pernr IS NOT INITIAL.

 

    SELECT SINGLE pernr

       FROM pa0001

       INTO lv_pernr

       WHERE pernr EQ p_pernr

       AND   endda EQ '99991231'.

 

     IF sy-subrc IS NOT INITIAL.

       MESSAGE 'Please enter a valid Employee Code'  TYPE 'E'.

     ENDIF.

   ENDIF.

 

 

Now with the use of RH_STRUC_GET i get all the employees that are directly or indirectly reporting to the concerned person for which i need to see the hierarchy, in tables parameters we will have three tables namely

 

it_result_tab   -> which shows the result of all objid which are directly or indirectly related to a concerned person

 

it_result_object -> which shows the designation of all employee with other details

 

it_result_struc   -> contains the level of each employee with other details

 

Now getting all the employees details through RH_STRUC_GET

 

FORM get_data .

 

   CLEAR lv_objid.

   SELECT SINGLE plans

     INTO lv_objid

     FROM pa0001

     WHERE pernr = p_pernr

     AND endda = '99991231'.

 

   CALL FUNCTION 'RH_STRUC_GET'

     EXPORTING

       act_otype      = 'S'

       act_objid      = lv_objid

       act_wegid      = 'B002'

       act_plvar      = '01'

       act_begda      = pm_datuv

       act_endda      = pm_datuv

     TABLES

       result_tab     = it_result_tab

       result_objec   = it_result_objec

       result_struc   = it_result_struc

     EXCEPTIONS

       no_plvar_found = 1

       no_entry_found = 2

       OTHERS         = 3.

 

ENDFORM.  

 

Now as we will have a table it_result_struc having levels of all employee, so getting the related details of employees.

 

FORM preapare_final_table .

 

   LOOP AT  it_result_struc INTO wa_result_struc .

     MOVE-CORRESPONDING wa_result_struc TO it_struct.

 

     SELECT SINGLE pernr

                   ename

                   bukrs

                   werks

                   btrtl

                   persk

                   kostl

       FROM pa0001

       INTO (it_struct-pernr ,

             it_struct-ename,

             it_struct-bukrs,

             it_struct-werks,

             it_struct-btrtl,

             it_struct-persk,

             it_struct-kostl )

       WHERE endda = '99991231'

       AND plans = it_struct-objid.

 

 

 

     SELECT SINGLE ptext

       FROM t503t

       INTO it_struct-ptext

       WHERE persk = it_struct-persk.

 

     SELECT SINGLE btext

       FROM t001p

       INTO it_struct-btext

       WHERE werks = it_struct-werks

         AND btrtl = it_struct-btrtl.

 

 

     SELECT SINGLE ltext

       FROM cskt

       INTO  it_struct-ltext

       WHERE spras  = 'E'

       AND kostl = it_struct-kostl.

 

     SELECT SINGLE plstx

       FROM t528t

       INTO it_struct-plstx

       WHERE sprsl = 'E'

         AND plans = it_struct-objid.

 

     APPEND it_struct.

     CLEAR it_struct.

 

   ENDLOOP.

 

   IF so_bukrs[] IS NOT INITIAL.

     DELETE it_struct WHERE bukrs NOT IN so_bukrs.

   ENDIF.

 

   IF so_werks[] IS NOT INITIAL.

     DELETE it_struct WHERE werks NOT IN so_werks.

   ENDIF.

 

   IF so_btrtl[] IS NOT INITIAL.

     DELETE it_struct WHERE btrtl NOT IN so_btrtl.

  ENDIF.

 

   IF so_persk[] IS NOT INITIAL.

     DELETE it_struct WHERE persk NOT IN so_persk.

  ENDIF.

 

   IF so_kostl[] IS NOT INITIAL.

     DELETE it_struct WHERE kostl NOT IN so_kostl.

  ENDIF.

 

   DELETE it_struct WHERE pernr IS INITIAL.

 

 

  READ TABLE it_struct WITH KEY pernr = p_pernr.

   IF sy-subrc IS NOT INITIAL.

    SELECT SINGLE pernr

                   ename

                   bukrs

                   werks

                   btrtl

                   persk

                   kostl

                   plans

       FROM pa0001

       INTO (it_struct-pernr,

             it_struct-ename,

             it_struct-bukrs,

             it_struct-werks,

             it_struct-btrtl,

             it_struct-persk,

             it_struct-kostl,

             it_struct-objid )

       WHERE endda = '99991231'

         AND plans = lv_objid.

 

     SELECT SINGLE ptext

       FROM t503t

       INTO it_struct-ptext

       WHERE persk = it_struct-persk.

 

     SELECT SINGLE btext

       FROM t001p

       INTO it_struct-btext

       WHERE werks = it_struct-werks

         AND btrtl = it_struct-btrtl.

 

     SELECT SINGLE ltext

       FROM cskt

       INTO  it_struct-ltext

       WHERE spras  = 'E'

       AND kostl = it_struct-kostl.

 

     SELECT SINGLE plstx

       FROM t528t

       INTO it_struct-plstx

       WHERE sprsl = 'E'

         AND plans = it_struct-objid.

 

     it_struct-level = 0.

 

     INSERT it_struct INDEX 1.

 

     DELETE ADJACENT DUPLICATES FROM it_struct COMPARING pernr.

  ENDIF.

 

ENDFORM.                   

 

 

Now we have all the data in our internal table it_struct, including level of each employee , here level refers to the hierarchy level of each employee w.r.t. to higher person for which we want to see the reporting hierarchy.

 

So, we have to go for each level separately and see haow many are reporting them directly, and the same will be checked for each entry.

 

FORM prepare_relationship .

 

 

   LOOP AT it_struct INTO wa_struct.

     lv_index = sy-tabix - 1.

     IF sy-tabix EQ 1.

       MOVE wa_struct-pernr TO ts1_pernr-pernr.

       APPEND ts1_pernr TO gt_pernr.

       CONTINUE.

     ELSE.

       PERFORM get_heir USING  wa_struct

                        CHANGING lv_index

                          gt_pernr.

    ENDIF.

   ENDLOOP.


LOOP AT gt_pernr INTO wa_person.

     CLEAR lv_counter.

     lv_index1 = sy-tabix + 1 .

     LOOP AT gt_pernr INTO wa_person1 FROM lv_index1.

       IF wa_person1-level GT wa_person-level .

         lv_counter = lv_counter + 1.

       ELSEIF  wa_person1-level EQ wa_person-level .

         EXIT.

       ENDIF.

     ENDLOOP.

     MOVE wa_person-pernr TO gt_pernr3-pernr.

 

     IF lv_counter IS INITIAL.

       lv_counter 1.

    ENDIF.

 

     MOVE  lv_counter TO gt_pernr3-count.

     APPEND gt_pernr3.

   ENDLOOP.

 

 

   gt_pernr2[] = gt_pernr[].

 

   SORT gt_pernr2 BY f_pernr.

   LOOP AT gt_pernr2.

     MOVE gt_pernr2-f_pernr TO it_pernr-pernr.

     MOVE 1 TO it_pernr-count.

     COLLECT it_pernr.

   ENDLOOP.

 

ENDFORM.   

 

 

FORM get_heir   USING    wa_struct  TYPE ty_pernr

                CHANGING lv_index  TYPE sy-tabix

                         gt_pernr    TYPE tt_bom.

 

   READ TABLE it_struct INTO wa_struct1 INDEX lv_index.

 

   IF sy-subrc IS INITIAL.

     IF wa_struct-level > wa_struct1-level.

       MOVE: wa_struct-pernr TO ts1_pernr-pernr,

             wa_struct1-pernr TO ts1_pernr-f_pernr,

             wa_struct-level TO ts1_pernr-level.

       APPEND  ts1_pernr TO gt_pernr.

    ELSE.

 

       IF lv_index > 1.

         lv_index = sy-tabix - 1.

         PERFORM get_heir USING  wa_struct

                         CHANGING lv_index

                                  gt_pernr .

       ELSE.

         MOVE: wa_struct-pernr TO ts1_pernr-pernr,

               wa_struct1-pernr TO ts1_pernr-f_pernr,

               wa_struct-level TO ts1_pernr-level.

         APPEND  ts1_pernr TO gt_pernr.

       ENDIF.

     ENDIF.

   ENDIF.

ENDFORM.        

 

 

To create the ALV Tree, we have to create a method, below code has been created for displaying the ALV Tree.

 

FORM display_alv_tree .

 

   LOOP AT gt_pernr ASSIGNING <fs_pernr>.

 

 

     READ TABLE it_struct INTO wa_struct

     WITH KEY pernr = <fs_pernr>-pernr.

 

 

 

     IF <fs_pernr>-f_pernr = ''.

 

       READ TABLE gt_pernr3 WITH KEY pernr = wa_struct-pernr.

       IF sy-subrc IS INITIAL.

         MOVE gt_pernr3-count TO lv_str.

         CONCATENATE wa_struct-ptext '( count' lv_str ')'INTO  l_node_text SEPARATED BY space.

       ELSE.

         l_node_text wa_struct-ename.

       ENDIF.

 

       READ TABLE it_pernr WITH KEY pernr = wa_struct-pernr.

       IF sy-subrc  IS INITIAL.

         MOVE it_pernr-count TO wa_struct-count.

       ELSE.

         MOVE 1 TO wa_struct-count.

       ENDIF.

 

       CLEAR l_node_key.

 

       CALL METHOD g_alv_tree->add_node

         EXPORTING

           i_relat_node_key = l_node_key

           i_relationship   = cl_gui_column_tree=>relat_last_child

           i_node_text      = l_node_text

           is_outtab_line   = wa_struct

         IMPORTING

           e_new_node_key   = l_node_key.

 

     ELSE.

 

       READ TABLE gt_pernr INTO w_pernr

       WITH KEY pernr = <fs_pernr>-f_pernr.

 

       READ TABLE gt_pernr3 WITH KEY pernr = wa_struct-pernr.

       IF sy-subrc IS INITIAL.

         MOVE gt_pernr3-count TO lv_str.

         CONCATENATE wa_struct-ptext '( count' lv_str ')'INTO  l_node_text SEPARATED BY space.

       ELSE.

         l_node_text wa_struct-ename.

       ENDIF.

 

       READ TABLE it_pernr WITH KEY pernr = wa_struct-pernr.

       IF sy-subrc  IS INITIAL.

         MOVE it_pernr-count TO wa_struct-count.

       ELSE.

         MOVE 1 TO wa_struct-count.

       ENDIF.

 

       lv_key =   w_pernr-key.

 

       CALL METHOD g_alv_tree->add_node

         EXPORTING

           i_relat_node_key = lv_key

           i_relationship   = cl_gui_column_tree=>relat_last_child

           i_node_text      = l_node_text

           is_outtab_line   = wa_struct

         IMPORTING

           e_new_node_key   = l_node_key.

    ENDIF.

 

 

     <fs_pernr>-key = l_node_key.

     lv_key = <fs_pernr>-key.

 

  ENDLOOP.

 

ENDFORM.                    " DISPLAY_ALV_

 

 

MODULE status_0100 OUTPUT.

   SET PF-STATUS 'MAIN11'.

   SET TITLEBAR 'MAINTITLE1'.

   IF g_alv_tree IS INITIAL.

     PERFORM init_tree.

 

     CALL METHOD cl_gui_cfw=>flush

       EXCEPTIONS

         cntl_system_error = 1

         cntl_error        = 2.

     IF sy-subrc NE 0.

       CALL FUNCTION 'POPUP_TO_INFORM'

         EXPORTING

           titel = 'Automation Queue failure'(801)

           txt1  = 'Internal error:'(802)

           txt2  = 'A method in the automation queue'(803)

           txt3  = 'caused a failure.'(804).

     ENDIF.

   ENDIF.

ENDMODULE.  



Now creating the container for holding the node containing the details


FORM init_tree .

   DATA: l_tree_container_name(30) TYPE c.

 

   l_tree_container_name = 'CCONTAINER1'.

 

   CREATE OBJECT g_custom_container

     EXPORTING

       container_name              = l_tree_container_name

     EXCEPTIONS

       cntl_error                  = 1

       cntl_system_error           = 2

       create_error                = 3

       lifetime_error              = 4

       lifetime_dynpro_dynpro_link = 5.

   IF sy-subrc <> 0.

     MESSAGE x208(00) WITH 'ERROR'(100).

   ENDIF.

 

* create tree control

   CREATE OBJECT g_alv_tree

     EXPORTING

       parent                      = g_custom_container

       node_selection_mode         = cl_gui_column_tree=>node_sel_mode_single

       item_selection              =