6

I spotted some very strange behavior using hierarchical SALV (class CL_SALV_TREE).

If I use the set_data_row method directly after creating the node instance then I receive the correct hierarchy.

REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      main
        RAISING cx_salv_msg cx_salv_error.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD main.
    DATA: lt_data TYPE STANDARD TABLE OF t000.
    cl_salv_tree=>factory(
      IMPORTING
        r_salv_tree = DATA(lo_salv_tree)
      CHANGING
        t_table = lt_data
    ).

    DATA(lo_tree_settings) = lo_salv_tree->get_tree_settings( ).
    lo_tree_settings->set_hierarchy_header( `Hierarchy` ).
    lo_tree_settings->set_hierarchy_size( 30 ).

    DATA(lo_nodes) = lo_salv_tree->get_nodes( ).
    DATA(lo_root_node) = lo_nodes->add_node(
      related_node = space
      relationship = if_salv_c_node_relation=>last_child
      data_row = VALUE t000( mandt = '100' )
      collapsed_icon = '@3S\QStatus: Collapsed@'
      expanded_icon = '@3T\QStatus: Expanded@'
      row_style = if_salv_c_tree_style=>emphasized_positive
      text = '100'
    ).
    lo_root_node->set_data_row( VALUE t000( mandt = '100' ) ).
    lo_root_node->get_hierarchy_item( )->set_icon( '@0V\QOK@' ).

    DATA(lo_node1) = lo_nodes->add_node(
      related_node = lo_root_node->get_key( )
      relationship = cl_gui_column_tree=>relat_last_child
      text = '200'
    ).
    lo_node1->set_data_row( VALUE t000( mandt = '200' ) ).
    DATA(lo_node2) = lo_nodes->add_node(
      related_node = lo_node1->get_key( )
      relationship = cl_gui_column_tree=>relat_last_child
      text = '300'
    ).
    lo_node2->set_data_row( VALUE t000( mandt = '300' ) ).

    DATA(lo_node3) = lo_nodes->add_node(
      related_node = lo_node2->get_key( )
      relationship = cl_gui_column_tree=>relat_last_child
      text = '400'
    ).
    lo_node3->set_data_row( VALUE t000( mandt = '400' ) ).

    lo_salv_tree->display( ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  TRY .
    lcl_main=>main( ).
  CATCH cx_salv_msg cx_salv_error.
    ASSERT 0 = 1.
  ENDTRY.

Correct hierarchy

However if I use set_data_row method at the end of my main method, then the result is totally unexpected.

REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      main
        RAISING cx_salv_msg cx_salv_error.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD main.
    DATA: lt_data TYPE STANDARD TABLE OF t000.
    cl_salv_tree=>factory(
      IMPORTING
        r_salv_tree = DATA(lo_salv_tree)
      CHANGING
        t_table = lt_data
    ).

    DATA(lo_tree_settings) = lo_salv_tree->get_tree_settings( ).
    lo_tree_settings->set_hierarchy_header( `Hierarchy` ).
    lo_tree_settings->set_hierarchy_size( 30 ).

    DATA(lo_nodes) = lo_salv_tree->get_nodes( ).
    DATA(lo_root_node) = lo_nodes->add_node(
      related_node = space
      relationship = if_salv_c_node_relation=>last_child
      data_row = VALUE t000( mandt = '100' )
      collapsed_icon = '@3S\QStatus: Collapsed@'
      expanded_icon = '@3T\QStatus: Expanded@'
      row_style = if_salv_c_tree_style=>emphasized_positive
      text = '100'
    ).
    lo_root_node->get_hierarchy_item( )->set_icon( '@0V\QOK@' ).

    DATA(lo_node1) = lo_nodes->add_node(
      related_node = lo_root_node->get_key( )
      relationship = cl_gui_column_tree=>relat_last_child
      text = '200'
    ).

    DATA(lo_node2) = lo_nodes->add_node(
      related_node = lo_node1->get_key( )
      relationship = cl_gui_column_tree=>relat_last_child
      text = '300'
    ).

    DATA(lo_node3) = lo_nodes->add_node(
      related_node = lo_node2->get_key( )
      relationship = cl_gui_column_tree=>relat_last_child
      text = '400'
    ).

    lo_root_node->set_data_row( VALUE t000( mandt = '100' ) ).
    lo_node1->set_data_row( VALUE t000( mandt = '200' ) ).
    lo_node2->set_data_row( VALUE t000( mandt = '300' ) ).
    lo_node3->set_data_row( VALUE t000( mandt = '400' ) ).

    lo_salv_tree->display( ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  TRY .
    lcl_main=>main( ).
  CATCH cx_salv_msg cx_salv_error.
    ASSERT 0 = 1.
  ENDTRY.

Incorrect hierarchy

Is this a bug in this component? I could not find any documentation that would explain this strange behavior.

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
Jagger
  • 10,350
  • 9
  • 51
  • 93

1 Answers1

4

By calling set_data_row method you overwrite all raw data, including child relations.

In the first example you always set mandt first, and add node later on. If you would do it the other way around, you would also get 'one level deep' tree.

verdevelli
  • 56
  • 4
  • Agreed. The [note 775100 - ALV OM Tree: Performance when creating nodes](https://launchpad.support.sap.com/#/notes/775100) discourages the use of `SET_DATA_ROW`: "To improve performance, the node must be created entirely using the method CL_SALV_NODES->ADD_NODE, that is, after the call of the method no setter methods of the class CL_SALV_NODE or the class CL_SALV_ITEM, in particular the data should be set in ADD_NODE using the parameter DATA_ROW and not using the additional call of the method CL_SALV_NODE->SET_DATA_ROW." So, better use `add_node( ... data_row = VALUE t000( mandt = '100' ) )`! – Sandra Rossi Jul 20 '19 at 19:15
  • Well, what if you do not know the data at the time of adding the node? The example in the question is actually some simplified version. I have run into this issue while building the tree parallel to calculate some values recursively. The tree was built top-down and the values were summed up bottom-up, so the actual sum to be added to the node was not yet known at the time of adding the node. – Jagger Jul 21 '19 at 18:07