Skip to Content

CL_SALV_TREE is a very useful class to print information on the output screen in the form of a tree.

We can view similar kind of information grouped under nodes and can have option to have limited or full access to them.

The tabular view enables us to navigate through the data in an informative kind of way.

In this blog, we shall discuss about many small useful events for the CL_SALV_TREE and also some tricks to use them for our own desired functionalities such as Sorting, Filtering and Deleting and most importantly, REFRESH.

We would try to populate the data dynamically on to the CL_SALV_TREE which makes it more interesting!

Here we shall use our program to generate a tree which can be used as a directory explorer similar to that of AL11 transaction.

 

 

Looks impressive, doesn’t it?

Well, its very simple.

I have used two main function modules to fetch the directory and file data :

 

You need to filter the directories from the files and I have used my own made logic for that.

Now, for the initial display, we need to display an empty table of the same type of the table that we want to have in the output.

Now, we need to add the parent node, which is the root directory( p_file )

    lo_nodes  = go_tree->get_nodes( ).
    lv_text = CONV #( p_file ).
    TRY.
*--- Add the root node
        lo_node = lo_nodes->add_node(
                       related_node   = ' '
                       relationship   = cl_salv_nodes=>if_salv_c_node_relation~parent
                       text           =  lv_text
                       visible        = abap_true
                       expander       = abap_true
                       folder         = abap_true ).

      CATCH cx_salv_msg.    "
        MESSAGE s001(icl) WITH lv_text.
    ENDTRY.

 

Now, we will set the screen PF STATUS

*--- Set PF status Adding all the functions required
    go_tree->set_screen_status(
      EXPORTING
        report        = sy-repid    " ABAP Program: Current Master Program
        pfstatus      = 'PF_STATUS'    " Screens, Current GUI Status
        set_functions = go_tree->c_functions_all    " ALV: Data Element for Constants
    ).

 

Now comes the interesting part of dynamically populating the data on to the SALV Tree Structure.

We would use an OOPS approach to the program for the functionality and use several events for the same.

 

Now we would assign each method for event handling on the SALV_TREE.

Now we would trigger the empty expand node event so as to populate the data under the node.

    TRY.

        lo_nodes =  go_tree->get_nodes( ).
        lo_node = lo_nodes->get_node( node_key = node_key ).
      CATCH cx_salv_msg.
        FREE : lo_nodes,lo_node.
    ENDTRY.

    ls_datarow = lo_node->get_data_row( ).

    ASSIGN ls_datarow->* TO <lfs_rowdata>.
*--- If the root node is clicked then the address comes from the parameters
    IF <lfs_rowdata>-address IS NOT INITIAL.
      lv_file = <lfs_rowdata>-address.
    ELSE.
      lv_file = p_file.
    ENDIF.


    me->md_directory_open( iv_file = lv_file ).


    me->md_create_node( iv_key = node_key ).

 

The directory open method contains the two methods to populate the data in the internal table.

Now we will populate the nodes dynamically using the create node method.

 

*--- Create the sub nodes after expansion
    LOOP AT lt_main INTO ls_main.
*--- Differentiate the files from the folders
      IF ls_main-filtyp = TEXT-003.

        lv_text = ls_main-name.
        TRY.
            lo_node = lo_nodes->add_node(

            related_node   = lv_key
            relationship   = cl_gui_column_tree=>relat_last_child
            data_row       = ls_main
            text           =  lv_text
            visible        = abap_true
            expander       = 'X'
            folder         = 'X'  ).
          CATCH cx_salv_msg.  "
            FREE lo_node.
        ENDTRY.

      ELSE.
        lv_text = ls_main-name.
        TRY.
            lo_node = lo_nodes->add_node(
                      related_node   = lv_key
                      relationship   = cl_gui_column_tree=>relat_last_child
                      data_row       = ls_main
                      text           =  lv_text
                      visible        = abap_true
                      expander       = ' '
                      folder         = ' '
                  ).
          CATCH cx_salv_msg.  "
            FREE lo_node.
        ENDTRY.
      ENDIF.
    ENDLOOP.

 

This will complete the preliminary directory explorer using CL_SALV_TREE.

Now, we will explore more about the events and their usefulness.

ON_EXPAND_EMPTY : –ย  This method will allow us to populate the nodes whenever an empty node is expanded and thus saving the data under that node.

 

ON_USER_COMMAND : – This event will handle all the functions that set the value of sy-ucomm in the output screen.

I have used this method to trigger the buttons put in the PF_STATUS of the SALV_TREE.

 

Now to the more interesting tricks for salv : –

1 . SORTING

I have implemented the function of sorting the elements under a selected folder in the following way : –

    TRY.
        lo_sels = go_tree->get_selections( ).
        lo_item = lo_sels->get_selected_item( ).
        IF lo_item IS NOT INITIAL.
          lo_node_parent = lo_item->get_node( ).
          lo_key         = lo_node_parent->get_key( ).
          lt_childr = lo_node_parent->get_children( ).
        ELSE.
          MESSAGE i303(42).
        ENDIF.



*--- Getting the childrens of the selected node and then deleting them and creating them again with the sorted data

        LOOP AT lt_childr ASSIGNING <ls_childr>.
          ls_datarow = <ls_childr>-node->get_data_row( ).
          <ls_childr>-node->delete( ).

          ASSIGN ls_datarow->* TO <lfs_rowdata>.
          APPEND <lfs_rowdata> TO lt_main.
        ENDLOOP.
      CATCH cx_salv_msg.
        FREE <ls_childr>.
    ENDTRY.

    me->md_create_node( iv_key =  lo_key ).

 

2. FILTERING

I have used the following logic to filter the elements under a particular node. You can filter the last expanded node too which shall be discussed later.

    TRY.
        lo_sels = go_tree->get_selections( ).
        lo_item = lo_sels->get_selected_item( ).
        IF lo_item IS NOT INITIAL.
          lo_node_parent = lo_item->get_node( ).
          lt_childr = lo_node_parent->get_children( ).
        ELSE.
          MESSAGE i303(42).
        ENDIF.


        LOOP AT lt_childr ASSIGNING <ls_childr>.
          ls_datarow = <ls_childr>-node->get_data_row( ).
          ASSIGN ls_datarow->* TO <lfs_rowdata>.
          IF <lfs_rowdata>-name NP iv_filters.
            <ls_childr>-node->delete( ).
          ENDIF.
        ENDLOOP.

      CATCH cx_salv_msg.
        FREE lo_nodes.
    ENDTRY.

 

3. REFRESH

This is the most easiest one!

    TRY.
        lo_nodes = go_tree->get_nodes( ).
        lo_nodes->delete_all( ).
      CATCH cx_salv_error.
        FREE lo_nodes.
    ENDTRY.

    me->md_display_initial( ).

The display initial method again initializes the SALV with an empty tree and repeats the whole processing and returns the tree to its initial state.

I have implemented many more functionalities and will be sharing them in the future.

Hope this helps ๐Ÿ™‚

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

Leave a Reply