You are on page 1of 17

ALV Tree using nested loops

By Yayati Ekbote, PRIMUS Techsystems

Summary

The aim of this article is to show how to create hierarchies using nested loops. In any scenario where the data
needs to be shown in hierarchical manner, we can use nested loops to create the hierarchies. This article also
contains demonstration for editable tree item using a pop-up screen.

Introduction

I have considered a basic case where we can see number of line items under a sales order and number of
sales order under type of sales order. So a hierarchy is created as follows

I have used ALV Grid Tree type for the display.

Also I have added some functionality for editable item in tree structure using double click event and pop up
screen.

Pre-requisite: Prepare a table type named ZITEM_TABLE type of structure MTREEITEM.

Sample Code

REPORT zprac_simple_tree.

TABLES: vbak.

CLASS cl_column_tree DEFINITION DEFERRED.

DATA: g_app TYPE REF TO cl_column_tree,


g_cont TYPE REF TO cl_gui_custom_container,

*On screen give custom container name as 'STREE'


g_tree TYPE REF TO cl_gui_column_tree,
tcode TYPE sy-ucomm,
ok_code TYPE sy-ucomm,
event TYPE cntl_simple_event,
t_event TYPE cntl_simple_events,
thhdr TYPE treev_hhdr.
DATA: node_table TYPE treev_ntab,
item_table TYPE zitem_table, "table type of MTREEITM (prepared in SE11)
w_node TYPE treev_node,
w_item TYPE mtreeitm,
g_node_key TYPE tv_nodekey,
g_node TYPE tv_nodekey,
g_item TYPE tv_itmname.

DATA: root TYPE tv_nodekey VALUE 'Root',


colm1 TYPE tv_itmname VALUE 'Column1',
colm2 TYPE tv_itmname VALUE 'Column2'.

TYPES:BEGIN OF st_get,
vbeln TYPE vbak-vbeln,
auart TYPE vbak-auart,
netwr TYPE vbak-netwr,
END OF st_get.

DATA: it_get TYPE STANDARD TABLE OF st_get,


wa_get TYPE st_get.

TYPES:BEGIN OF st_sot,
auart TYPE vbak-auart,

END OF st_sot.

DATA: it_sot TYPE STANDARD TABLE OF st_sot,


wa_sot TYPE st_sot.

TYPES:BEGIN OF st_so,
vbeln TYPE vbak-vbeln,
auart TYPE vbak-auart,
netwr TYPE vbak-netwr,
END OF st_so.

DATA: it_so TYPE STANDARD TABLE OF st_so,


wa_so TYPE st_so.

TYPES:BEGIN OF st_line,
vbeln TYPE vbap-vbeln,
posnr TYPE vbap-posnr,
netwr TYPE vbap-netwr,
END OF st_line.

DATA: it_line TYPE STANDARD TABLE OF st_line,


wa_line TYPE st_line.
*-------------Screen 200 fields----------------------------------------*
DATA: budj TYPE vbak-netwr,
rson TYPE string.

*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* CLASS cl_simple_tree DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_column_tree DEFINITION.
PUBLIC SECTION.
METHODS: handle_node_double_click

FOR EVENT node_double_click OF cl_gui_column_tree


IMPORTING
node_key,
handle_item_double_click

FOR EVENT item_double_click OF cl_gui_column_tree


IMPORTING
node_key
item_name,
handle_expand_no_children

FOR EVENT expand_no_children OF cl_gui_column_tree


IMPORTING
node_key.
ENDCLASS. "cl_simple_tree DEFINITION

*----------------------------------------------------------------------*
* CLASS cl_simple_tree IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*

CLASS cl_column_tree IMPLEMENTATION.


METHOD handle_node_double_click.
g_node = node_key.
ENDMETHOD. "handle_node_double_click

METHOD handle_item_double_click.
g_node = node_key.
g_item = item_name.
IF g_item = colm2.
CALL SCREEN 200 STARTING AT 10 10
ENDING AT 46 15.

IF budj IS NOT INITIAL.


PERFORM update_tree USING budj g_node g_item.
ENDIF.

ENDIF.
ENDMETHOD.

METHOD handle_expand_no_children.

g_node = node_key.
ENDMETHOD. "handle_expand_no_children
ENDCLASS. "cl_simple_tree IMPLEMENTATION

SELECTION-SCREEN: BEGIN OF BLOCK mgrp.


SELECT-OPTIONS: sdtype FOR vbak-auart.
SELECTION-SCREEN: END OF BLOCK mgrp.
START-OF-SELECTION.

CREATE OBJECT g_app.

SELECT * FROM vbak INTO CORRESPONDING FIELDS OF TABLE it_get


WHERE auart IN sdtype.

LOOP AT it_get INTO wa_get.


MOVE-CORRESPONDING wa_get TO wa_sot.
MOVE-CORRESPONDING wa_get TO wa_so.
APPEND wa_sot TO it_sot.
APPEND wa_so TO it_so.
ENDLOOP.

SORT it_sot BY auart.


DELETE ADJACENT DUPLICATES FROM it_sot.

SORT it_so BY vbeln.


DELETE ADJACENT DUPLICATES FROM it_so COMPARING vbeln.

SELECT * FROM vbap INTO CORRESPONDING FIELDS OF TABLE it_line


FOR ALL ENTRIES IN it_so
WHERE vbeln = it_so-vbeln.

SORT it_line BY vbeln.


DELETE ADJACENT DUPLICATES FROM it_line COMPARING ALL FIELDS.
END-OF-SELECTION.

SET SCREEN 100.

*&---------------------------------------------------------------------*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'TMENU'.
* SET TITLEBAR 'xxx'.

IF g_tree IS INITIAL.
PERFORM grow_tree.
ELSE.
IF budj IS NOT INITIAL AND rson IS NOT INITIAL.

CALL METHOD g_tree->delete_all_nodes


EXCEPTIONS
failed =1
cntl_system_error = 2
others =3
.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

CALL METHOD g_tree->add_nodes_and_items


EXPORTING
node_table = node_table
item_table = item_table
item_table_structure_name = 'MTREEITM'
EXCEPTIONS
failed =1
cntl_system_error =2
error_in_tables =3
dp_error =4
table_structure_name_not_found = 5
others =6
.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

ENDIF.
ENDIF.

ENDMODULE. " STATUS_0100 OUTPUT

*&---------------------------------------------------------------------*
*& Module USER_COMMAND_0100 INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*

MODULE user_command_0100 INPUT.


CASE tcode.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
WHEN 'EXIT'.
LEAVE PROGRAM.
ENDCASE.
ENDMODULE. " USER_COMMAND_0100 INPUT

*&---------------------------------------------------------------------*
*& Form GROW_TREE
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*

FORM grow_tree .
CREATE OBJECT g_cont
EXPORTING
container_name = 'STREE'.

thhdr-heading = 'Column1'.
thhdr-width = 30.

CREATE OBJECT g_tree


EXPORTING
* lifetime =
parent = g_cont
* shellstyle =
node_selection_mode = cl_gui_column_tree=>node_sel_mode_single
* hide_selection =
item_selection = 'X'
hierarchy_column_name = colm1
hierarchy_header = thhdr
* no_hierarchy_column =
* name =
EXCEPTIONS
lifetime_error =1
cntl_system_error =2
create_error =3
illegal_node_selection_mode = 4
failed =5
illegal_column_name =6
others =7
.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

event-eventid = cl_gui_column_tree=>eventid_node_double_click.
event-appl_event = 'X'. " process PAI if event occurs
APPEND event TO t_event.

event-eventid = cl_gui_column_tree=>eventid_item_double_click.
event-appl_event = 'X'. " process PAI if event occurs
APPEND event TO t_event.

" expand no children


event-eventid = cl_gui_column_tree=>eventid_expand_no_children.
event-appl_event = 'X'.
APPEND event TO t_event.

CALL METHOD g_tree->set_registered_events


EXPORTING
events = t_event
EXCEPTIONS
cntl_error =1
cntl_system_error =2
illegal_event_combination = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

SET HANDLER g_app->handle_node_double_click FOR g_tree.


SET HANDLER g_app->handle_item_double_click FOR g_tree.
SET HANDLER g_app->handle_expand_no_children FOR g_tree.

CALL METHOD g_tree->add_column


EXPORTING
name = colm2
* hidden =
* disabled =
* alignment =
width = 20
* width_pix =
* header_image =
header_text = 'Column2'
* header_tooltip =
EXCEPTIONS
column_exists =1
illegal_column_name =2
too_many_columns =3
illegal_alignment =4
different_column_types =5
cntl_system_error =6
failed =7
predecessor_column_not_found = 8
others =9
.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

PERFORM build_tree USING node_table item_table.

CALL METHOD g_tree->add_nodes_and_items


EXPORTING
node_table = node_table
item_table = item_table
item_table_structure_name = 'MTREEITM'
EXCEPTIONS
failed =1
cntl_system_error =2
error_in_tables =3
dp_error =4
table_structure_name_not_found = 5
others =6
.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

ENDFORM. " GROW_TREE

FORM build_tree USING node_table TYPE treev_ntab


item_table TYPE zitem_table.
DATA: node TYPE mtreesnode,
item TYPE mtreeitm,
val_to_str TYPE string,
sor TYPE vbap-vbeln,
pos TYPE vbap-posnr,
sopos TYPE string.

node-node_key = root.
CLEAR node-relatship.
CLEAR node-relatkey.
node-isfolder = 'X'.
APPEND node TO node_table.
item-node_key = root.
item-item_name = colm1.
item-class = cl_gui_column_tree=>item_class_text.
item-text = root.
APPEND item TO item_table.

item-node_key = root.
item-item_name = colm2.
item-class = cl_gui_column_tree=>item_class_text.
val_to_str = root.
item-text = val_to_str.
APPEND item TO item_table.

LOOP AT it_sot INTO wa_sot.


node-node_key = wa_sot-auart.
node-relatkey = root.
node-relatship = cl_gui_column_tree=>relat_last_child.
node-isfolder = 'X'.
node-expander = 'X'.
APPEND node TO node_table.

item-node_key = wa_sot-auart.
item-item_name = colm1.
item-class = cl_gui_column_tree=>item_class_text.
val_to_str = wa_sot-auart.
item-text = val_to_str.
APPEND item TO item_table.

item-node_key = wa_sot-auart.
item-item_name = colm2.
item-class = cl_gui_column_tree=>item_class_text.
item-text = 'Net Value'.
APPEND item TO item_table.

LOOP AT it_so INTO wa_so WHERE auart = wa_sot-auart.


node-node_key = wa_so-vbeln.
node-relatkey = wa_sot-auart.
node-relatship = cl_gui_column_tree=>relat_last_child.
node-isfolder = 'X'.
node-expander = 'X'.
APPEND node TO node_table.

item-node_key = wa_so-vbeln.
item-item_name = colm1.
item-class = cl_gui_column_tree=>item_class_text.
val_to_str = wa_so-vbeln.
item-text = val_to_str.
APPEND item TO item_table.

item-node_key = wa_so-vbeln.
item-item_name = colm2.
item-class = cl_gui_column_tree=>item_class_text.
val_to_str = wa_so-netwr.
item-text = val_to_str.
APPEND item TO item_table.

LOOP AT it_line INTO wa_line WHERE vbeln = wa_so-vbeln.


SHIFT wa_line-posnr LEFT DELETING LEADING '0'.
SHIFT wa_line-vbeln LEFT DELETING LEADING '0'.
CONCATENATE wa_line-vbeln wa_line-posnr INTO sopos.
node-node_key = sopos.
node-relatkey = wa_so-vbeln.
node-relatship = cl_gui_column_tree=>relat_last_child.
node-isfolder = ''.
node-expander = ''.
APPEND node TO node_table.

item-node_key = sopos.
item-item_name = colm1.
item-class = cl_gui_column_tree=>item_class_text.
val_to_str = wa_line-posnr.
item-text = val_to_str.
APPEND item TO item_table.

item-node_key = sopos.
item-item_name = colm2.
item-class = cl_gui_column_tree=>item_class_text.
val_to_str = wa_line-netwr.
item-text = val_to_str.
APPEND item TO item_table.
ENDLOOP.

CLEAR wa_so.
ENDLOOP.
CLEAR wa_sot.
ENDLOOP.
ENDFORM.

*&---------------------------------------------------------------------*
*& Module STATUS_0200 OUTPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
module STATUS_0200 output.
SET PF-STATUS 'EDIT'.
* SET TITLEBAR 'xxx'.
CLEAR: budj, rson.
endmodule. " STATUS_0200 OUTPUT

*&---------------------------------------------------------------------*
*& Module USER_COMMAND_0200 INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
module USER_COMMAND_0200 input.
CASE ok_code.
WHEN 'OK'.
IF budj IS NOT INITIAL AND rson IS NOT INITIAL.
LEAVE TO SCREEN 0.
ELSE.
MESSAGE 'Value cannot be nil' TYPE 'E'.
ENDIF.
WHEN 'CANC'.
LEAVE TO SCREEN 0.
ENDCASE.
endmodule. " USER_COMMAND_0200 INPUT

FORM update_tree USING budj g_node g_item.


DATA: key_to_char TYPE string.
LOOP AT item_table INTO w_item WHERE node_key = g_node
AND item_name = g_item.
w_item-node_key = g_node.
w_item-item_name = g_item.
w_item-class = cl_gui_column_tree=>item_class_text.
key_to_char = budj.
w_item-text = key_to_char.
MODIFY item_table FROM w_item.

ENDLOOP.
ENDFORM.
If we enter only one sales order type, for example TA (In my case TA), we get
If we want to see multiple types of sales order types and sales orders in them and there line items
We get
Now if we want to edit the value of some node (In this case I have considered

VBAK-NETWR).

We can do so by adding the code in event response of local class event

method. We get ->

1. Double click on the node whose value we have to change

2. In this example I select ZIC order types sales order 71.


Now I enter new value and reason for it. In this case I have made the reason compulsory for change to happen.
So I want to change the value 10764.00 to change to 20000.00.
Result
The main idea and key point behind creating this hierarchy is keeping the node_key

unique. We can add further levels by adding nested loops inside the loops for example billing plans, dates..etc..
We can add one more column to show the payments against the billing plans in hierarchical manner.

You might also like