lunes, 6 de enero de 2014

Crear un Tree dentro de un Docking y mostrar un ALV

Objetivo:
  • Crear un Docking con un Tree.
    • El Tree contendrá la lista de CARRID y PLANETYPE de la tabla SFLIGHT.
  • Pulsar un elemento del Tree y mostrar un ALV con los datos de la SFLIGHT que contengan dicho elemento.
La mayor parte del código no ha sido creado directamente, sino que copiado y adaptado de los ejemplos disponibles en el sistema SAP.

En la transacción SE83 tendremos todos los ejemplos disponibles que se han usado en este ejercicio.

Objeto Docking de la SE83.
Objeto Tree de la SE83. 
Objeto ALV de la SE83.

 Empezamos creando los elementos necesarios del Screen:
  • Un input/output que solo mostrará el texto del elemento pulsado del Tree.
  • Un Custom Control que contendrá nuestro objeto ALV.
Elementos input/output y Custom Control de la pantalla Screen.
No será necesario crear un Custom Control para el Docking ni para el Tree, ya que el Docking se incorporará a la izquierda de la pantalla, y el contenedor del Tree es el propio Docking.

*&---------------------------------------------------------------------*
*& Report  Z_FLIGHT_OBJETOS
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  z_flight_objetos MESSAGE-ID tree_control_msg.

TABLES sflight.

DATA: g_it_sflight TYPE TABLE OF sflight,
      g_st_sflight TYPE sflight.

* Docking Container
DATA g_ob_docking TYPE REF TO cl_gui_docking_container.

* Simple Tree
CLASS lcl_application DEFINITION DEFERRED.
TYPES: g_tt_node_table_type LIKE STANDARD TABLE OF mtreesnode
           WITH DEFAULT KEY.
DATA g_wa_node.

DATA: g_ob_application TYPE REF TO lcl_application,
      g_ob_tree TYPE REF TO cl_gui_simple_tree.

CONSTANTS: BEGIN OF g_c_nodekey,
  root TYPE tv_nodekey VALUE 'Root',
  carrid TYPE tv_nodekey VALUE 'Carrid',
  planetype TYPE tv_nodekey VALUE 'Planetype',
  END OF g_c_nodekey.

* ALV
DATA: g_ob_container TYPE scrfname VALUE 'ALV_9000',
      g_ob_alv  TYPE REF TO cl_gui_alv_grid,
      g_ob_custom_container TYPE REF TO cl_gui_custom_container.

DATA: ok_code_9000 TYPE sy-ucomm,
      g_wa_init,
      g_wa_repid TYPE sy-repid,
      g_wa_dynnr TYPE sy-dynnr,
      io_9000_click(42) TYPE c.

*----------------------------------------------------------------------*
*       CLASS LCL_APPLICATION DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_application DEFINITION.

  PUBLIC SECTION.
    METHODS:
      handle_node_double_click
        FOR EVENT node_double_click
        OF cl_gui_simple_tree
        IMPORTING node_key,
      handle_expand_no_children
        FOR EVENT expand_no_children
        OF cl_gui_simple_tree
        IMPORTING node_key.

ENDCLASS.                    "LCL_APPLICATION DEFINITION

*----------------------------------------------------------------------*
*       CLASS LCL_APPLICATION IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_application IMPLEMENTATION.

  METHOD  handle_node_double_click.
    " this method handles the node double click event of the tree
    " control instance

    io_9000_click = node_key.

    FREE g_it_sflight.
    SELECT * FROM sflight INTO TABLE g_it_sflight
                          WHERE carrid = node_key
                          OR planetype = node_key.

    CALL METHOD g_ob_alv->set_table_for_first_display
      EXPORTING
        i_structure_name = 'SFLIGHT'
      CHANGING
        it_outtab        = g_it_sflight.

  ENDMETHOD.                    "HANDLE_NODE_DOUBLE_CLICK

  METHOD handle_expand_no_children.
    " this method handles the expand no children event of the tree
    " control instance

    IF node_key = g_c_nodekey-carrid.
      g_wa_node = 1.
      PERFORM f_expandir_nodo USING g_wa_node.
    ELSEIF node_key = g_c_nodekey-planetype.
      g_wa_node = 2.
      PERFORM f_expandir_nodo USING g_wa_node.
    ENDIF.

  ENDMETHOD.                    "HANDLE_EXPAND_NO_CHILDREN

ENDCLASS.                    "LCL_APPLICATION IMPLEMENTATION

START-OF-SELECTION.

  CREATE OBJECT g_ob_application.

  CALL SCREEN 9000.

*&---------------------------------------------------------------------*
*&      Module  STATUS_9000  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_9000 OUTPUT.

  SET PF-STATUS 'STATUS_9000'.
  SET TITLEBAR 'TITLE_9000'.

  IF g_wa_init IS INITIAL.

    g_wa_repid = sy-repid.
    g_wa_dynnr = sy-dynnr.
    g_wa_init = 'X'.

* create the docking container
    CREATE OBJECT g_ob_docking
      EXPORTING
        repid     = g_wa_repid
        dynnr     = g_wa_dynnr
        side      = g_ob_docking->dock_at_left
        extension = 180.

    IF g_ob_tree IS INITIAL.
      " The Tree Control has not been created yet.
      " Create a Tree Control and insert nodes into it.
      PERFORM f_create_and_init_tree.
    ENDIF.

    IF g_ob_custom_container IS INITIAL.
      CREATE OBJECT g_ob_custom_container
        EXPORTING
          container_name = g_ob_container.
      CREATE OBJECT g_ob_alv
        EXPORTING
          i_parent = g_ob_custom_container.
    ENDIF.

  ENDIF.

ENDMODULE.                 " STATUS_9000  OUTPUT                       
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_9000  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_9000 INPUT.

  CASE ok_code_9000.
    WHEN 'CANCEL'.
      CALL METHOD g_ob_docking->free.
      LEAVE PROGRAM.
  ENDCASE.

ENDMODULE.                 " USER_COMMAND_9000  INPUT
*&---------------------------------------------------------------------*
*&      Form  CREATE_AND_INIT_TREE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM f_create_and_init_tree .

  DATA: l_it_node_table TYPE g_tt_node_table_type,
        l_it_events TYPE cntl_simple_events,
        l_st_event TYPE cntl_simple_event.

* create a tree control in the docking
  CREATE OBJECT g_ob_tree
    EXPORTING
      parent                      = g_ob_docking
      node_selection_mode         = cl_gui_simple_tree=>node_sel_mode_single
    EXCEPTIONS
      lifetime_error              = 1
      cntl_system_error           = 2
      create_error                = 3
      failed                      = 4
      illegal_node_selection_mode = 5.
  IF sy-subrc <> 0.
    MESSAGE a000.
  ENDIF.

* define the events which will be passed to the backend
  " node double click
  l_st_event-eventid = cl_gui_simple_tree=>eventid_node_double_click.
  l_st_event-appl_event = 'X'. " process PAI if event occurs
  APPEND l_st_event TO l_it_events.

  " expand no children
  l_st_event-eventid = cl_gui_simple_tree=>eventid_expand_no_children.
  l_st_event-appl_event = 'X'.
  APPEND l_st_event TO l_it_events.

  CALL METHOD g_ob_tree->set_registered_events
    EXPORTING
      events                    = l_it_events
    EXCEPTIONS
      cntl_error                = 1
      cntl_system_error         = 2
      illegal_event_combination = 3.
  IF sy-subrc <> 0.
    MESSAGE a000.
  ENDIF.

* assign event handlers in the application class to each desired event
  SET HANDLER g_ob_application->handle_node_double_click FOR g_ob_tree.
  SET HANDLER g_ob_application->handle_expand_no_children FOR g_ob_tree.

  PERFORM f_build_node_table USING l_it_node_table.

* node_table_structure_name     = 'MTREESNODE'
*   A programmer using the tree control must create a structure in the
*   dictionary. This structure must include the structure TREEV_NODE
*   and must contain a character field with the name 'TEXT'.

  CALL METHOD g_ob_tree->add_nodes
    EXPORTING
      table_structure_name           = 'MTREESNODE'
      node_table                     = l_it_node_table
    EXCEPTIONS
      failed                         = 1
      error_in_node_table            = 2
      dp_error                       = 3
      table_structure_name_not_found = 4
      OTHERS                         = 5.
  IF sy-subrc <> 0.
    MESSAGE a000.
  ENDIF.

ENDFORM.                    " CREATE_AND_INIT_TREE
*&---------------------------------------------------------------------*
*&      Form  F_BUILD_NODE_TABLE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_IT_NODE_TABLE  text
*----------------------------------------------------------------------*
FORM f_build_node_table USING p_it_node_table TYPE g_tt_node_table_type.

  DATA: l_st_node LIKE mtreesnode.

* Node with key 'Root'
  l_st_node-node_key = g_c_nodekey-root.
  " Key of the node
  CLEAR l_st_node-relatkey.      " A root node has no parent node
  CLEAR l_st_node-relatship.

  l_st_node-hidden = ' '.        " The node is visible,
  l_st_node-disabled = ' '.      " selectable,
  l_st_node-isfolder = 'X'.      " a folder.
  CLEAR l_st_node-n_image.
  " use default.
  CLEAR l_st_node-exp_image.
  " use default
  CLEAR l_st_node-expander.      " see below.
  l_st_node-text = 'Root'(roo).
  APPEND l_st_node TO p_it_node_table.

* Node with key 'Carrid'
  l_st_node-node_key = g_c_nodekey-carrid.
  " Key of the node
  " Node is inserted as child of the node with key 'Root'.
  l_st_node-relatkey = g_c_nodekey-root.
  l_st_node-relatship = cl_gui_simple_tree=>relat_last_child.

  l_st_node-hidden = ' '.
  l_st_node-disabled = ' '.
  l_st_node-isfolder = 'X'.
  CLEAR l_st_node-n_image.
  CLEAR l_st_node-exp_image.
  l_st_node-expander = 'X'.

  l_st_node-text = 'Carrid'(ch1).
  l_st_node-style = cl_gui_simple_tree=>style_emphasized_positive.
  APPEND l_st_node TO p_it_node_table.

* Node with key 'Planetype'
  l_st_node-node_key = g_c_nodekey-planetype.
  " Key of the node
  " Node is inserted as child of the node with key 'Root'.
  l_st_node-relatkey = g_c_nodekey-root.
  l_st_node-relatship = cl_gui_simple_tree=>relat_last_child.

  l_st_node-hidden = ' '.
  l_st_node-disabled = ' '.
  l_st_node-isfolder = 'X'.
  CLEAR l_st_node-n_image.
  CLEAR l_st_node-exp_image.
  l_st_node-expander = 'X'.

  l_st_node-text = 'Plane type'(ch2).
  l_st_node-style = cl_gui_simple_tree=>style_emphasized_positive.
  APPEND l_st_node TO p_it_node_table.

ENDFORM.                    " BUILD_NODE_TABLE
*&---------------------------------------------------------------------*
*&      Form  F_EXPANDIR_NODO
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM f_expandir_nodo USING p_wa_node TYPE c.

  DATA: l_it_node_table TYPE g_tt_node_table_type,
        l_st_node TYPE mtreesnode.

  DATA: l_it_sflight TYPE TABLE OF sflight WITH HEADER LINE.

  IF p_wa_node = 1.

    SELECT carrid FROM sflight
                  INTO CORRESPONDING FIELDS OF TABLE l_it_sflight.
    SORT l_it_sflight BY carrid.
    DELETE ADJACENT DUPLICATES FROM l_it_sflight COMPARING carrid.

    LOOP AT l_it_sflight.
* Node with key 'Carrid'
      CLEAR l_st_node.
      l_st_node-node_key = l_it_sflight-carrid.
      l_st_node-relatkey = g_c_nodekey-carrid.
      l_st_node-relatship = cl_gui_simple_tree=>relat_last_child.
      l_st_node-isfolder = ' '.
      l_st_node-text = l_it_sflight-carrid.
      APPEND l_st_node TO l_it_node_table.
    ENDLOOP.

  ELSEIF p_wa_node = 2.
    SELECT planetype FROM sflight 
                     INTO CORRESPONDING FIELDS OF TABLE l_it_sflight.
    SORT l_it_sflight BY planetype.
    DELETE ADJACENT DUPLICATES FROM l_it_sflight COMPARING planetype.

    LOOP AT l_it_sflight.
* Node with key 'Planetype'
      CLEAR l_st_node.
      l_st_node-node_key = l_it_sflight-planetype.
      l_st_node-relatkey = g_c_nodekey-planetype.
      l_st_node-relatship = cl_gui_simple_tree=>relat_last_child.
      l_st_node-isfolder = ' '.
      l_st_node-text = l_it_sflight-planetype.
      APPEND l_st_node TO l_it_node_table.
    ENDLOOP.
  ENDIF.

  CALL METHOD g_ob_tree->add_nodes
    EXPORTING
      table_structure_name           = 'MTREESNODE'
      node_table                     = l_it_node_table
    EXCEPTIONS
      failed                         = 1
      error_in_node_table            = 2
      dp_error                       = 3
      table_structure_name_not_found = 4
      OTHERS                         = 5.
  IF sy-subrc <> 0.
    MESSAGE a000.
  ENDIF.

ENDFORM.                    " F_EXPANDIR_NODO

Resultado final del ejercicio.

0 comentarios :

Publicar un comentario