在一些情況下,輸出的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.