ALV Tree

找相关的alv tree demo:se38 -> bcalv_tree*

1.创建对话屏幕

由于ALV没有专门实现的控件,需要先在对话屏幕100上增加一个用户自定义控件区域Custom Control),名为CONTAINER1

2.demo源码

*&---------------------------------------------------------------------*
*& Report YALV_TREE
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT yalv_tree.
*&---------------------------------------------------------------------*
*&数据对象定义
*&---------------------------------------------------------------------*
DATA: g_alv_tree         TYPE REF TO cl_gui_alv_tree,         "树形ALV控制器引用变量
      g_custom_container TYPE REF TO cl_gui_custom_container. "容器类引用变量

DATA: gt_sflight      TYPE sflight OCCURS 0,                  "Output-Table
      gt_fieldcatalog TYPE lvc_t_fcat,
      ok_code         LIKE sy-ucomm,                                  "获取100屏幕触发的功能码
      save_ok         LIKE sy-ucomm,                                  "OK-Code
      g_max           TYPE i VALUE 255.                                 "maximum of db records to select
*&---------------------------------------------------------------------*
*&事件接受类定义
*&---------------------------------------------------------------------*
CLASS lcl_tree_event_receiver DEFINITION.

  PUBLIC SECTION.
    "定义双击节点事件触发时的处理方法
    METHODS handle_node_double_click
                  FOR EVENT node_double_click OF cl_gui_alv_tree
      IMPORTING node_key sender.
* 'sender' is an implicit event parameter that is provided by
* ABAP Objects runtime system. It contains a reference to the
* object that fired the event. You may directly use it to
* call methods of this instance.
    "其中SENDER这个参数是一个隐式的事件参数,是由ABAP对象运行系统提供,它指向了触发这个事件的实例,可以直接使用它来调用这个实例的方法。
ENDCLASS.
CLASS lcl_tree_event_receiver IMPLEMENTATION.
*§3. Implement your event handler methods.定义处理方法的具体实施

  METHOD handle_node_double_click.
    DATA: lt_children TYPE lvc_t_nkey.
*first check if the node is a leaf, i.e. can not be expanded 检查被点击的NODE几点下面有无子节点,有则展开节点。

    CALL METHOD sender->get_children
      EXPORTING
        i_node_key  = node_key
      IMPORTING
        et_children = lt_children.

    IF NOT lt_children IS INITIAL.

      CALL METHOD sender->expand_node
        EXPORTING
          i_node_key    = node_key
          i_level_count = 2.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

END-OF-SELECTION.

  CALL SCREEN 100.
*&---------------------------------------------------------------------*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'MAIN100'.
  SET TITLEBAR 'TITLE'.
  IF g_alv_tree IS INITIAL.
    PERFORM init_tree.

    CALL METHOD cl_gui_cfw=>flush
      EXCEPTIONS
        cntl_system_error = 1
        cntl_error        = 2.
    IF sy-subrc NE 0.
      CALL FUNCTION 'POPUP_TO_INFORM'
        EXPORTING
          titel = 'Automation Queue failure'
          txt1  = 'Internal error:'
          txt2  = 'A method in the automation queue'
          txt3  = 'caused a failure.'.
    ENDIF.
  ENDIF.
ENDMODULE.
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
  save_ok = ok_code.
  CLEAR ok_code.

  CASE save_ok.
    WHEN 'EXIT' OR 'BACK' OR 'CANC'.
      "释放容器,退出程序
      CALL METHOD g_custom_container->free.
      LEAVE PROGRAM.
    WHEN OTHERS.
      "为正确调用工具栏按钮功能,必须调用该方法
      CALL METHOD cl_gui_cfw=>dispatch.

  ENDCASE.

  CALL METHOD cl_gui_cfw=>flush.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Form INIT_TREE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM init_tree .
* create container for alv-tree
  DATA: l_tree_container_name(30) TYPE c.

  l_tree_container_name = 'CONTAINER1'.

  CREATE OBJECT g_custom_container
    EXPORTING
      container_name              = l_tree_container_name
    EXCEPTIONS
      cntl_error                  = 1
      cntl_system_error           = 2
      create_error                = 3
      lifetime_error              = 4
      lifetime_dynpro_dynpro_link = 5.
  IF sy-subrc <> 0.
    MESSAGE x208(00) WITH 'ERROR'(100).
  ENDIF.

* create tree control 实例化TREE控制器
  CREATE OBJECT g_alv_tree
    EXPORTING
      parent                      = g_custom_container
      node_selection_mode         = cl_gui_column_tree=>node_sel_mode_single
      item_selection              = 'X'
      no_html_header              = 'X'
      no_toolbar                  = ''
    EXCEPTIONS
      cntl_error                  = 1
      cntl_system_error           = 2
      create_error                = 3
      lifetime_error              = 4
      illegal_node_selection_mode = 5
      failed                      = 6
      illegal_column_name         = 7.
  IF sy-subrc <> 0.
    MESSAGE x208(00) WITH 'ERROR'.                          "#EC NOTEXT
  ENDIF.

  DATA l_hierarchy_header TYPE treev_hhdr.
  PERFORM build_hierarchy_header CHANGING l_hierarchy_header.

* Hide columns and sum up values initially using the fieldcatalog
*设置ALV字段
  PERFORM build_fieldcatalog.

* IMPORTANT: Table 'gt_sflight' must be empty. Do not change this table
* (even after this method call). You can change data of your table
* by calling methods of CL_GUI_ALV_TREE.
* Furthermore, the output table 'gt_outtab' must be global and can
* only be used for one ALV Tree Control.
  CALL METHOD g_alv_tree->set_table_for_first_display
    EXPORTING
      is_hierarchy_header = l_hierarchy_header
    CHANGING
      it_fieldcatalog     = gt_fieldcatalog
      it_outtab           = gt_sflight. "table must be empty ! 此表必须一直为空,且为全局变量
* 设置根节点,填充叶节点数据
  PERFORM create_hierarchy.
* 注册事件
  PERFORM register_events.
* Update calculations which were initially defined by field DO_SUM
* of the fieldcatalog. (see build_fieldcatalog).
* 更新汇总字段
  CALL METHOD g_alv_tree->update_calculations.

* Send data to frontend.
* 前端显示数据
  CALL METHOD g_alv_tree->frontend_update.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  build_hierarchy_header
*&---------------------------------------------------------------------*
*       build hierarchy-header-information
*----------------------------------------------------------------------*
*      -->P_L_HIERARCHY_HEADER  strucxture for hierarchy-header
*----------------------------------------------------------------------*
FORM build_hierarchy_header CHANGING
                               p_hierarchy_header TYPE treev_hhdr.

  p_hierarchy_header-heading = 'Totals/Month/Carrier/Date'(300).
  p_hierarchy_header-tooltip = 'Flights in a month'(400).
  p_hierarchy_header-width = 35.
  p_hierarchy_header-width_pix = ''.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form build_fieldcatalog
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> P_
*&      --> P_
*&---------------------------------------------------------------------*
FORM build_fieldcatalog.
  DATA: ls_fieldcatalog TYPE lvc_s_fcat.

* The following function module generates a fieldcatalog according
* to a given structure.
  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
      i_structure_name = 'SFLIGHT'
    CHANGING
      ct_fieldcat      = gt_fieldcatalog.

* Now change the fieldcatalog to hide fields and to determine
* some initial calculations for chosen fields.
  LOOP AT gt_fieldcatalog INTO ls_fieldcatalog.
    CASE ls_fieldcatalog-fieldname.
* hide columns which are already displayed in our tree
      WHEN 'CARRID' OR 'FLDATE'.
        ls_fieldcatalog-no_out = 'X'.
* Do some initial calculations:
* ALV Tree uses the field 'do_sum' to declare that a function
* for the corresponding column shall be calculated.
* Use 'h_ftype' to set the function type (MAX, MIN, SUM, AVG).
      WHEN 'PRICE'.
        ls_fieldcatalog-do_sum = 'X'.
        ls_fieldcatalog-h_ftype = 'MAX'.
      WHEN 'SEATSMAX'.
        ls_fieldcatalog-do_sum = 'X'.
        ls_fieldcatalog-h_ftype = 'SUM'.
      WHEN 'SEATSOCC'.
        ls_fieldcatalog-do_sum = 'X'.
        ls_fieldcatalog-h_ftype = 'AVG'.
    ENDCASE.
    MODIFY gt_fieldcatalog FROM ls_fieldcatalog.
  ENDLOOP.

* The fieldcatalog is provided in form 'init_tree' using method
* set_table_for_first_display.
ENDFORM.                               " build_fieldcatalog
*&---------------------------------------------------------------------*
*& Form CREATE_HIERARCHY
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM create_hierarchy .
* See BCALV_TREE_01 for more comments on building the hierarchy
  DATA: ls_sflight       TYPE sflight,
        lt_sflight       TYPE sflight OCCURS 0,
        l_yyyymm(6)      TYPE c,            "year and month of sflight-fldate
        l_yyyymm_last(6) TYPE c,
        l_carrid         LIKE sflight-carrid,
        l_carrid_last    LIKE sflight-carrid.

  DATA: l_month_key  TYPE lvc_nkey,
        l_carrid_key TYPE lvc_nkey,
        l_last_key   TYPE lvc_nkey,
        l_top_key    TYPE lvc_nkey.

* Select data
  SELECT * FROM sflight INTO TABLE lt_sflight UP TO g_max ROWS.
* sort table according to conceived hierarchy
  SORT lt_sflight BY fldate+0(6) carrid fldate+6(2).

* Define one top node. In this way it is possible to calculate
* values for the whole hierarchy.添加主节点
  CALL METHOD g_alv_tree->add_node
    EXPORTING
      i_relat_node_key = ''
      i_relationship   = cl_gui_column_tree=>relat_last_child
      i_node_text      = TEXT-050
    IMPORTING
      e_new_node_key   = l_top_key.

  LOOP AT lt_sflight INTO ls_sflight.
    l_yyyymm = ls_sflight-fldate+0(6).
    l_carrid = ls_sflight-carrid.

    IF l_yyyymm <> l_yyyymm_last.      "on change of l_yyyymm
      l_yyyymm_last = l_yyyymm.
* month nodes
      PERFORM add_month USING    l_yyyymm
                                      l_top_key
                             CHANGING l_month_key.
* clear l_carrid_last because this is a new month
      CLEAR l_carrid_last.
    ENDIF.
* Carrier nodes:
    IF l_carrid <> l_carrid_last.      "on change of l_carrid
      l_carrid_last = l_carrid.
      PERFORM add_carrid_line USING    ls_sflight
                                       l_month_key
                              CHANGING l_carrid_key.
    ENDIF.
* Leaf:
    PERFORM add_complete_line USING  ls_sflight
                                     l_carrid_key
                            CHANGING l_last_key.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form REGISTER_EVENTS
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM register_events .
  "注册前端后后端事件
  DATA: lt_events        TYPE cntl_simple_events,
        l_event          TYPE cntl_simple_event,
        l_event_receiver TYPE REF TO lcl_tree_event_receiver.

*1。获取已注册的前端事件
  CALL METHOD g_alv_tree->get_registered_events
    IMPORTING
      events = lt_events.
  "2.添加前端双击时间
  l_event-eventid = cl_gui_column_tree=>eventid_node_double_click.
  APPEND l_event TO lt_events.

*3.重新设置前端注册时间
  CALL METHOD g_alv_tree->set_registered_events
    EXPORTING
      events                    = lt_events
    EXCEPTIONS
      cntl_error                = 1
      cntl_system_error         = 2
      illegal_event_combination = 3.
  IF sy-subrc <> 0.
    MESSAGE e208(00) WITH '注册前端事件失败!'.                      "#EC NOTEXT
  ENDIF.
*--------------------
  "4.注册后端事件
  CREATE OBJECT l_event_receiver.
  SET HANDLER l_event_receiver->handle_node_double_click FOR g_alv_tree.
ENDFORM.
FORM add_carrid_line USING     ps_sflight TYPE sflight
                               p_relat_key TYPE lvc_nkey
                     CHANGING  p_node_key TYPE lvc_nkey.

  DATA: l_node_text TYPE lvc_value,
        ls_sflight  TYPE sflight.

* add node
  l_node_text =  ps_sflight-carrid.
  CALL METHOD g_alv_tree->add_node
    EXPORTING
      i_relat_node_key = p_relat_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      i_node_text      = l_node_text
      is_outtab_line   = ls_sflight
    IMPORTING
      e_new_node_key   = p_node_key.

ENDFORM.                               " add_carrid_line
*&---------------------------------------------------------------------*
*&      Form  add_complete_line
*&---------------------------------------------------------------------*
FORM add_complete_line USING   ps_sflight TYPE sflight
                               p_relat_key TYPE lvc_nkey
                     CHANGING  p_node_key TYPE lvc_nkey.

  DATA: l_node_text TYPE lvc_value.

  WRITE ps_sflight-fldate TO l_node_text MM/DD/YYYY.

  CALL METHOD g_alv_tree->add_node
    EXPORTING
      i_relat_node_key = p_relat_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      is_outtab_line   = ps_sflight
      i_node_text      = l_node_text
    IMPORTING
      e_new_node_key   = p_node_key.

ENDFORM.                               " add_complete_line
*&---------------------------------------------------------------------*
*&      Form  GET_MONTH
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_P_YYYYMM  text
*      <--P_L_MONTH  text
*----------------------------------------------------------------------*
FORM get_month USING    p_yyyymm
               CHANGING p_month.

  DATA: l_monthdigits(2) TYPE c.

  l_monthdigits = p_yyyymm+4(2).
  CASE l_monthdigits.
    WHEN '01'.
      p_month = 'January'(701).
    WHEN '02'.
      p_month = 'February'(702).
    WHEN '03'.
      p_month = 'March'(703).
    WHEN '04'.
      p_month = 'April'(704).
    WHEN '05'.
      p_month = 'May'(705).
    WHEN '06'.
      p_month = 'June'(706).
    WHEN '07'.
      p_month = 'July'(707).
    WHEN '08'.
      p_month = 'August'(708).
    WHEN '09'.
      p_month = 'September'(709).
    WHEN '10'.
      p_month = 'October'(710).
    WHEN '11'.
      p_month = 'November'(711).
    WHEN '12'.
      p_month = 'December'(712).
  ENDCASE.
  CONCATENATE p_yyyymm+0(4) '->' p_month INTO p_month.

ENDFORM.                               " GET_MONTH
*&---------------------------------------------------------------------*
*&      Form  add_month
*&---------------------------------------------------------------------*
FORM add_month  USING     p_yyyymm TYPE c
                          p_relat_key TYPE lvc_nkey
                CHANGING  p_node_key TYPE lvc_nkey.

  DATA: l_node_text TYPE lvc_value,
        ls_sflight  TYPE sflight,
        l_month(15) TYPE c.            "output string for month

* get month name for node text
  PERFORM get_month USING p_yyyymm
                    CHANGING l_month.
  l_node_text = l_month.

* add node
  CALL METHOD g_alv_tree->add_node
    EXPORTING
      i_relat_node_key = p_relat_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      i_node_text      = l_node_text
      is_outtab_line   = ls_sflight
    IMPORTING
      e_new_node_key   = p_node_key.

ENDFORM.                               " add_month

3.运行结果

 

posted @ 2018-11-09 16:45  枫叶飘摇  阅读(668)  评论(0编辑  收藏  举报