*&---------------------------------------------------------------------*
*& Report YTEST00A
*&---------------------------------------------------------------------*
*&Violin 2021/4/29
*&---------------------------------------------------------------------*
REPORT ytest00a.
*第9章 Tree Control的使用---------------------------------------------------------------------*
*9.3通過右鍵菜單完成Tree Control 節點的增刪改功能
**功能碼返回值
DATA: ok_code TYPE sy-ucomm,
save_ok TYPE sy-ucomm.
*定制對象
DATA: wa_container TYPE scrfname VALUE 'TREE',
*客戶對象
wa_custom_container TYPE REF TO cl_gui_custom_container,
wa_tree TYPE REF TO cl_gui_simple_tree.
*NODE節點表
DATA: node_table LIKE TABLE OF mtreesnode,
anode_table LIKE TABLE OF mtreesnode,
*節點
node1 TYPE mtreesnode,
node2 TYPE mtreesnode.
*定義內表,變量需要傳遞,不加HEADER LINE
DATA: wa_spfli TYPE TABLE OF spfli.
*當雙擊時取得節點Key值與節點文本值變量
DATA: nodekey(200) VALUE 'NODE',nodetext(200) VALUE 'NONE',
nodekeyold(200) VALUE 'NODE',selectkey(200).
DATA menustr(10) VALUE ''.
*定義對象,定義對象的雙擊方法,用於將該對象雙擊方法分配到樹雙擊事件
CLASS lcl_application DEFINITION DEFERRED.
*對象定義
CLASS lcl_application DEFINITION.
PUBLIC SECTION.
*自定義雙擊方法,參數為節點關鍵字
METHODS handle_node_double_click
FOR EVENT node_double_click
OF cl_gui_simple_tree
IMPORTING node_key.
METHODS:
handle_node_context_menu_req
FOR EVENT node_context_menu_request
OF cl_gui_simple_tree
IMPORTING node_key menu,
handle_node_context_menu_sel
FOR EVENT node_context_menu_select
OF cl_gui_simple_tree
IMPORTING node_key fcode.
ENDCLASS.
*對象方法實現
CLASS lcl_application IMPLEMENTATION.
METHOD handle_node_double_click.
*當雙擊時彈出信息窗口,調試用
* MESSAGE i208(00) WITH 'DOUBLE'.
*獲取KEY值,在窗口顯示
nodekey = node_key.
*從節點內表中按關鍵字讀取單個節點
READ TABLE node_table WITH KEY node_key = node_key INTO node1.
*將節點文本在窗口中顯示
nodetext = node1-text.
ENDMETHOD.
METHOD handle_node_context_menu_req.
CALL METHOD menu->add_function
EXPORTING
text = '增加本級節點'
fcode = 'CODE1'.
CALL METHOD menu->add_function
EXPORTING
text = '增加子節點'
fcode = 'CODE2'.
CALL METHOD menu->add_function
EXPORTING
text = '修改當前節點'
fcode = 'CODE3'.
CALL METHOD menu->add_function
EXPORTING
text = '刪除當前節點'
fcode = 'CODE4'.
ENDMETHOD.
METHOD handle_node_context_menu_sel.
DATA str1 TYPE tv_nodekey.
CALL METHOD wa_tree->get_selected_node
IMPORTING
node_key = str1
EXCEPTIONS
failed = 1
single_node_selection_only = 2
cntl_system_error = 3
OTHERS = 4.
if sy-subrc = 0.
menustr = fcode.
nodekey = str1.
nodekeyold = str1.
endif.
READ TABLE node_table WITH KEY node_key = str1 INTO node1.
nodetext = node1-text.
IF fcode = 'CODE4'.
CALL METHOD wa_tree->delete_node
EXPORTING
node_key = node1-node_key
EXCEPTIONS
failed = 1
node_not_found = 2
cntl_system_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
DELETE node_table WHERE node_key = nodekey.
ENDIF.
.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
ENDMETHOD.
ENDCLASS.
*自定義對象實例
DATA: g_application TYPE REF TO lcl_application.
START-OF-SELECTION.
*直接調用窗口,在窗口PBO分配雙擊對象
CALL SCREEN 590.
MODULE status_0100 OUTPUT.
IF wa_custom_container IS INITIAL.
CREATE OBJECT g_application.
PERFORM create_tree.
ENDIF.
ENDMODULE.
*用戶交互
MODULE user_command_0100 INPUT.
DATA str1 TYPE tv_nodekey.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'CANCEL'.
LEAVE PROGRAM.
WHEN 'GETKEY'.
CALL METHOD wa_tree->get_selected_node
IMPORTING
node_key = str1
EXCEPTIONS
failed = 1
single_node_selection_only = 2
cntl_system_error = 3
OTHERS = 4.
* IF sy-subrc <> 0.
* Implement suitable error handling here
* ENDIF.
IF sy-subrc EQ 0.
selectkey = str1.
ENDIF.
WHEN 'UPTREE'.
IF ( menustr = 'CODE1' ) OR ( menustr = 'CODE2' ).
READ TABLE node_table WITH KEY node_key = nodekey INTO node1.
IF sy-subrc EQ 0.
MESSAGE e208(00) WITH '鍵值重複!'.
ENDIF.
ENDIF.
CASE menustr.
WHEN 'CODE1'.
READ TABLE node_table WITH KEY node_key = nodekeyold INTO node2.
CLEAR node1.
node1-node_key = nodekey.
node1-relatkey = node2-relatkey.
node1-relatship = cl_gui_simple_tree=>relat_last_child.
node1-hidden = ''.
node1-disabled = ''.
node1-isfolder = 'X'.
node1-n_image = '@G3@'.
node1-exp_image = '@G3@'.
CLEAR node1-expander.
node1-text = nodetext.
APPEND node1 TO node_table.
CLEAR anode_table.
APPEND node1 TO anode_table.
CALL METHOD wa_tree->add_nodes
EXPORTING
table_structure_name = 'MTREESNODE'
node_table = anode_table
EXCEPTIONS
error_in_node_table = 1
failed = 2
dp_error = 3
table_structure_name_not_found = 4
OTHERS = 5.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
WHEN 'CODE2'.
CLEAR node1.
node1-node_key = nodekey.
node1-relatkey = nodekeyold.
node1-relatship = cl_gui_simple_tree=>relat_last_child.
node1-hidden = ''.
node1-disabled = ''.
node1-isfolder = 'X'.
node1-n_image = '@G3@'.
node1-exp_image = '@G3@'.
CLEAR node1-expander.
node1-text = nodetext.
APPEND node1 TO node_table.
CLEAR anode_table.
APPEND node1 TO anode_table.
CALL METHOD wa_tree->add_nodes
EXPORTING
table_structure_name = 'MTREESNODE'
node_table = anode_table
EXCEPTIONS
error_in_node_table = 1
failed = 2
dp_error = 3
table_structure_name_not_found = 4
OTHERS = 5.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
WHEN 'CODE3'.
node1-node_key = nodekeyold.
CALL METHOD wa_tree->node_set_text
EXPORTING
node_key = node1-node_key
text = nodetext
EXCEPTIONS
failed = 1
node_not_found = 2
cntl_system_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
ENDCASE.
ENDCASE.
ENDMODULE.
*創建樹及子節點
FORM create_tree.
*事件內表及單個事件對象
DATA: events TYPE cntl_simple_events,
event1 TYPE cntl_simple_event.
*建立定制控制對象
CREATE OBJECT wa_custom_container
EXPORTING
container_name = wa_container.
* 建立樹對象
CREATE OBJECT wa_tree
EXPORTING
* lifetime =
parent = wa_custom_container
* shellstyle =
node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single
* hide_selection =
* name =
* EXCEPTIONS
* lifetime_error = 1
* cntl_system_error = 2
* create_error = 3
* failed = 4
* illegal_node_selection_mode = 5
* others = 6
.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
*開始建立以國家->城市->城區三層的樹
CLEAR node1.
*節點關鍵字
node1-node_key = 'COUNTRY'.
* 第一層
CLEAR node1-relatkey.
CLEAR node1-relatship.
* 文件夾
node1-hidden = ''.
node1-disabled = ''.
node1-isfolder = 'X'.
* 不帶ICON
CLEAR node1-n_image.
CLEAR node1-exp_image.
CLEAR node1-expander.
node1-text = '中國'.
APPEND node1 TO node_table.
* 二層節點
CLEAR node1.
node1-node_key = 'CITY_BJ'.
* 上層關係
node1-relatkey = 'COUNTRY'.
node1-relatship = cl_gui_simple_tree=>relat_last_child.
node1-hidden = ''.
node1-disabled = ''.
node1-isfolder = 'X'.
CLEAR node1-n_image.
CLEAR node1-exp_image.
CLEAR node1-expander.
node1-text = '北京'.
APPEND node1 TO node_table.
CLEAR node1.
node1-node_key = 'CITY_SH'.
* 上層關係
node1-relatkey = 'COUNTRY'.
node1-relatship = cl_gui_simple_tree=>relat_last_child.
node1-hidden = ''.
node1-disabled = ''.
node1-isfolder = 'X'.
CLEAR node1-n_image.
CLEAR node1-exp_image.
CLEAR node1-expander.
node1-text = '上海'.
APPEND node1 TO node_table.
CLEAR node1.
node1-node_key = 'AREA_BJ_CW'.
* 上層關係
node1-relatkey = 'CITY_BJ'.
node1-relatship = cl_gui_simple_tree=>relat_last_child.
node1-hidden = ''.
node1-disabled = ''.
node1-isfolder = ''.
*圖標,可運行SHOWICON查閱
node1-n_image = '@9Y@'.
node1-exp_image = '@9Y@'.
CLEAR node1-expander.
node1-text = '崇文區'.
APPEND node1 TO node_table.
CLEAR node1.
node1-node_key = 'AREA_BJ_XC'.
* 上層關係
node1-relatkey = 'CITY_BJ'.
node1-relatship = cl_gui_simple_tree=>relat_last_child.
node1-hidden = ''.
node1-disabled = ''.
node1-isfolder = ''.
*圖標,可運行SHOWICON查閱
node1-n_image = '@DF@'.
node1-exp_image = '@DF@'.
CLEAR node1-expander.
node1-text = '西城區'.
APPEND node1 TO node_table.
CLEAR node1.
node1-node_key = 'AREA_SH_MX'.
* 上層關係
node1-relatkey = 'CITY_SH'.
node1-relatship = cl_gui_simple_tree=>relat_last_child.
node1-hidden = ''.
node1-disabled = ''.
node1-isfolder = ''.
*圖標,可運行SHOWICON查閱
node1-n_image = '@NL@'.
node1-exp_image = '@NL@'.
CLEAR node1-expander.
node1-text = '閔行區'.
APPEND node1 TO node_table.
*按照節點內容添加節點
CALL METHOD wa_tree->add_nodes
EXPORTING
table_structure_name = 'MTREESNODE'
node_table = node_table
* EXCEPTIONS
* error_in_node_table = 1
* failed = 2
* dp_error = 3
* table_structure_name_not_found = 4
* others = 5
.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
*默認展開Tree
CALL METHOD wa_tree->expand_node
EXPORTING
node_key = 'COUNTRY'
* level_count =
expand_subtree = 'X'
EXCEPTIONS
failed = 1
illegal_level_count = 2
cntl_system_error = 3
node_not_found = 4
cannot_expand_leaf = 5
OTHERS = 6.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
*定義雙擊事件
event1-eventid = cl_gui_simple_tree=>eventid_node_double_click.
event1-appl_event = 'X'.
APPEND event1 TO events.
event1-eventid = cl_gui_simple_tree=>eventid_node_context_menu_req.
event1-appl_event = ''.
APPEND event1 TO events.
CALL METHOD wa_tree->set_ctx_menu_select_event_appl
EXPORTING
appl_event = 'X'.
*添加事件內表
CALL METHOD wa_tree->set_registered_events
EXPORTING
events = events
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
illegal_event_combination = 3
OTHERS = 4.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
*將以定義的雙擊事件分配至樹對象
SET HANDLER g_application->handle_node_double_click FOR wa_tree.
SET HANDLER g_application->handle_node_context_menu_req FOR wa_tree.
SET HANDLER g_application->handle_node_context_menu_sel FOR wa_tree.
ENDFORM.