5. OO SALV tree
利用函數和GRID的功能發布的SALV包程序(SALV也稱為New ALV)。通過類cl_salv_tree,實現tree類型ALV的輸出。
5.1顯示tree ALV
通過cl_salv_tree類對象lo_tree,顯示tree ALV。
代碼實例:
全局變量定義,使用icon需要引入type-pools:icon;gt_spfli顯示的內表結構,是一個空內表;lo_tree為cl_salv_tree類對象;lo_error為異常類對象;lo_container為容器類對象。
"使用icon type-pools: icon. "這個內表創建alv時,沒有數據 DATA:gt_spfli TYPE STANDARD TABLE OF spfli. "cl_salv_tree類對象 DATA:lo_tree TYPE REF TO cl_salv_tree. "異常類對象 DATA:lo_error TYPE REF TO CX_SALV_ERROR. "屏幕容器類對象 DATA:lo_container TYPE REF TO cl_gui_custom_container.
創建cl_salv_tree類對象,設置顯示tree結構
"創建tree alv,全屏顯示 FORM creat_alv_fullscreen. TRY . "獲取cl_salv_tree類對象 cl_salv_tree=>factory( importing r_salv_tree = lo_tree changing t_table = gt_spfli ). "設置全局 PERFORM set_tree_settings. "獲取數據,設置tree結構 PERFORM set_tree. "顯示alv lo_tree->display( ). CATCH CX_SALV_NO_NEW_DATA_ALLOWED CX_SALV_ERROR INTO lo_error. DATA:result TYPE string. result = lo_error->IF_MESSAGE~GET_TEXT( ). MESSAGE result TYPE 'E'. ENDTRY. ENDFORM.
設置tree的樹形結構,數據是在這個階段獲取的,而生成cl_salv_tree類對象lo_tree時傳入的table為空。
代碼實例:
"設置tree結構 FORM set_tree. DATA:lt_spfli TYPE STANDARD TABLE OF spfli. DATA:lw_spfli LIKE LINE OF lt_spfli. DATA:l_carrid_key type lvc_nkey. DATA:l_connid_key type lvc_nkey. DATA:l_last_key type lvc_nkey. DATA:lo_nodes type ref to cl_salv_nodes. DATA:lo_node type ref to cl_salv_node. DATA:lo_item type ref to cl_salv_item. "查詢數據 SELECT * INTO TABLE lt_spfli FROM spfli. "獲取tree的node節點 "插入節點 "IF_SALV_C_NODE_RELATION~FIRST_CHILD:第一個child "IF_SALV_C_NODE_RELATION~FIRST_SIBLING:第一個brother "IF_SALV_C_NODE_RELATION~LAST_CHILD:最后child "IF_SALV_C_NODE_RELATION~LAST_SIBLING:最后brother "IF_SALV_C_NODE_RELATION~NEXT_SIBLING:next brother "IF_SALV_C_NODE_RELATION~PREVIOUS_SIBLING:previous brother "IF_SALV_C_NODE_RELATION~PARENT:parent節點 lo_nodes = lo_tree->get_nodes( ). LOOP AT lt_spfli INTO lw_spfli. ON CHANGE OF lw_spfli-carrid. TRY . "添加子節點 lo_node = lo_nodes->add_node( related_node = '' data_row = lw_spfli relationship = cl_salv_nodes=>IF_SALV_C_NODE_RELATION~LAST_CHILD ). l_carrid_key = lo_node->get_key( ). CATCH cx_salv_msg. ENDTRY. ENDON. ON CHANGE OF lw_spfli-connid. TRY . "添加子節點 lo_node = lo_nodes->add_node( related_node = l_carrid_key data_row = lw_spfli relationship = cl_salv_nodes=>IF_SALV_C_NODE_RELATION~LAST_CHILD ). "獲取節點key l_connid_key = lo_node->get_key( ). CATCH cx_salv_msg. ENDTRY. ENDON. "添加最后層 TRY . "添加子節點 lo_node = lo_nodes->add_node( related_node = l_connid_key data_row = lw_spfli relationship = cl_salv_nodes=>IF_SALV_C_NODE_RELATION~LAST_CHILD ). "獲取節點key l_last_key = lo_node->get_key( ). CATCH cx_salv_msg. ENDTRY. ENDLOOP. ENDFORM.
5.2使用子屏幕顯示tree alv
定義全局的lo_container容器類對象。
1.創建子屏幕100

2.創建GUI Status

3.創建屏幕容器CONTAINER

代碼實例:
調用子屏幕程序
"創建子屏幕container顯示alv FORM creat_alv_screen. "調用子屏幕 CALL SCREEN 100. ENDFORM. 子屏幕輸入輸入module *&---------------------------------------------------------------------* *& Module STATUS_0100 OUTPUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE STATUS_0100 OUTPUT. "設置PF-STATUS SET PF-STATUS '100'. IF lo_container IS NOT BOUND. IF cl_salv_tree=>is_offline( ) EQ abap_false. CREATE OBJECT lo_container EXPORTING container_name = 'CONTAINER'. ENDIF. ENDIF. "創建cl_salv_tree類對象 TRY . cl_salv_tree=>factory( EXPORTING r_container = lo_container IMPORTING r_salv_tree = lo_tree CHANGING t_table = gt_spfli ). "設置全局 PERFORM set_tree_settings. "獲取數據,設置tree結構 PERFORM set_tree. "顯示alv lo_tree->display( ). CATCH CX_SALV_NO_NEW_DATA_ALLOWED CX_SALV_ERROR. EXIT. ENDTRY. ENDMODULE. " STATUS_0100 OUTPUT *&---------------------------------------------------------------------* *& Module USER_COMMAND_0100 INPUT *&---------------------------------------------------------------------* * text user command *----------------------------------------------------------------------* MODULE USER_COMMAND_0100 INPUT. DATA:ok_code TYPE syucomm. ok_code = sy-ucomm. CASE ok_code. WHEN 'BACK'. CLEAR ok_code. SET SCREEN 0. LEAVE SCREEN. ENDCASE. ENDMODULE. " USER_COMMAND_0100 INPUT
5.3設置tree顯示
通過cl_salv_tree_settings類對象lo_tree_settings設置層級的顯示參數。
通過cl_salv_tree類對象lo_tree的get_tree_settings方法獲取cl_salv_tree_settings類對象。
代碼實例:
"設置tree顯示 FORM set_tree_settings. DATA:lo_tree_settings TYPE REF TO cl_salv_tree_settings. DATA:lo_tooltips TYPE REF TO cl_salv_tooltips. "獲取設置實例化對象 lo_tree_settings = lo_tree->get_tree_settings( ). "設置header lo_tree_settings->set_hierarchy_header( 'tree alv' ). "設置tooltip lo_tree_settings->set_hierarchy_tooltip( 'tree alv tooltip' ). "設置層級列icon,type pools:icon lo_tree_settings->set_hierarchy_icon( '@06@' ). "設置size,層級列寬度 lo_tree_settings->set_hierarchy_size( 30 ). "設置header DATA:lv_title TYPE salv_de_tree_text. lv_title = sy-title."系統title lo_tree_settings->set_header( lv_title ). "設置tooltips lo_tooltips = lo_tree_settings->get_tooltips( ). DATA:lv_value TYPE LVC_VALUE. lv_value = IF_SALV_C_TREE_STYLE=>EMPHASIZED_A. "C_TYPE_ICON "C_TYPE_SYMBOL "C_TYPE_COLOR "C_TYPE_EXCEPTION "C_TYPE_TREE_STYLE lo_tooltips->add_tooltip( EXPORTING TYPE = CL_SALV_TOOLTIP=>C_TYPE_TREE_STYLE VALUE = lv_value TOOLTIP = 'tree style tooltip' ). ENDFORM.
5.4設置function
通過cl_salv_tree類對象lo_tree的set_screen_status方法設置pf-status。
找到Function Group:KKBL,復制標准的PF-STATUS到Program。但是在tree ALV 中顯示出來的標准功能,基本上沒有用,所以需要定制自己的Tool工具欄。

代碼實例:
"設置function FORM set_functions. "設置自定義PF-STATUS "C_FUNCTIONS_NONE "C_FUNCTIONS_ALL "C_FUNCTIONS_DEFAULT lo_tree->set_screen_status( pfstatus = 'STANDARD_ALV_TREE' report = sy-repid set_functions = lo_tree->c_functions_all ). ENDFORM.

自定義function按鈕,使用cl_salv_functions和cl_salv_functions_tree類對象。
代碼實例:
"設置function FORM set_functions. DATA:lo_functions_base TYPE REF TO cl_salv_functions. DATA:lo_functions_tree TYPE REF TO cl_salv_functions_tree. "設置自定義PF-STATUS "C_FUNCTIONS_NONE "C_FUNCTIONS_ALL "C_FUNCTIONS_DEFAULT lo_tree->set_screen_status( pfstatus = 'STANDARD_ALV_TREE' report = sy-repid set_functions = lo_tree->c_functions_all ). "獲取當前pf-status "lo_tree->get_screen_status( IMPORTING report = pfstatus = ). "使用cl_salv_functions,cl_salv_functions_tree添加自定義function, "只能在定義容器顯示tree ALV時才能生效 TRY . "獲取基礎function類對象 lo_functions_base = lo_tree->get_functions_base( ). "添加function,好像並沒添加 lo_functions_base->add_function( name = 'MYFUN1' icon = 'ICON_SELECT_DETAIL' text = 'MYFUN1' tooltip = 'my function' position = IF_SALV_C_FUNCTION_POSITION=>RIGHT_OF_SALV_FUNCTIONS ). CATCH CX_SALV_EXISTING CX_SALV_WRONG_CALL. ENDTRY. TRY. "設置tree特有function lo_functions_tree = lo_tree->get_functions( ). lo_functions_tree->add_function( name = 'MYFUN2' icon = 'ICON_SELECT_DETAIL' text = 'MYFUN2' tooltip = 'my function2' position = IF_SALV_C_FUNCTION_POSITION=>RIGHT_OF_SALV_FUNCTIONS ). CATCH CX_SALV_EXISTING CX_SALV_WRONG_CALL. ENDTRY. ENDFORM.
5.5設置列
通過cl_salv_tree類對象lo_tree的方法get_columns獲取列設置類cl_salv_columns_tree對象lo_columns。
代碼實例:
"設置列 FORM set_columns. DATA:lo_columns TYPE REF TO cl_salv_columns_tree. DATA:lt_columns TYPE SALV_T_COLUMN_REF. DATA:lo_column TYPE REF TO cl_salv_column. TRY . "獲取列設置對象 lo_columns = lo_tree->get_columns( ). "設置自適應列寬 lo_columns->set_optimize( abap_true ). "獲取column內表,所有列 lt_columns = lo_columns->get( ). "獲取單列 lo_column = lo_columns->get_column( columnname = 'CARRID' ). "獲取列位置 DATA:lv_pos. lv_pos = lo_columns->get_column_position( columnname = 'CARRID' ). "設置列位置 lo_columns->set_column_position( columnname = 'CARRID' position = 3 ). "獲取,設置exception列 "SET_EXCEPTION_COLUMN "GET_EXCEPTION_COLUMN "通過cl_salv_column設置單列 lo_column->set_alignment( IF_SALV_C_ALIGNMENT=>LEFT ). lo_column->set_short_text( '航班id' ). "設置隱藏 lo_column = lo_columns->get_column( columnname = 'AIRPFROM' ). lo_column->set_visible( abap_false ). lo_column = lo_columns->get_column( columnname = 'AIRPTO' ). lo_column->set_technical( abap_true ). "設置quantity lo_column = lo_columns->get_column( columnname = 'DISTANCE' ). lo_column->set_quantity( 'C36' ). "SET_ALIGNMENT設置對齊方式 "IF_SALV_C_ALIGNMENT=>LEFT/RIGHT/CENTERED "SET_CURRENCY_COLUMN,設置currency列 "SET_CURRENCY,設置currency "SET_DDIC_REFERENCE:設置數據庫參考數據結構 "SET_DECIMALS_COLUMN"設置小數列 "SET_DECIMALS"設置整列小數位數 "SET_EDIT_MASK"設置格式顯示 "SET_F1_ROLLNAME "SET_LEADING_ZERO "設置前置0 "SET_LOWERCASE "是否可轉換小寫 "SET_LONG_TEXT "設置列字段名 "SET_MEDIUM_TEXT"設置列字段名 "SET_SHORT_TEXT"設置列字段名 "SET_OPTIMIZED "設置自適應寬度 "SET_OUTPUT_LENGTH"設置輸出長度 "SET_QUANTITY "設置數量 "SET_QUANTITY_COLUMN "設置數量列 "SET_ROUND "設置四舍五入 "SET_ROUND_COLUMN"設置四舍五入列 "SET_ROW "SET_SIGN "設置顯示sign "SET_TECHNICAL "設置technical隱藏 "SET_VISIBLE "設置是否可見 "SET_TOOLTIP "SET_ZERO "SET_DECFLOAT_STYLE "GET_DECFLOAT_STYLE "SET_FIXED_HEADER_TEXT CATCH CX_SALV_NOT_FOUND. ENDTRY. ENDFORM.
5.6設置event事件
通過自定義事件處理類lcl_handle_events,然后實現該類;
通過cl_salv_tree類對象lo_tree的get_event方法獲取cl_salv_events_tree類對象,然后將事件處理類方法注冊給該類對象。
代碼實例:
"定義事件處理類 CLASS lcl_handle_events DEFINITION. PUBLIC SECTION. METHODS:on_user_command FOR EVENT added_function OF cl_salv_events IMPORTING e_salv_function. METHODS:on_before_user_command FOR EVENT before_salv_function OF cl_salv_events IMPORTING e_salv_function. METHODS:on_after_user_command FOR EVENT after_salv_function OF cl_salv_events IMPORTING e_salv_function. METHODS:on_double_click FOR EVENT double_click OF cl_salv_events_tree IMPORTING node_key columnname. METHODS:on_link_click FOR EVENT link_click OF cl_salv_events_tree IMPORTING columnname. METHODS:on_keypress FOR EVENT keypress OF cl_salv_events_tree IMPORTING node_key columnname key. METHODS:on_checkbox_change FOR EVENT checkbox_change OF cl_salv_events_tree IMPORTING columnname node_key checked. METHODS:on_expand_empty FOR EVENT expand_empty_folder OF cl_salv_events_tree IMPORTING node_key. ENDCLASS. "事件處理類實現 CLASS lcl_handle_events IMPLEMENTATION. METHOD on_user_command. MESSAGE i000(0k) WITH e_salv_function. ENDMETHOD. METHOD on_before_user_command. MESSAGE i000(0k) WITH 'before:' e_salv_function. ENDMETHOD. METHOD on_after_user_command. MESSAGE i000(0k) WITH 'after:' e_salv_function. ENDMETHOD. METHOD on_double_click. MESSAGE i000(0k) WITH node_key columnname. ENDMETHOD. METHOD on_link_click. MESSAGE i000(0k) WITH columnname. ENDMETHOD. METHOD on_keypress. MESSAGE i000(0k) WITH node_key columnname key. ENDMETHOD. METHOD on_checkbox_change. MESSAGE i000(0k) WITH columnname node_key checked. ENDMETHOD. METHOD on_expand_empty. MESSAGE i000(0k) WITH node_key. ENDMETHOD. ENDCLASS. "設置event FORM set_events. DATA:lo_events TYPE REF TO cl_salv_events_tree. DATA:lo_handle_events TYPE REF TO lcl_handle_events. TRY . "獲取event類對象 lo_events = lo_tree->get_event( ). "創建事件處理類對象 CREATE OBJECT lo_handle_events. "注冊事件 SET HANDLER lo_handle_events->on_user_command FOR lo_events. SET HANDLER lo_handle_events->on_before_user_command FOR lo_events. SET HANDLER lo_handle_events->on_after_user_command FOR lo_events. SET HANDLER lo_handle_events->on_double_click FOR lo_events. SET HANDLER lo_handle_events->on_link_click FOR lo_events. SET HANDLER lo_handle_events->on_keypress FOR lo_events. SET HANDLER lo_handle_events->on_checkbox_change FOR lo_events. SET HANDLER lo_handle_events->on_expand_empty FOR lo_events. "keypress lo_events->add_key_for_keypress( if_salv_c_keys=>f1 ). lo_events->add_key_for_keypress( if_salv_c_keys=>f4 ). lo_events->add_key_for_keypress( if_salv_c_keys=>enter ). CATCH CX_SALV_MSG. ENDTRY. ENDFORM.
5.7設置Node節點
創建樹形結構添加節點時,通過cl_salv_nodes類對象lo_nodes添加新的節點,刪除節點,移動節點。
代碼實例:
"設置node節點 FORM set_nodes. DATA:lt_spfli TYPE TABLE OF spfli. DATA:lw_spfli LIKE LINE OF lt_spfli. "節點類對象 DATA:lo_nodes type ref to cl_salv_nodes. DATA:lo_node type ref to cl_salv_node. DATA:lo_item type ref to cl_salv_item. "key DATA:lv_key type lvc_nkey. "設置節點內容 lw_spfli-carrid = 'BB'. lw_spfli-connid = '11'. lw_spfli-countryfr = 'CN'. lw_spfli-cityfrom = 'CQ'. "獲取節點類對象 lo_nodes = lo_tree->get_nodes( ). TRY . "添加節點 "related_node:父節點 "relationship:設置添加節點和父節點關系 "cl_salv_nodes "IF_SALV_C_NODE_RELATION~FIRST_CHILD:第一個child "IF_SALV_C_NODE_RELATION~FIRST_SIBLING:第一個brother "IF_SALV_C_NODE_RELATION~LAST_CHILD:最后child "IF_SALV_C_NODE_RELATION~LAST_SIBLING:最后brother "IF_SALV_C_NODE_RELATION~NEXT_SIBLING:next brother "IF_SALV_C_NODE_RELATION~PREVIOUS_SIBLING:previous brother "IF_SALV_C_NODE_RELATION~PARENT:parent節點 "或者cl_gui_column_tree "RELAT_FIRST_CHILD "RELAT_FIRST_SIBLING "RELAT_LAST_CHILD "RELAT_LAST_SIBLING "RELAT_NEXT_SIBLING "RELAT_PREV_SIBLING "add_node參數時創建時傳入,也可以使用lo_node的方法設置 "data_row:本節點數據,使用SET_DATA_ROW,GET_DATA_ROW "collapsed_icon:收攏icon,使用SET_COLLAPSED_ICON,GET_COLLAPSED_ICON "expanded_icon:展開icon,使用SET_EXPANDED_ICON,GET_EXPANDED_ICON "row_style:行類型,使用SET_ROW_STYLE,GET_ROW_STYLE "text:tree控制列文本,使用SET_TEXT,GET_TEXT "visible:是否可見,使用SET_VISIBLE,IS_VISIBLE, "expander:是否可展開,使用SET_EXPANDER,HAS_EXPANDER "enabled:是否使能,使用SET_ENABLED,IS_ENABLED "folder:是否活頁夾,使用SET_FOLDER,IS_FOLDER "COLLAPSE:收攏節點 "EXPAND:展開節點 "DELETE:刪除節點 "MOVE:移動節點 "GET_CHILDREN:獲取所有子節點 "GET_FIRST_CHILD:獲取第一個子節點 "GET_LAST_CHILD:獲取最后子節點 "GET_NEXT_SIBLING:獲取下個兄弟節點 "GET_PARENT:獲取parent節點 "GET_PREVIOUS_SIBLING:獲取上個兄弟節點 lo_node = lo_nodes->add_node( related_node = '' relationship = cl_gui_column_tree=>RELAT_LAST_CHILD data_row = lw_spfli text = 'root node' ). "設置folder lo_node->set_folder( abap_true ). "設置icon lo_node->set_expanded_icon( '@3T@' ). lo_node->set_collapsed_icon( '@3S@' ). "獲取key lv_key = lo_node->get_key( ). "獲取hierarchy item,設置超鏈接, lo_item = lo_node->get_hierarchy_item( ). lo_item->set_type( if_salv_c_item_type=>link ). "獲取特定列,設置button類型 lo_item = lo_node->get_item( 'CARRID' ). lo_item->set_type( if_salv_c_item_type=>button ). "添加子節點 lo_node = lo_nodes->add_node( related_node = lv_key relationship = cl_gui_column_tree=>RELAT_LAST_CHILD data_row = lw_spfli ). lo_item = lo_node->get_hierarchy_item( ). "設置為checkbox lo_item->set_type( if_salv_c_item_type=>checkbox ). lo_item->set_editable( abap_true ). lo_node = lo_nodes->add_node( related_node = lv_key relationship = cl_gui_column_tree=>RELAT_LAST_CHILD data_row = lw_spfli ). CATCH CX_SALV_MSG. ENDTRY. ENDFORM.

5.8設置selection
代碼實例:
"設置selection FORM set_selection. DATA:lo_selection TYPE REF TO cl_salv_selections_tree. DATA:lt_nodes TYPE salv_t_nodes. DATA:ls_nodes TYPE salv_s_nodes. DATA:lt_columns TYPE salv_t_column. DATA:lv_column TYPE LVC_FNAME. DATA:lo_item TYPE REF TO cl_salv_item. "獲取selection類對象 lo_selection = lo_tree->get_selections( ). "獲取選擇節點 lt_nodes = lo_selection->get_selected_nodes( ). "設置選擇節點 lo_selection->set_selected_nodes( lt_nodes ). "設置選擇列 lt_columns = lo_selection->get_selected_columns( ). "獲取選擇列 lo_selection->set_selected_columns( lt_columns ). "獲取選擇item lo_item = lo_selection->get_selected_item( ). "設置選擇item lo_selection->set_selected_item( lo_item ). ENDFORM.
5.9設置顯示為popup
直接調用cl_salv_tree類對象lo_tree方法set_screen_popup設置為窗口顯示,只能是fullscreen方式才能設置為popup顯示。
代碼實例:
"設置窗口顯示,只能是fullscreen方式顯示才能設置 FORM set_popup. lo_tree->set_screen_popup( start_column = 10 end_column = 400 start_line = 10 end_line = 500 ). ENDFORM.
5.10關閉窗口
代碼實例:
"關閉窗口 FORM set_close_window. lo_tree->close_screen( ). ENDFORM.
5.11設置layout
代碼實例:
"設置layout FORM set_layout. DATA:lo_layout TYPE REF TO cl_salv_layout. DATA:lv_key TYPE salv_s_layout_key. "設置key lv_key-report = sy-repid. "獲取當前layout lo_layout = lo_tree->get_layout( ). lo_layout->set_key( lv_key ). "獲取default lo_layout->get_default_layout( ). "獲取init layout lo_layout->get_initial_layout( ). "獲取當前layout lo_layout->get_current_layout( ). "設置default lo_layout->set_default( abap_true ). "設置init layout lo_layout->set_initial_layout( 'test' ). "設置save restriction "if_salv_c_layout=>restrict_user_dependant "if_salv_c_layout=>restrict_user_independant. lo_layout->set_save_restriction( if_salv_c_layout=>restrict_none ). ENDFORM.
5.12設置匯總
通過cl_salv_tree類對象lo_tree調用方法get_aggregations獲取cl_salv_aggregations類對象。
代碼實例:
"設置匯總 FORM set_sort_agg. DATA:lo_aggregations TYPE REF TO cl_salv_aggregations. "獲取lo_aggregation類對象 lo_aggregations = lo_tree->get_aggregations( ). "清空匯總 lo_aggregations->clear( ). "添加匯總 "匯總規則AGGREGATION "IF_SALV_C_AGGREGATION~TOTAL "IF_SALV_C_AGGREGATION~MINIMUM "IF_SALV_C_AGGREGATION~MAXIMUM "IF_SALV_C_AGGREGATION~AVERAGE "IF_SALV_C_AGGREGATION~NONE TRY . lo_aggregations->add_aggregation( columnname = 'DISTANCE' ). CATCH cx_salv_not_found cx_salv_data_error cx_salv_existing. ENDTRY. ENDFORM.


