(原創)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.

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM