
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 = 'X'
no_html_header = 'X'
no_toolbar = ''
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
illegal_node_selection_mode = 5
failed = 6
illegal_column_name = 7.
IF sy-subrc <> 0.
MESSAGE x208(00) WITH 'ERROR'. "#EC NOTEXT
ENDIF.
DATA l_hierarchy_header TYPE treev_hhdr.
PERFORM build_hierarchy_header CHANGING l_hierarchy_header.
CALL METHOD g_alv_tree->set_table_for_first_display
EXPORTING
i_structure_name = 'ZHR_EMP'
is_hierarchy_header = l_hierarchy_header
CHANGING
it_outtab = gt_pernr1. "table must be empty !
PERFORM get_data.
PERFORM preapare_final_table.
PERFORM prepare_relationship.
PERFORM display_alv_tree.
CALL METHOD g_alv_tree->frontend_update.
ENDFORM.
When you will execute the report , you will get a result like this
On opening its successive nodes, you will get the various level of hierarchy.
PS.: Editing still is in Process.
In the above screenshot i have shown that how many peoples are there under each level, The Source Code can be optimised for any data related to this Hierarchy (Means you can add your needy data to show here.).
Regards
Sanjeev kumar.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
3 | |
2 | |
2 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |