* Demoprogramm: SAPCOLUMN_TREE_CONTROL_DEMO
CONSTANTS: co_root TYPE tv_nodekey VALUE 'Root'.
CONSTANTS: co_auart TYPE tv_itmname VALUE 'Auftragsart'.
CONSTANTS: co_matnr TYPE tv_itmname VALUE 'Mat.-Nr.'.
CONSTANTS: co_arktx TYPE tv_itmname VALUE 'Kurztext'.
CONSTANTS: co_netwr TYPE tv_itmname VALUE 'Wert'.
CONSTANTS: co_flag TYPE tv_itmname VALUE 'Flag'.
DATA: it_nodes TYPE treev_ntab.
DATA: it_items TYPE STANDARD TABLE OF mtreeitm WITH DEFAULT KEY.
TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
TYPES: BEGIN OF ty_vbak_vbap,
auart TYPE vbak-auart,
vbeln TYPE vbak-vbeln,
posnr TYPE vbap-posnr,
matnr TYPE vbap-matnr,
arktx TYPE vbap-arktx,
netwr TYPE vbap-netwr,
flag TYPE boolean,
END OF ty_vbak_vbap.
TYPES: ty_it_vbak_vbap TYPE STANDARD TABLE OF ty_vbak_vbap WITH DEFAULT KEY.
* Eventhandlerklasse
CLASS lcl_event DEFINITION.
PUBLIC SECTION.
CLASS-METHODS: on_node_double_click FOR EVENT node_double_click OF cl_gui_column_tree
IMPORTING
node_key
sender.
CLASS-METHODS: on_item_double_click FOR EVENT item_double_click OF cl_gui_column_tree
IMPORTING
node_key
item_name
sender.
CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_column_tree
IMPORTING
node_key
sender.
CLASS-METHODS: on_header_click FOR EVENT header_click OF cl_gui_column_tree
IMPORTING
header_name
sender.
CLASS-METHODS: on_button_click FOR EVENT button_click OF cl_gui_column_tree
IMPORTING
node_key
item_name
sender.
CLASS-METHODS: on_link_click FOR EVENT link_click OF cl_gui_column_tree
IMPORTING
node_key
item_name
sender.
CLASS-METHODS: on_checkbox_change FOR EVENT checkbox_change OF cl_gui_column_tree
IMPORTING
node_key
item_name
checked
sender.
CLASS-METHODS: on_dft_context_menu_req FOR EVENT default_context_menu_request OF cl_gui_column_tree
IMPORTING
menu
sender.
CLASS-METHODS: on_dft_context_menu_sel FOR EVENT default_context_menu_select OF cl_gui_column_tree
IMPORTING
fcode
sender.
CLASS-METHODS: on_node_context_menu_req FOR EVENT node_context_menu_request OF cl_gui_column_tree
IMPORTING
node_key
menu
sender.
CLASS-METHODS: on_node_context_menu_sel FOR EVENT node_context_menu_select OF cl_gui_column_tree
IMPORTING
node_key
fcode
sender.
CLASS-METHODS: on_item_context_menu_req FOR EVENT item_context_menu_request OF cl_gui_column_tree
IMPORTING
node_key
item_name
menu
sender.
CLASS-METHODS: on_item_context_menu_sel FOR EVENT item_context_menu_select OF cl_gui_column_tree
IMPORTING
node_key
item_name
fcode
sender.
CLASS-METHODS: on_header_context_menu_req FOR EVENT header_context_menu_request OF cl_gui_column_tree
IMPORTING
header_name
menu
sender.
CLASS-METHODS: on_header_context_menu_sel FOR EVENT header_context_menu_select OF cl_gui_column_tree
IMPORTING
header_name
fcode
sender.
ENDCLASS.
CLASS lcl_event IMPLEMENTATION.
* Doppelklick auf Icon
METHOD on_node_double_click.
MESSAGE node_key TYPE 'S'.
ENDMETHOD.
* Doppelklick auf Item
METHOD on_item_double_click.
CASE item_name.
* wenn Item für Wert NETWR editiert werden soll
WHEN co_netwr.
* Text aus der Nodes-Tabelle lesen
ASSIGN it_items[ node_key = node_key item_name = item_name ] TO FIELD-SYMBOL(<i>).
DATA: lv_changed TYPE as4flag.
DATA: lv_value TYPE string.
lv_value = condense( <i>-text ).
* Popup für Werte-Eingabe
CALL FUNCTION 'CC_POPUP_STRING_INPUT'
EXPORTING
property_name = 'NETWR:'
IMPORTING
value_changed = lv_changed
CHANGING
string_value = lv_value.
IF lv_changed = abap_true.
* Text in der Item Table anpassen
<i>-text = lv_value.
* Text in der Node anpassen
sender->item_set_text( node_key = node_key
item_name = item_name
text = |{ <i>-text }| ).
ENDIF.
ENDCASE.
MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
* hier können evtl. Daten nachgeladen werden
METHOD on_expand_no_children.
MESSAGE node_key TYPE 'S'.
ENDMETHOD.
* Header-Klick
METHOD on_header_click.
MESSAGE |{ header_name }| TYPE 'S'.
ENDMETHOD.
* Button-Klick
METHOD on_button_click.
MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
ENDMETHOD.
* Link-Klick
METHOD on_link_click.
MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
ENDMETHOD.
* Checkbox Change
METHOD on_checkbox_change.
MESSAGE |{ item_name }_{ node_key }: { checked }| TYPE 'S'.
ENDMETHOD.
* Freier Klickbereich: Kontextmenu füllen
METHOD on_dft_context_menu_req.
menu->add_function( text = 'Message'
fcode = 'MSG' ).
menu->add_function( text = 'Exit'
fcode = 'EXIT' ).
ENDMETHOD.
* Freier Klickbereich: Klick im Kontextmenu auswerten
METHOD on_dft_context_menu_sel.
CASE fcode.
WHEN 'MSG'.
MESSAGE 'Message' TYPE 'S'.
WHEN 'EXIT'.
LEAVE PROGRAM.
ENDCASE.
ENDMETHOD.
* Node: Kontextmenu füllen
METHOD on_node_context_menu_req.
menu->add_function( text = |{ node_key }|
fcode = 'NODE' ).
ENDMETHOD.
* Node: Klick im Kontextmenu auswerten
METHOD on_node_context_menu_sel.
CASE fcode.
WHEN 'NODE'.
MESSAGE node_key TYPE 'S'.
ENDCASE.
ENDMETHOD.
* Item: Kontextmenu füllen
METHOD on_item_context_menu_req.
menu->add_function( text = |{ node_key }_{ item_name }|
fcode = 'NODE_ITEM' ).
ENDMETHOD.
* Item: Klick im Kontextmenu auswerten
METHOD on_item_context_menu_sel.
CASE fcode.
WHEN 'NODE_ITEM'.
MESSAGE |{ node_key }_{ item_name }| TYPE 'S'.
ENDCASE.
ENDMETHOD.
* Header: Kontextmenu füllen
METHOD on_header_context_menu_req.
menu->add_function( text = |{ header_name }|
fcode = 'HEADER' ).
ENDMETHOD.
* Header: Klick im Kontextmenu auswerten
METHOD on_header_context_menu_sel.
CASE fcode.
WHEN 'HEADER'.
MESSAGE |{ header_name }| TYPE 'S'.
ENDCASE.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA: it_vbak_vbap TYPE ty_it_vbak_vbap.
* Daten holen -> bei zu vielen Elementen (-> 450?) kommt es zum Absturz der Trees
SELECT vbak~auart, vbak~vbeln, vbap~posnr, vbap~matnr, vbap~arktx, vbap~netwr FROM vbak
INNER JOIN vbap ON vbak~vbeln = vbap~vbeln
INTO CORRESPONDING FIELDS OF TABLE @it_vbak_vbap
UP TO 100 ROWS.
SORT: it_vbak_vbap BY auart vbeln posnr.
* 1. Spalte des Trees
DATA(lv_thhdr) = VALUE treev_hhdr( heading = co_auart
width = 50 ).
* Tree-Objekt im default_screen einbetten
DATA(o_tree) = NEW cl_gui_column_tree( parent = cl_gui_container=>default_screen
node_selection_mode = cl_gui_column_tree=>node_sel_mode_single
item_selection = abap_true
hierarchy_column_name = co_auart
hierarchy_header = lv_thhdr ).
* Eventtypten müssen gesondert registriert werden
DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_column_tree=>eventid_node_double_click
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_item_double_click
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_expand_no_children
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_link_click
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_button_click
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_checkbox_change
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_header_click
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_def_context_menu_req
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_node_context_menu_req
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_item_context_menu_req
appl_event = abap_true )
( eventid = cl_gui_column_tree=>eventid_header_context_men_req
appl_event = abap_true ) ).
* Events registrieren
o_tree->set_registered_events( events = it_events ).
* Eventhandler für Klicks und Kontextmenüs
SET HANDLER lcl_event=>on_node_double_click FOR o_tree.
SET HANDLER lcl_event=>on_item_double_click FOR o_tree.
SET HANDLER lcl_event=>on_expand_no_children FOR o_tree.
SET HANDLER lcl_event=>on_header_click FOR o_tree.
SET HANDLER lcl_event=>on_button_click FOR o_tree.
SET HANDLER lcl_event=>on_link_click FOR o_tree.
SET HANDLER lcl_event=>on_checkbox_change FOR o_tree.
SET HANDLER lcl_event=>on_dft_context_menu_req FOR o_tree.
SET HANDLER lcl_event=>on_dft_context_menu_sel FOR o_tree.
SET HANDLER lcl_event=>on_node_context_menu_req FOR o_tree.
SET HANDLER lcl_event=>on_node_context_menu_sel FOR o_tree.
SET HANDLER lcl_event=>on_item_context_menu_req FOR o_tree.
SET HANDLER lcl_event=>on_item_context_menu_sel FOR o_tree.
SET HANDLER lcl_event=>on_header_context_menu_req FOR o_tree.
SET HANDLER lcl_event=>on_header_context_menu_sel FOR o_tree.
* weitere Spalten entsprechend der Reihenfolge
o_tree->add_column( name = co_matnr
width = 30
header_text = CONV #( co_matnr ) ).
o_tree->add_column( name = co_arktx
width = 70
header_text = CONV #( co_arktx ) ).
o_tree->add_column( name = co_netwr
width = 30
header_text = CONV #( co_netwr ) ).
o_tree->add_column( name = co_flag
width = 5
header_text = CONV #( co_flag ) ).
* Inhalt des Trees komplett löschen
* o_tree->delete_all_nodes( ).
* Rootnode einfügen
it_nodes = VALUE #( ( node_key = co_root
isfolder = abap_true ) ).
* Items der Rootnode
it_items = VALUE #( ( node_key = co_root
item_name = co_auart
class = cl_gui_column_tree=>item_class_text
text = co_root
font = cl_gui_column_tree=>item_font_fixed
style = cl_gui_column_tree=>style_intensified )
( node_key = co_root
item_name = co_matnr
class = cl_gui_column_tree=>item_class_text
text = '' )
( node_key = co_root
item_name = co_arktx
class = cl_gui_column_tree=>item_class_text
text = '' )
( node_key = co_root
item_name = co_netwr
class = cl_gui_column_tree=>item_class_text
text = '' )
( node_key = co_root
item_name = co_flag
class = cl_gui_column_tree=>item_class_text
text = '' ) ).
* Unternodes: Auftragsarten <a> -> Belege <v> -> Positionen <p>
LOOP AT it_vbak_vbap ASSIGNING FIELD-SYMBOL(<a>) GROUP BY <a>-auart ASCENDING.
* Node für Auftragsarten
APPEND VALUE #( node_key = <a>-auart
relatkey = co_root
relatship = cl_gui_column_tree=>relat_last_child
isfolder = abap_true
expander = abap_true ) TO it_nodes.
* Items für Auftragsarten
APPEND VALUE #( node_key = <a>-auart
item_name = co_auart
class = cl_gui_column_tree=>item_class_text
text = <a>-auart
font = cl_gui_column_tree=>item_font_fixed ) TO it_items.
APPEND VALUE #( node_key = <a>-auart
item_name = co_matnr
class = cl_gui_column_tree=>item_class_text
text = '' ) TO it_items.
APPEND VALUE #( node_key = <a>-auart
item_name = co_arktx
class = cl_gui_column_tree=>item_class_text
text = '' ) TO it_items.
APPEND VALUE #( node_key = <a>-auart
item_name = co_netwr
class = cl_gui_column_tree=>item_class_text
text = '' ) TO it_items.
APPEND VALUE #( node_key = <a>-auart
item_name = co_flag
class = cl_gui_column_tree=>item_class_text
text = '' ) TO it_items.
LOOP AT GROUP <a> ASSIGNING FIELD-SYMBOL(<v>) GROUP BY <v>-vbeln ASCENDING.
* Node für Belegnummern
APPEND VALUE #( node_key = <v>-vbeln
relatkey = <a>-auart
relatship = cl_gui_column_tree=>relat_last_child
isfolder = abap_true
expander = abap_true ) TO it_nodes.
* Items für Belegnummern
APPEND VALUE #( node_key = <v>-vbeln
item_name = co_auart
class = cl_gui_column_tree=>item_class_text
text = <v>-vbeln
font = cl_gui_column_tree=>item_font_fixed ) TO it_items.
APPEND VALUE #( node_key = <v>-vbeln
item_name = co_matnr
class = cl_gui_column_tree=>item_class_text
text = '' ) TO it_items.
APPEND VALUE #( node_key = <v>-vbeln
item_name = co_arktx
class = cl_gui_column_tree=>item_class_text
text = '' ) TO it_items.
APPEND VALUE #( node_key = <v>-vbeln
item_name = co_flag
class = cl_gui_column_tree=>item_class_text
text = '' ) TO it_items.
DATA(lv_sum_netwr) = VALUE vbap-netwr( ).
DATA(lv_cnt) = 0.
LOOP AT GROUP <v> ASSIGNING FIELD-SYMBOL(<p>).
* Node für Positionen
* eindeutigen Key erzeugen (max. 12 Zeichen lang)
DATA(lv_pos_key) = |{ <p>-vbeln ALPHA = OUT }{ <p>-posnr ALPHA = OUT }|.
APPEND VALUE #( node_key = lv_pos_key
relatkey = <v>-vbeln
relatship = cl_gui_column_tree=>relat_last_child
isfolder = abap_false
expander = abap_false ) TO it_nodes.
* Items für Positionen
APPEND VALUE #( node_key = lv_pos_key
item_name = co_auart
class = cl_gui_column_tree=>item_class_button
text = <p>-posnr
font = cl_gui_column_tree=>item_font_default ) TO it_items.
APPEND VALUE #( node_key = lv_pos_key
item_name = co_matnr
class = cl_gui_column_tree=>item_class_link
text = <p>-matnr
style = cl_gui_column_tree=>style_intensified
font = cl_gui_column_tree=>item_font_fixed ) TO it_items.
APPEND VALUE #( node_key = lv_pos_key
item_name = co_arktx
class = cl_gui_column_tree=>item_class_text
text = <p>-arktx
font = cl_gui_column_tree=>item_font_fixed ) TO it_items.
APPEND VALUE #( node_key = lv_pos_key
item_name = co_netwr
class = cl_gui_column_tree=>item_class_text
text = CONV string( <p>-netwr )
font = cl_gui_column_tree=>item_font_fixed ) TO it_items.
APPEND VALUE #( node_key = lv_pos_key
item_name = co_flag
class = cl_gui_column_tree=>item_class_checkbox
editable = abap_true
text = <p>-flag ) TO it_items.
* Summierung des NETWR für übergeordnetes Item
lv_sum_netwr = lv_sum_netwr + <p>-netwr.
lv_cnt = lv_cnt + 1.
ENDLOOP.
* Ausgabe der Summe in Item für Position
APPEND VALUE #( node_key = <v>-vbeln
item_name = co_netwr
class = cl_gui_column_tree=>item_class_text
text = |Summe: { lv_sum_netwr } ({ lv_cnt })|
font = cl_gui_column_tree=>item_font_fixed ) TO it_items.
ENDLOOP.
ENDLOOP.
* Nodes und Items zum Baum hinzufügen und anzeigen
o_tree->add_nodes_and_items( node_table = it_nodes
item_table = it_items
item_table_structure_name = 'MTREEITM' ). " Typ muss gleich mit Zeilentyp von it_items sein
* Root-Nodes des Trees expandieren
o_tree->expand_root_nodes( ).
* Spaltenbreiten anpassen
* o_tree->adjust_column_width( all_columns = abap_true
* include_heading = abap_true ).
* leere Toolbar ausblenden
cl_abap_list_layout=>suppress_toolbar( ).
* Erzwingung der Listenausgabe in cl_gui_container=>default_screen und Anzeige des Trees
WRITE space.