CL_SALV_TREE¶
Hierarchical ALV tree — displays parent-child data as an expandable tree grid.
Purpose¶
CL_SALV_TREE extends the SALV framework to display data with a tree structure — useful for bill of materials, org charts, hierarchical order data, or any parent-child relationship.
More complex than CL_SALV_TABLE
CL_SALV_TREE requires a specific node table structure and more setup than the flat grid. For simple flat data, use CL_SALV_TABLE instead.
Requires a screen and container — not a simple report
Unlike CL_SALV_TABLE (which displays in a report output), CL_SALV_TREE requires a CL_GUI_CUSTOM_CONTAINER on a screen. You must create a module pool with a screen that has a custom control area. See the working example below.
Required table structure¶
The table passed to factory is empty — it only defines the column structure. The tree framework manages node keys and hierarchy internally. Add nodes after the factory call using get_nodes( )->add_node( ).
TYPES: BEGIN OF ty_node,
descr TYPE string,
qty TYPE i,
END OF ty_node.
DATA lt_nodes TYPE STANDARD TABLE OF ty_node. " empty — defines columns only
DATA lo_tree TYPE REF TO cl_salv_tree.
Minimum working example (module pool)¶
Setup (SE80):
1. Create module pool ZSALV_TREE_DEMO
2. Create screen 100 with a Custom Control named CC_TREE
3. Add the code below to the respective includes
Global data (top include):
DATA: go_container TYPE REF TO cl_gui_custom_container,
go_tree TYPE REF TO cl_salv_tree.
TYPES: BEGIN OF ty_node,
descr TYPE string,
qty TYPE i,
END OF ty_node.
DATA lt_nodes TYPE STANDARD TABLE OF ty_node. " empty — defines columns only
START-OF-SELECTION:
PBO module:
You must create the PF-status manually — use a Z/Y name
SET PF-STATUS 'ZMAIN' references a local GUI status in your module pool. The easiest way to create it is to copy the SAP standard: open SE41, enter program SAPLSALV and status STANDARD, then Status → Copy and set your program and ZMAIN as the target. If SAPLSALV is not available try SAPLKKBL. The PF-status only provides navigation keys — custom actions go through events, not the PF-status.
MODULE pbo_100 OUTPUT.
SET PF-STATUS 'ZMAIN'.
IF go_container IS INITIAL.
CREATE OBJECT go_container
EXPORTING container_name = 'CC_TREE'.
TRY.
" Pass empty table — it defines the columns, not the data
cl_salv_tree=>factory(
EXPORTING
r_container = go_container
IMPORTING
r_salv_tree = go_tree
CHANGING
t_table = lt_nodes ).
" Build hierarchy using add_node
" Relationship constants live on CL_GUI_COLUMN_TREE (RELAT_LAST_CHILD = 6)
DATA lo_nodes TYPE REF TO cl_salv_nodes.
DATA ls_data TYPE ty_node.
DATA lv_root_key TYPE salv_de_node_key. " initial = no parent (root)
DATA lv_comp_key TYPE salv_de_node_key.
lo_nodes = go_tree->get_nodes( ).
" Add root node — related_node is initial (no parent)
ls_data-descr = 'Root Order'. ls_data-qty = 0.
DATA(lo_root) = lo_nodes->add_node(
related_node = lv_root_key
relationship = cl_gui_column_tree=>relat_last_child
text = 'Root Order'
data_row = ls_data ).
lv_root_key = lo_root->get_key( ).
" Add children under root
ls_data-descr = 'Component A'. ls_data-qty = 10.
DATA(lo_comp_a) = lo_nodes->add_node(
related_node = lv_root_key
relationship = cl_gui_column_tree=>relat_last_child
text = 'Component A'
data_row = ls_data ).
ls_data-descr = 'Component B'. ls_data-qty = 5.
lo_nodes->add_node(
related_node = lv_root_key
relationship = cl_gui_column_tree=>relat_last_child
text = 'Component B'
data_row = ls_data ).
" Add grandchild under Component A
lv_comp_key = lo_comp_a->get_key( ).
ls_data-descr = 'Sub-part A1'. ls_data-qty = 100.
lo_nodes->add_node(
related_node = lv_comp_key
relationship = cl_gui_column_tree=>relat_last_child
text = 'Sub-part A1'
data_row = ls_data ).
go_tree->get_columns( )->set_optimize( abap_true ).
go_tree->get_nodes( )->expand_all( ).
go_tree->display( ).
CATCH cx_salv_error INTO DATA(lx).
MESSAGE lx->get_text( ) TYPE 'E'.
ENDTRY.
ENDIF.
ENDMODULE.
PAI module:
MODULE pai_100 INPUT.
CASE sy-ucomm.
WHEN '&F03' OR '&F15' OR '&F12'. " Back / Exit / Cancel
LEAVE TO SCREEN 0.
ENDCASE.
ENDMODULE.
Working with nodes¶
Expand / Collapse — standard toolbar buttons¶
CL_SALV_TREE has no events, so there is no event handler pattern like CL_GUI_ALV_GRID. Expand/collapse buttons are provided by the built-in standard toolbar — enable them with get_functions( )->set_all( abap_true ) in PBO after the factory call:
go_tree->get_functions( )->set_all( abap_true ).
go_tree->get_nodes( )->expand_all( ).
go_tree->display( ).
Custom node properties — set at build time in PBO¶
Node text and icons must be set before go_tree->display( ) is called — changes made after the initial display from PAI will not be visible. Set them in PBO immediately after add_node:
" Add root node
ls_data-descr = 'Root Order'. ls_data-qty = 0.
DATA(lo_root) = lo_nodes->add_node(
related_node = lv_root_key
relationship = cl_gui_column_tree=>relat_last_child
text = 'Root Order'
data_row = ls_data ).
" Set icons on the node — SALV_DE_TREE_IMAGE is CHAR 46,
" assign icon constant to a typed variable before passing
DATA lv_icon TYPE salv_de_tree_image.
lv_icon = icon_folder.
lo_root->set_collapsed_icon( lv_icon ).
lv_icon = icon_open_folder.
lo_root->set_expanded_icon( lv_icon ).
lv_root_key = lo_root->get_key( ).
PAI module — only navigation:
MODULE pai_100 INPUT.
CASE sy-ucomm.
WHEN '&F03' OR '&F15' OR '&F12'. " Back / Exit / Cancel
LEAVE TO SCREEN 0.
ENDCASE.
ENDMODULE.
Column configuration¶
DATA(lo_columns) = go_tree->get_columns( ).
lo_columns->set_optimize( abap_true ).
" Rename a column header
DATA(lo_col) = go_tree->get_columns( )->get_column( 'DESCR' ).
lo_col->set_long_text( 'Description' ).
lo_col->set_medium_text( 'Descr.' ).
" Hide a column
DATA(lo_qty_col) = go_tree->get_columns( )->get_column( 'QTY' ).
lo_qty_col->set_visible( abap_false ).
See also¶
CL_SALV_TABLE— simpler flat gridCL_SALV_FUNCTIONS_LIST— toolbar button configuration