zoukankan      html  css  js  c++  java
  • (原创)OO的ALV-TREE

          在一些情况下,输出的ALV可能用树形结构更容易展现数据之间的相互关联,为了输出ALV-TREE主要用到的是容器类(如CL_GUI_CONTAINER或CL_GUI_CUSTOM_CONTAINER等)和ALV-TREE控制器类CL_GUI_ALV_TREE。

          对于类CL_GUI_ALV_TREE,主要用其ADD_NODE的方法添加节点。

    下面直接给出仿照SAP示例程序BCALV_TREE_02创建的一个DEMO:

    输出目标(汇总可用库存字段/双击节点对应的文件夹图标能展开其子节点):

    源代码:

    *&---------------------------------------------------------------------*
    *& Report Z15540_OOALV_TREE
    *&---------------------------------------------------------------------*
    *&
    *&---------------------------------------------------------------------*
    REPORT Z15540_OOALV_TREE.
    *&---------------------------------------------------------------------*
    *&数据对象定义
    *&---------------------------------------------------------------------*
    DATA:BEGIN OF GS_ALV,
           WERKS TYPE MARD-WERKS,
           LGORT TYPE MARD-LGORT,
           MATNR TYPE MARD-MATNR,
           MAKTX TYPE MAKT-MAKTX,
           LABST TYPE MARD-LABST,
           MEINS TYPE MARA-MEINS,
         END OF GS_ALV.
    DATA GT_ALV LIKE TABLE OF GS_ALV.
    DATA:GS_FCAT TYPE LVC_S_FCAT,
         GT_FCAT TYPE LVC_T_FCAT.
    DATA:LCL_CONTAINER TYPE REF TO CL_GUI_CONTAINER, "容器类引用变量
         LCL_TREE      TYPE REF TO CL_GUI_ALV_TREE. "树形ALV控制器引用变量
    DATA:OK_CODE   TYPE SY-UCOMM, "获取100屏幕触发的功能码
         SAVE_CODE TYPE SY-UCOMM.
    *&---------------------------------------------------------------------*
    *&事件接受类定义
    *&---------------------------------------------------------------------*
    CLASS LCL_HANDLE DEFINITION.
    
      PUBLIC SECTION.
        "定义双击节点事件触发时的处理方法
        METHODS HANDLE_NODE_DCLICK
                      FOR EVENT NODE_DOUBLE_CLICK OF CL_GUI_ALV_TREE
          IMPORTING NODE_KEY SENDER.
        "其中SENDER这个参数是一个隐式的事件参数,是由ABAP对象运行系统提供,它指向了触发这个事件的实例,可以直接使用它来调用这个实例的方法。
    
    ENDCLASS.
    
    CLASS LCL_HANDLE IMPLEMENTATION.
    
      "定义处理方法的具体实施
      METHOD HANDLE_NODE_DCLICK.
        DATA: LT_CHILDREN TYPE LVC_T_NKEY.
    *检查被点击的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.
      CALL SCREEN 100.
    *&---------------------------------------------------------------------*
    *& Module STATUS_0100 OUTPUT
    *&---------------------------------------------------------------------*
    *&
    *&---------------------------------------------------------------------*
    MODULE STATUS_0100 OUTPUT.
      SET PF-STATUS 'MAIN100'.
      SET TITLEBAR 'TITLE'.
      IF LCL_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.
    *&---------------------------------------------------------------------*
    *& Form INIT_TREE
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM INIT_TREE .
      "1.实例化容器对象
      LCL_CONTAINER = CL_GUI_CONTAINER=>SCREEN0.
    
      "2.实例化TREE控制器
      CREATE OBJECT LCL_TREE
        EXPORTING
          PARENT                      = LCL_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 E208(00) WITH '实例化ALV TREE控制器失败!'.     "
      ENDIF.
      "3.设置NODE描述字段信息
      DATA L_HIERARCHY_HEADER TYPE TREEV_HHDR.
      PERFORM BUILD_HIERARCHY_HEADER CHANGING L_HIERARCHY_HEADER.
      "4.设置ALV字段
      PERFORM FRM_FILLFIELD USING: 'WERKS' '工厂',
                                   'LGORT' '仓库',
                                   'MATNR' '物料号',
                                   'MAKTX' '物料描述',
                                   'LABST' '非限制使用库存',
                                   'MEINS' '数量单位'.
      "5设置ALV显示字段
      CALL METHOD LCL_TREE->SET_TABLE_FOR_FIRST_DISPLAY
        EXPORTING
          IS_HIERARCHY_HEADER = L_HIERARCHY_HEADER
        CHANGING
          IT_FIELDCATALOG     = GT_FCAT
          IT_OUTTAB           = GT_ALV. "此表必须一直为空,且为全局变量
      "6.设置根节点,填充叶节点数据
      PERFORM CREATE_HIERARCHY.
      "7.注册事件
      PERFORM REGISTER_EVENTS.
    * 更新汇总字段
      CALL METHOD LCL_TREE->UPDATE_CALCULATIONS.
    *前端显示数据
      CALL METHOD LCL_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 = '工厂/仓库'.
      P_HIERARCHY_HEADER-TOOLTIP = '节点依据'.
      P_HIERARCHY_HEADER-WIDTH = 50.
      P_HIERARCHY_HEADER-WIDTH_PIX = ''.
    
    ENDFORM.
    *&---------------------------------------------------------------------*
    *& Form FRM_FILLFIELD
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *&      --> P_
    *&      --> P_
    *&---------------------------------------------------------------------*
    FORM FRM_FILLFIELD USING P_FIELDNAME TYPE LVC_FNAME
                              P_COLTEXT TYPE LVC_TXTCOL.
    
      CLEAR GS_FCAT.
      GS_FCAT-FIELDNAME = P_FIELDNAME.
      GS_FCAT-COLTEXT = P_COLTEXT.
      IF P_FIELDNAME = 'WERKS' OR P_FIELDNAME = 'LGORT' OR P_FIELDNAME = 'MATNR' .
        GS_FCAT-NO_OUT = 'X'."隐藏右侧输出的MATNR/WERKS/LGORT字段
      ELSEIF P_FIELDNAME = 'LABST'.
        GS_FCAT-QFIELDNAME = 'MEINS'.
        GS_FCAT-DO_SUM = 'X'."汇总可用库存字段
        GS_FCAT-H_FTYPE = 'SUM'.
        GS_FCAT-REF_FIELD = 'LABST'.
        GS_FCAT-REF_TABLE = 'MARD'.
        GS_FCAT-OUTPUTLEN = '30'.
      ELSEIF P_FIELDNAME = 'MAKTX'.
        GS_FCAT-OUTPUTLEN = '30'.
      ENDIF.
      APPEND GS_FCAT TO GT_FCAT.
    ENDFORM.
    *&---------------------------------------------------------------------*
    *& Form CREATE_HIERARCHY
    *&---------------------------------------------------------------------*
    *& text
    *&---------------------------------------------------------------------*
    *& -->  p1        text
    *& <--  p2        text
    *&---------------------------------------------------------------------*
    FORM CREATE_HIERARCHY .
      DATA: LS_NODE      LIKE GS_ALV,
            LS_ALV       LIKE GS_ALV,
            LT_ALV       LIKE TABLE OF GS_ALV,
            L_LAST_WERKS TYPE MARD-WERKS,
            L_LAST_LGORT TYPE MARD-LGORT.
      DATA: L_WERKS_KEY TYPE LVC_NKEY,
            L_LGORT_KEY TYPE LVC_NKEY,
            L_LAST_KEY  TYPE LVC_NKEY,
            L_TOP_KEY   TYPE LVC_NKEY.
      DATA L_NODE_TEXT TYPE LVC_VALUE.
    
      SELECT D~MATNR,
             D~WERKS,
             D~LGORT,
             D~LABST,
             A~MEINS,
             T~MAKTX
      INTO CORRESPONDING FIELDS OF TABLE @LT_ALV UP TO 200 ROWS
      FROM MARD AS D INNER JOIN MARA AS A
      ON D~MATNR = A~MATNR
      LEFT OUTER JOIN MAKT AS T
      ON D~MATNR = T~MATNR
      WHERE T~SPRAS = @SY-LANGU.
    
      SORT LT_ALV BY WERKS LGORT.
    
      "添加祖节点
      CALL METHOD LCL_TREE->ADD_NODE
        EXPORTING
          I_RELAT_NODE_KEY = ''
          I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
          I_NODE_TEXT      = '可用库存'
        IMPORTING
          E_NEW_NODE_KEY   = L_TOP_KEY. "祖节点标识
      "按照工厂->仓库层次设置节点,设置”叶片“,填充"叶片"数据
      LOOP AT  LT_ALV INTO LS_ALV.
        "设置工厂节点
        IF L_LAST_WERKS NE LS_ALV-WERKS.
          L_LAST_WERKS = LS_ALV-WERKS.
          "若此次循环到的工厂与上一次不相同,则创造新的工厂节点
          "ADD NODE
          CLEAR L_NODE_TEXT.
          L_NODE_TEXT = LS_ALV-WERKS.
          CALL METHOD LCL_TREE->ADD_NODE
            EXPORTING
              I_RELAT_NODE_KEY = L_TOP_KEY "处于祖节点之下
              I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
              I_NODE_TEXT      = L_NODE_TEXT
              IS_OUTTAB_LINE   = LS_NODE
            IMPORTING
              E_NEW_NODE_KEY   = L_WERKS_KEY. "工厂节点标识
          CLEAR L_LAST_LGORT."当创建新的工厂节点时,清空上一个库存节点
        ENDIF.
    
        "设置库存节点
        IF L_LAST_LGORT NE LS_ALV-LGORT.
          L_LAST_LGORT = LS_ALV-LGORT.
          "若此次循环到的库存点点与上一次不相同,则创造新的库存节点
          "ADD NODE
          CLEAR L_NODE_TEXT.
          L_NODE_TEXT = LS_ALV-LGORT.
          CALL METHOD LCL_TREE->ADD_NODE
            EXPORTING
              I_RELAT_NODE_KEY = L_WERKS_KEY "处于工厂节点之下
              I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
              I_NODE_TEXT      = L_NODE_TEXT
              IS_OUTTAB_LINE   = LS_NODE
            IMPORTING
              E_NEW_NODE_KEY   = L_LGORT_KEY. "工厂节点标识
        ENDIF.
        "设置”叶片“,填充"叶片"数据
        CLEAR L_NODE_TEXT.
        L_NODE_TEXT = LS_ALV-MATNR.
        CALL METHOD LCL_TREE->ADD_NODE
          EXPORTING
            I_RELAT_NODE_KEY = L_LGORT_KEY "处于库存节点之下
            I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
            I_NODE_TEXT      = L_NODE_TEXT
            IS_OUTTAB_LINE   = LS_ALV "有数据
          IMPORTING
            E_NEW_NODE_KEY   = 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_HANDLE.
    
    *1。获取已注册的前端事件
      CALL METHOD LCL_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 LCL_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_DCLICK FOR LCL_TREE.
    ENDFORM.
    *&---------------------------------------------------------------------*
    *&      Module  USER_COMMAND_0100  INPUT
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    MODULE USER_COMMAND_0100 INPUT.
      SAVE_CODE = OK_CODE.
      CLEAR OK_CODE.
    
      CASE SAVE_CODE.
        WHEN 'EXIT' OR 'BACK' OR 'CANC'.
          "释放容器,退出程序
          CALL METHOD LCL_CONTAINER->FREE.
          LEAVE PROGRAM.
        WHEN OTHERS.
          "为正确调用工具栏按钮功能,必须调用该方法
          CALL METHOD CL_GUI_CFW=>DISPATCH.
    
      ENDCASE.
    
      CALL METHOD CL_GUI_CFW=>FLUSH.
    ENDMODULE.
  • 相关阅读:
    浅谈数据分析中的“暗物质”
    浅谈数据分析中的“暗物质”
    房屋价格数据采集与分析
    房屋价格数据采集与分析
    基于Python对象引用、可变性和垃圾回收详解
    基于Python对象引用、可变性和垃圾回收详解
    人脸识别中常用的几种分类器
    人脸识别中常用的几种分类器
    解析新零售,互联网大数据时代的到来
    osg::NodeVisitor中计算一个节点对应的世界变换矩阵、法向量、顶点坐标
  • 原文地址:https://www.cnblogs.com/jianglaizhen/p/8870859.html
Copyright © 2011-2022 走看看