Solution Manager – hierarchies and data model

Solution Manager stores its data about projects, solutions, test cases etc. in the hierarchies. It is a bit complicated to find the relations between elements in this data model. It consists of trees which include structures, nodes and reference links. Some of identifiers are used on as well on node level as on reference level. Final data is stored in numerous database tables.

Below you can find the simple program, which shows the data models for various structure types, here an example for Test Organizer: test case, documentation, transaction, etc.

Full coding:

REPORT zsm_tree.

TYPES:
* Types for structure and table of ALV tree data
  BEGIN OF ts_data,
    type     TYPE string,
    id       TYPE string,
    mykey    TYPE string,
    text     TYPE hier_text,
    db_table TYPE HIER_TABLE,
  END OF ts_data,
  tt_data  TYPE TABLE OF ts_data,

* Types for structure and table of ALV tree hierarchy
  BEGIN OF ts_hier,
    node     TYPE string,
    parent   TYPE string,
    key      TYPE salv_de_node_key,
  END OF ts_hier,
  tt_hier  TYPE TABLE OF ts_hier.

DATA:
  gt_data        TYPE tt_data, " ALV tree data
  gt_hier        TYPE tt_hier, " ALV tree hierarchy
  gv_dummy_ttree TYPE ttreetype-tree_type.

SELECT-OPTIONS:
  so_ttree FOR gv_dummy_ttree DEFAULT 'BMTC1'.

START-OF-SELECTION.

* Read the tree data and hierarchy
  PERFORM read_hier CHANGING gt_data gt_hier.

* Display tree
  PERFORM display_alv_tree.

*&---------------------------------------------------------------------*
*&      Form  read_hier
*&---------------------------------------------------------------------*
FORM read_hier CHANGING pt_data   TYPE tt_data
                        pt_hier   TYPE tt_hier.

  DATA:
    lt_hier_stype  TYPE TABLE OF hier_stype,
    ls_hier_stype  TYPE hier_stype,
    lt_hier_ntype  TYPE TABLE OF hier_ntype,
    lt_hier_ntype2 TYPE TABLE OF hier_ntype,
    ls_hier_ntype  TYPE hier_ntype,
    lt_tnodertype  TYPE TABLE OF tnodertype,
    ls_tnodertype  TYPE tnodertype,
    lt_trtypeh     TYPE TABLE OF trtypeh,
    ls_trtypeh     TYPE trtypeh,
    lt_trtypet     TYPE TABLE OF trtypet,
    ls_trtypet     TYPE trtypet,

    lv_mykey       TYPE string,
    lv_parent1     TYPE string,
    lv_parent2     TYPE string.

  CALL FUNCTION 'STREE_STRUCTURE_TYPE_GET'
    EXPORTING
      only_active             = 'X'
    TABLES
      list_of_structure_types = lt_hier_stype.

  LOOP AT lt_hier_stype INTO ls_hier_stype
    WHERE tree_type IN so_ttree.

*   WRITE: / 'TREE_TYPE', ls_hier_stype-tree_type, ls_hier_stype-text.

    PERFORM append_data
      USING '' 'TREE_TYPE' ls_hier_stype-tree_type ls_hier_stype-text
            ls_hier_stype-db_table
      CHANGING pt_data lv_mykey.
    PERFORM append_hier USING lv_mykey '' CHANGING pt_hier.

    lv_parent1 = lv_mykey.

    CALL FUNCTION 'STREE_NODE_TYPE_GET'
      EXPORTING
        only_active    = 'X'
        structure_type = ls_hier_stype-tree_type
      TABLES
        node_types     = lt_hier_ntype.

    LOOP AT lt_hier_ntype INTO ls_hier_ntype.

*     WRITE: / '...', 'NOTE_TYPE', ls_hier_ntype-node_type, ls_hier_ntype-text.

      PERFORM append_data USING lv_parent1 'NODE_TYPE'
        ls_hier_ntype-node_type ls_hier_ntype-text '' CHANGING pt_data lv_mykey.
      PERFORM append_hier USING lv_mykey lv_parent1 CHANGING pt_hier.

      lv_parent2 = lv_mykey.

      CLEAR lt_hier_ntype2.
      APPEND ls_hier_ntype TO lt_hier_ntype2.

      CALL FUNCTION 'STREE_NODE_TYPE_READ'
        TABLES
          i_list_of_node_types       = lt_hier_ntype2
          e_assigned_reference_types = lt_tnodertype.

      LOOP AT lt_tnodertype INTO ls_tnodertype.

        CLEAR lt_trtypeh.
        ls_trtypeh-ref_type = ls_tnodertype-ref_type.
        APPEND ls_trtypeh TO lt_trtypeh.

        CALL FUNCTION 'STREE_REFERENCE_TYPE_READ'
          TABLES
            i_reference_types      = lt_trtypeh
            e_reference_types_text = lt_trtypet.

        READ TABLE lt_trtypet INTO ls_trtypet WITH KEY spras = sy-langu.

*       WRITE: / '......', 'REF_TYPE', ls_tnodertype-ref_type, ls_trtypet-text.

        PERFORM append_data USING lv_parent2 'REF_TYPE'
          ls_tnodertype-ref_type ls_trtypet-text '' CHANGING pt_data lv_mykey.
        PERFORM append_hier USING lv_mykey lv_parent2 CHANGING pt_hier.

      ENDLOOP.
    ENDLOOP.
  ENDLOOP.
ENDFORM.                    "read_hier

*&---------------------------------------------------------------------*
*&      Form  append_data
*&---------------------------------------------------------------------*
FORM append_data USING    pi_parent
                          pi_type
                          pi_id
                          pi_text
                          pi_db_table
                 CHANGING pt_data TYPE tt_data
                          po_mykey.

  DATA:
    ls_data        TYPE ts_data.

  ls_data-type     = pi_type.
  ls_data-id       = pi_id.
  IF pi_parent IS INITIAL.
    CONCATENATE pi_type '_' pi_id INTO po_mykey.
  ELSE.
    CONCATENATE pi_parent '-' pi_type '_' pi_id INTO po_mykey.
  ENDIF.
  ls_data-mykey    = po_mykey.
  ls_data-text     = pi_text.
  CONDENSE ls_data-text.
  ls_data-db_table = pi_db_table.
  APPEND ls_data TO pt_data.
ENDFORM.                    "append_data

*&---------------------------------------------------------------------*
*&      Form  append_hier
*&---------------------------------------------------------------------*
FORM append_hier USING    pi_mykey
                          pi_parent
                 CHANGING pt_hier   TYPE tt_hier.

  DATA:
    ls_hier TYPE ts_hier.

  ls_hier-node   = pi_mykey.
  ls_hier-parent = pi_parent.
  APPEND ls_hier TO pt_hier.
ENDFORM.                    "append_hier

*&---------------------------------------------------------------------*
*&      Form  display_alv_tree
*&---------------------------------------------------------------------*
FORM display_alv_tree.

  DATA:
    lt_empty         TYPE tt_data,
    ls_data          TYPE ts_data,
    ls_hier          TYPE ts_hier,
    lv_key           TYPE salv_de_node_key,
    lo_tree          TYPE REF TO cl_salv_tree,
    lo_nodes         TYPE REF TO cl_salv_nodes,
    lo_node          TYPE REF TO cl_salv_node,
    lo_columns       TYPE REF TO cl_salv_columns,
    lo_column        TYPE REF TO cl_salv_column,
    lo_tree_settings TYPE REF TO cl_salv_tree_settings,
    lv_text          TYPE lvc_value.

  FIELD-SYMBOLS:
    <fs_hier> TYPE ts_hier.

  TRY.
*     1. Create instance with an empty table
      CALL METHOD cl_salv_tree=>factory
        IMPORTING
          r_salv_tree = lo_tree
        CHANGING
          t_table     = lt_empty.

*     2. Add the nodes to the tree and set their relations
      lo_nodes = lo_tree->get_nodes( ).

      LOOP AT gt_hier ASSIGNING <fs_hier>.

        IF <fs_hier>-parent = ''.
*         Add the node as root
          lo_node = lo_nodes->add_node(
            related_node = ''
            relationship = if_salv_c_node_relation=>parent ).
        ELSE.
*         Read the ALV key of parent node and add as a child
          READ TABLE gt_hier INTO ls_hier
            WITH KEY node = <fs_hier>-parent.
          lo_node = lo_nodes->add_node(
            related_node = ls_hier-key
            relationship = if_salv_c_node_relation=>first_child ).
        ENDIF.

*       Save the ALV internal key
        <fs_hier>-key = lo_node->get_key( ).

*       Add the data of the tree
        READ TABLE gt_data INTO ls_data
          WITH KEY mykey = <fs_hier>-node.
        lo_node->set_data_row( ls_data ).
        lv_text = ls_data-id.
        lo_node->set_text( lv_text ).
      ENDLOOP.

*     Do some final format tasks
      lo_columns = lo_tree->get_columns( ).
      lo_columns->set_optimize( abap_true ).
      lo_column = lo_columns->get_column( 'ID' ).
      lo_column->set_visible( abap_false ).
      lo_column = lo_columns->get_column( 'MYKEY' ).
      lo_column->set_visible( abap_false ).
      lo_column = lo_columns->get_column( 'TYPE' ).
      lo_column->set_short_text( 'Type' ).
      lo_tree_settings = lo_tree->get_tree_settings( ).
      lo_tree_settings->set_hierarchy_header( 'ID' ).
      lo_nodes->expand_all( ).

*     Display Table
      lo_tree->display( ).

    CATCH cx_salv_error. " for cl_salv_tree=>factory
  ENDTRY.
ENDFORM.                    "display_alv_tree

See other related notes on my website:

Scroll to Top