How to trigger code when the user clicks an ALV hotspot field? - abap

I am struggling with the following issue:
I have two tables (header and items) that I want to connect them by using a hotspot and the class CL_SALV_TABLE. I managed to display the header table and set a hotspot on the column with the number of the order. I want that the second table opens as a popup window after I click once on the number field (which was my hotspot). However, I don't know how to define the event. I know how to get a popup window by using the display method of CL_SALV_TABLE, e.g., this code:
CALL METHOD cl_salv_table=>factory(
* EXPORTING
* list_display = IF_SALV_C_BOOL_SAP=>FALSE
* r_container =
* container_name =
IMPORTING
r_salv_table = o_alv
CHANGING
t_table = it_tab )
.
CATCH cx_salv_msg .
ENDTRY.
o_alv->set_screen_popup( start_column = 1
end_column = 150
start_line = 1
end_line = 30 ).
o_alv->display( ).
Any comment or help is highly appreciated. Thank you in advance!

Here is a minimal example to execute code when an ALV hotspot field is clicked (when any cell in the column "Book number" is clicked, a popup is displayed with a text, but you can do whatever you want of course).
What is important to remember:
METHODS on_hotspot_click FOR EVENT hotspot_click OF cl_gui_alv_grid ... : this is the method to define the code to run when the hotspot field is clicked
SET HANDLER on_hotspot_click ... : to tell the Control Framework to trigger the method when the event occurs
Code:
CLASS lcl_app DEFINITION.
PUBLIC SECTION.
METHODS constructor.
METHODS on_hotspot_click
FOR EVENT hotspot_click OF cl_gui_alv_grid
IMPORTING e_row_id e_column_id es_row_no.
DATA go_alv TYPE REF TO cl_gui_alv_grid.
DATA gt_sbook TYPE TABLE OF sbook.
ENDCLASS.
CLASS lcl_app IMPLEMENTATION.
METHOD constructor.
CREATE OBJECT go_alv EXPORTING i_parent = cl_gui_container=>screen0.
SELECT * FROM sbook INTO TABLE gt_sbook.
DATA(fieldcatalog) = VALUE lvc_t_fcat(
( fieldname = 'BOOKID' ref_table = 'SBOOK' ref_field = 'BOOKID' hotspot = 'X' ) ).
SET HANDLER on_hotspot_click FOR go_alv.
go_alv->set_table_for_first_display(
EXPORTING i_structure_name = 'SBOOK'
CHANGING it_outtab = gt_sbook it_fieldcatalog = fieldcatalog ).
ENDMETHOD.
METHOD on_hotspot_click.
READ TABLE gt_sbook INDEX es_row_no-row_id INTO DATA(ls_sbook).
IF sy-subrc = 0.
MESSAGE |click { ls_sbook-bookid } col { e_column_id-fieldname } row { es_row_no-row_id }| TYPE 'I'.
ENDIF.
ENDMETHOD.
ENDCLASS.
DATA go_app TYPE REF TO lcl_app.
PARAMETERS dummy.
AT SELECTION-SCREEN OUTPUT.
IF go_app IS NOT BOUND.
go_app = NEW lcl_app( ).
ENDIF.

Related

How can I use dynamic SALV with 3 different raditobutton in OO ABAP

I have to do Batch program for 3 different info types (0014,0015,2010).
First step, I have a parameter that is reading the .xls file in a selection screen and 3 different radio buttons for each info type. I want to display a different ALV as when I execute the program with selected radio button. For example, I want to see 0014 if I selected 0014's radio button. The same situation for others.
I can do what I want with one way. That's way is using Perform which have parameters tables and using.
But I cannot do it with OO ABAP. It means using SALV and CLASS/Method style.
Anyone can guide me?
*------------DEFINITION--------
class lcl_report definition.
public section.
types: begin of ty_list_14,
pernr(8) type c,
begda(10) type c,
endda(10) type c,
lgart(5) type c,
betrg(9) type c,
anzhl type i,
message(200) type c,
durum(5) type c,
end of ty_list_14.
data: gt_list_14 type standard table of ty_list_14,
gs_list_14 like line of gt_list_14.
methods:
check_filename,
file_operations,
display_alv.
private section.
data: mo_alv type ref to cl_salv_table.
data: gt_rows type salv_t_row,
gs_rows type i.
data: it_raw type truxs_t_text_data.
data: v_strln type i,
offset type i,
extension type string.
data: i_0014 type table of p0014 initial size 1,
w_0014 type p0014,
l_bapireturn type bapireturn1.
data: filename type string.
methods:
create_alv,
selection_rows,
alv_properties,
upload_file,
create_record_i0014.
methods :
on_user_command for event added_function of cl_salv_events
importing e_salv_function.
endclass.
*------------IMPLEMENTATION--------
class lcl_report implementation.
method display_alv.
me->create_alv( ).
me->selection_rows( ).
me->alv_properties( ).
endmethod.
method file_operations.
me->upload_file( ).
endmethod.
method create_alv.
data: lo_events type ref to cl_salv_events_table.
try.
cl_salv_table=>factory(
importing
r_salv_table = mo_alv
changing
t_table = gt_list_14[]
).
catch cx_salv_msg.
endtry.
lo_events = mo_alv->get_event( ).
set handler go_report->on_user_command for lo_events.
mo_alv->display( ).
endmethod.
method selection_rows .
data: lo_selection type ref to cl_salv_selections.
try.
"Soldan seçim kutularını ekrana getirir.
lo_selection = mo_alv->get_selections( ).
lo_selection->set_selection_mode( if_salv_c_selection_mode=>row_column ).
catch cx_salv_not_found.
endtry.
endmethod.
method check_filename.
v_strln = strlen( p_file ).
if v_strln le 4.
message text-003 type 'E'.
else.
offset = v_strln - 1.
do v_strln times.
if p_file+offset(1) eq '.'.
extension = p_file+offset.
shift extension left deleting leading '.'.
exit.
endif.
subtract 1 from offset.
enddo.
if extension ne 'xls' and
extension ne 'XLS' and
extension ne 'xlsx' and
extension ne 'XLSX' and
extension ne 'txt' and
extension ne 'TXT'.
message text-003 type 'E'.
endif.
endif.
endmethod.
method create_record_i0014.
data: lv_begda type begda,
lv_endda type endda.
loop at gt_rows into gs_rows.
read table gt_list_14 into gs_list_14 index gs_rows.
call function 'CONVERSION_EXIT_ALPHA_INPUT'
exporting
input = gs_list_14-pernr
importing
output = gs_list_14-pernr.
call function 'CONVERSION_EXIT_QNTY1_INPUT'
exporting
input = gs_list_14-betrg
importing
output = gs_list_14-betrg.
clear: lv_begda, lv_endda.
concatenate gs_list_14-begda+6(4)
gs_list_14-begda+3(2)
gs_list_14-begda(2)
into lv_begda.
concatenate gs_list_14-endda+6(4)
gs_list_14-endda+3(2)
gs_list_14-endda(2)
into lv_endda.
move-corresponding gs_list_14 to w_0014.
w_0014-infty = '0014'.
w_0014-begda = lv_begda.
w_0014-endda = lv_endda.
w_0014-lgart = gs_list_14-lgart.
w_0014-betrg = gs_list_14-betrg.
w_0014-anzhl = gs_list_14-anzhl.
append w_0014 to i_0014.
call function 'BAPI_EMPLOYEE_ENQUEUE'
exporting
number = w_0014-pernr
importing
return = l_bapireturn.
call function 'HR_INFOTYPE_OPERATION'
exporting
infty = '0014'
number = w_0014-pernr
record = w_0014
operation = 'INS'
importing
return = l_bapireturn.
gs_list_14-message = l_bapireturn-message.
if l_bapireturn-type eq 'E'.
gs_list_14-durum = '#5C#'.
elseif l_bapireturn-type eq 'W'.
gs_list_14-durum = '#5D#'.
elseif l_bapireturn-type eq 'S' or
l_bapireturn-type is initial.
gs_list_14-durum = '#5B#'.
gs_list_14-message = text-033.
endif.
call function 'BAPI_EMPLOYEE_DEQUEUE'
exporting
number = w_0014-pernr
importing
return = l_bapireturn.
modify gt_list_14 from gs_list_14 index gs_rows.
clear: gs_list_14, w_0014.
refresh i_0014.
endloop.
endmethod.
method on_user_command.
data: lo_selection type ref to cl_salv_selections.
lo_selection = mo_alv->get_selections( ).
gt_rows = lo_selection->get_selected_rows( ).
case e_salv_function.
when '&AKTAR'.
me->create_record_i0014( ).
endcase.
mo_alv->refresh( ).
endmethod.
endclass.
You need create a field-symbol like Excel table structure and set this field-symbol in the SALV.
See this post to know how to create the field-symbol.
Create a structure from a dynamically assigned <itab>
Best regards.
Sebastian

ALV Grid custom F4 help works but then shows No help found

I have a program that displays an editable ALV grid, with a custom F4 help for the field "No." handled via the event onf4. My custom F4 help is displayed and the selected value is returned correctly.
However every time after the custom F4 help closes, another window opens saying "No input help is available".
How to get rid of this supplementary popup?
Thanks.
Here's my code:
CLASS lcl_app DEFINITION.
PUBLIC SECTION.
METHODS constructor.
METHODS display.
METHODS on_onf4
FOR EVENT onf4 OF cl_gui_alv_grid
IMPORTING e_fieldname es_row_no e_fieldvalue.
DATA: grid TYPE REF TO cl_gui_alv_grid,
spflis TYPE TABLE OF spfli.
ENDCLASS.
CLASS lcl_app IMPLEMENTATION.
METHOD constructor.
SELECT * FROM spfli INTO TABLE spflis.
grid = NEW cl_gui_alv_grid(
i_parent = cl_gui_container=>screen0 ).
SET HANDLER on_onf4 FOR grid.
grid->register_f4_for_fields(
it_f4 = VALUE #( ( fieldname = 'CONNID' register = 'X' chngeafter = 'X' ) ) ).
ENDMETHOD.
METHOD display.
DATA(fcat) = VALUE lvc_t_fcat(
( fieldname = 'CARRID' ref_table = 'SPFLI' )
( fieldname = 'CONNID' ref_table = 'SPFLI' f4availabl = 'X' ) ).
grid->set_table_for_first_display(
EXPORTING is_layout = VALUE #( edit = 'X' )
CHANGING it_outtab = spflis
it_fieldcatalog = fcat
EXCEPTIONS OTHERS = 4 ).
ENDMETHOD.
METHOD on_onf4.
DATA return TYPE TABLE OF ddshretval.
IF e_fieldname = 'CONNID'.
SELECT DISTINCT connid FROM spfli INTO TABLE #DATA(connids).
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = 'CONNID'
value_org = 'S'
TABLES
value_tab = connids
return_tab = return
EXCEPTIONS
parameter_error = 1
no_values_found = 2
OTHERS = 3.
IF sy-subrc = 0 AND return IS NOT INITIAL.
FIELD-SYMBOLS <modis> TYPE lvc_t_modi.
ASSIGN er_event_data->m_data->* TO <modis>.
<modis> = VALUE #( BASE <modis> ( row_id = es_row_no-row_id
fieldname = e_fieldname
value = return[ 1 ]-fieldval ) ).
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.
PARAMETERS dummy.
AT SELECTION-SCREEN OUTPUT.
NEW lcl_app( )->display( ).
There's a flag er_event_data->m_event_handled which needs to be set to 'X' in the F4 method handler to say that the F4 was actually managed by the custom handling, otherwise the ALV grid attempts displaying the standard F4 (there was no standard F4 in my case hence the popup).
First add the ER_EVENT_DATA parameter in the method declaration :
METHODS on_onf4
FOR EVENT onf4 OF cl_gui_alv_grid
IMPORTING e_fieldname es_row_no e_fieldvalue
er_event_data.
Inside the method ON_ONF4, set the flag :
er_event_data->m_event_handled = 'X'.

How to disable the Editable ALV Grid in case of an incorrect entry?

Whenever an invalid value is entered in an ALV Grid, how do I disable the other fields (grey out) in the grid and force the user to fix the incorrect field.
I have tried adding protocol in DATA_CHANGED event. But protocol list only shows the error in popup. Editing is still possible and no fields are disabled.
But how do I disable the other fields. Sample behavior as shown below:
Here, the other fields are greyed out and the invalid entry is highlighted. Until the user fixes this error, he/she cannot proceed further.
Having screen 100 with container CCONTAINER1 paste this snippet
CLASS zcl_alv_test DEFINITION.
PUBLIC SECTION.
METHODS: constructor, display_grid, populate_grid.
DATA: lr_rtti_struc TYPE REF TO cl_abap_structdescr,
it_fldcat TYPE lvc_t_fcat,
grid_container1 TYPE REF TO cl_gui_custom_container,
grid1 TYPE REF TO cl_gui_alv_grid.
DATA: BEGIN OF gs_outtab.
INCLUDE TYPE spfli.
DATA: celltab TYPE lvc_t_styl.
DATA: END OF gs_outtab.
DATA gt_outtab1 LIKE TABLE OF gs_outtab INITIAL SIZE 0.
METHODS:
handle_data_changed FOR EVENT data_changed OF cl_gui_alv_grid IMPORTING er_data_changed,
handle_data_changed_finished FOR EVENT data_changed_finished OF cl_gui_alv_grid IMPORTING e_modified et_good_cells,
create_dynamic_fcat.
PRIVATE SECTION.
TYPES: ty_tab LIKE LINE OF gt_outtab1.
METHODS: refresh_grid, fill_celltab IMPORTING p_fieldname TYPE lvc_fname
CHANGING pt_celltab TYPE lvc_t_styl.
ENDCLASS.
CLASS zcl_alv_test IMPLEMENTATION.
METHOD constructor.
CREATE OBJECT grid_container1 EXPORTING container_name = 'CCONTAINER1'.
CREATE OBJECT grid1 EXPORTING i_parent = grid_container1.
SET HANDLER handle_data_changed FOR grid1.
SET HANDLER handle_data_changed_finished FOR grid1.
CALL METHOD grid1->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter.
ENDMETHOD. "constructor
METHOD fill_celltab.
LOOP AT pt_celltab ASSIGNING FIELD-SYMBOL(<fs_fcat>).
IF <fs_fcat>-fieldname = p_fieldname.
<fs_fcat>-style = cl_gui_alv_grid=>mc_style_enabled.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD handle_data_changed.
DATA: lt_celltab TYPE lvc_t_styl.
LOOP AT it_fldcat ASSIGNING FIELD-SYMBOL(<fs_fcat>).
INSERT VALUE lvc_s_styl( style = cl_gui_alv_grid=>mc_style_disabled fieldname = <fs_fcat>-fieldname ) INTO TABLE lt_celltab.
ENDLOOP.
MODIFY gt_outtab1 FROM VALUE ty_tab( celltab = lt_celltab ) TRANSPORTING celltab WHERE connid IS NOT INITIAL.
LOOP AT er_data_changed->mt_mod_cells ASSIGNING FIELD-SYMBOL(<mods>).
READ TABLE gt_outtab1 ASSIGNING FIELD-SYMBOL(<sym>) INDEX <mods>-row_id.
fill_celltab( EXPORTING p_fieldname = <mods>-fieldname
CHANGING pt_celltab = <sym>-celltab ).
MODIFY gt_outtab1 FROM <sym> INDEX <mods>-row_id.
ENDLOOP.
refresh_grid( ).
ENDMETHOD.
METHOD handle_data_changed_finished.
DATA: lt_celltab TYPE lvc_t_styl.
LOOP AT it_fldcat ASSIGNING FIELD-SYMBOL(<fs_fcat>).
IF sy-tabix MOD 2 = 0.
DATA(style) = cl_gui_alv_grid=>mc_style_disabled.
ELSE.
style = cl_gui_alv_grid=>mc_style_enabled.
ENDIF.
INSERT VALUE lvc_s_styl( style = style fieldname = <fs_fcat>-fieldname ) INTO TABLE lt_celltab.
ENDLOOP.
MODIFY gt_outtab1 FROM VALUE ty_tab( celltab = lt_celltab ) TRANSPORTING celltab WHERE connid IS NOT INITIAL.
refresh_grid( ).
ENDMETHOD.
METHOD create_dynamic_fcat.
lr_rtti_struc ?= cl_abap_structdescr=>describe_by_name( 'SPFLI' ).
DATA(comps) = lr_rtti_struc->components.
LOOP AT comps ASSIGNING FIELD-SYMBOL(<comps>).
IF sy-tabix MOD 2 = 0.
DATA(edit) = abap_false.
ELSE.
edit = abap_true.
ENDIF.
APPEND VALUE lvc_s_fcat( edit = edit fieldname = <comps>-name datatype = <comps>-type_kind inttype = <comps>-type_kind intlen = <comps>-length decimals = <comps>-decimals coltext = <comps>-name lowercase = 'X' ) TO it_fldcat .
ENDLOOP.
ENDMETHOD. "create_dynamic_fcat
METHOD populate_grid.
SELECT * UP TO 1000 ROWS
FROM spfli
INTO CORRESPONDING FIELDS OF TABLE gt_outtab1.
ENDMETHOD. "CHANGE_TITLE
METHOD display_grid.
create_dynamic_fcat( ).
grid1->set_table_for_first_display(
EXPORTING
is_layout = VALUE lvc_s_layo( zebra = abap_true stylefname = 'CELLTAB' )
CHANGING
it_outtab = gt_outtab1
it_fieldcatalog = it_fldcat ).
ENDMETHOD. "display_grid
METHOD refresh_grid.
cl_gui_cfw=>flush( ).
grid1->refresh_table_display( ).
ENDMETHOD.
ENDCLASS.
MODULE status_0100 OUTPUT.
SET PF-STATUS 'MAIN100'.
DATA: yalv TYPE REF TO zcl_alv_test.
CREATE OBJECT yalv.
yalv->populate_grid( ).
yalv->display_grid( ).
ENDMODULE.
MODULE user_command_0100 INPUT.
CASE sy-ucomm.
WHEN 'BACK' OR 'EXIT' OR 'RETURN'.
LEAVE PROGRAM.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
START-OF-SELECTION.
CALL SCREEN 100.
It uses the concept of cell styles, where each row in table is assigned a table of styles for each of the column in this row. There you can apply conditional attributes on a cell level, including editability.
When throwing an error through builtin checktables/domains, the grid is made not editable except erroneous cell, and when correcting the error, editability returns.

ALV data_changed with deleted rows

I want to access cell value in my ALV OOPS instance for a deleted row.
LOOP AT er_data_changed->mt_deleted_rows INTO ls_del.
CALL METHOD er_data_changed->get_cell_value
EXPORTING
i_row_id = ls_del-row_id
i_fieldname = 'FIPEX'
IMPORTING
e_value = lv-fipex.
ENDLOOP.
but lv-fipex is always blank. Why get_cell_value doesn't work with deleted rows? What can I use for this?
This method seems to return data only if you modify a particular cell or cells of a row. In order to achieve what you want read directly from the internal table used as CHANGING parameter in the call of method SET_TABLE_FOR_FIRST_DISPLAY. The actual deletion occurs after the event DATA_CHANGED so you can do that as the data to be deleted are still in the internal table.
Look at this example (you have to create the screen and status 100 by yourself).
REPORT ZZZ.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main,
on_data_changed FOR EVENT data_changed OF cl_gui_alv_grid
IMPORTING
er_data_changed,
on_double_click FOR EVENT double_click OF cl_gui_alv_grid
IMPORTING
es_row_no.
PRIVATE SECTION.
CLASS-DATA:
st_t000 TYPE STANDARD TABLE OF t000 WITH EMPTY KEY.
ENDCLASS.
MODULE status_0100 OUTPUT.
SET PF-STATUS '100'.
lcl_main=>main( ).
ENDMODULE.
MODULE user_command_0100 INPUT.
IF sy-ucomm = 'BACK'.
LEAVE TO SCREEN 0.
ENDIF.
ENDMODULE.
CLASS lcl_main IMPLEMENTATION.
METHOD on_double_click.
ASSERT 1 = 1.
ENDMETHOD.
METHOD on_data_changed.
DATA: l_value TYPE t000-ort01.
LOOP AT er_data_changed->mt_deleted_rows ASSIGNING FIELD-SYMBOL(<fs_deleted_row>).
* er_data_changed->get_cell_value(
* EXPORTING
* i_row_id = <fs_deleted_row>-row_id
* i_fieldname = 'ORT01'
* IMPORTING
* e_value = l_value
* ).
l_value = st_t000[ <fs_deleted_row>-row_id ]-ort01.
ENDLOOP.
ENDMETHOD.
METHOD main.
DATA(lo_gui_container) = NEW cl_gui_custom_container( container_name = 'CONTAINER' ).
DATA(lo_gui_alv_grid) = NEW cl_gui_alv_grid( i_parent = lo_gui_container ).
SELECT * FROM t000 INTO TABLE st_t000 UP TO 20 ROWS.
lo_gui_alv_grid->set_ready_for_input( 1 ).
SET HANDLER on_data_changed FOR lo_gui_alv_grid.
SET HANDLER on_double_click FOR lo_gui_alv_grid.
lo_gui_alv_grid->set_table_for_first_display(
EXPORTING
i_structure_name = 'T000'
CHANGING
it_outtab = st_t000
EXCEPTIONS
invalid_parameter_combination = 1
program_error = 2
too_many_lines = 3
OTHERS = 99
).
ASSERT sy-subrc = 0.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
CALL SCREEN 100.

Is it possible to add a user defined function to CL_SALV_TREE without copying GUI status?

Is it possible to add a user defined function to an instance of CL_SALV_TREE without copying GUI status to the report where this instance is used?
What I am trying to do is to add a custom function with add_function method.
REPORT zzy.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA: lt_table TYPE STANDARD TABLE OF t000.
TRY .
cl_salv_tree=>factory(
IMPORTING
r_salv_tree = DATA(lo_salv_tree)
CHANGING
t_table = lt_table
).
DATA(lo_salv_functions) = lo_salv_tree->get_functions( ).
lo_salv_functions->add_function(
name = 'EXPORT_TO_EXCEL'
icon = '#J2#'
tooltip = 'Export as Excel'
position = if_salv_c_function_position=>right_of_salv_functions
).
lo_salv_functions->set_all( abap_true ).
lo_salv_tree->display( ).
CATCH cx_salv_error.
ASSERT 0 = 1.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).
However the button does not appear.
I remember that I tried to do it some time ago with CL_SALV_TABLE and I got an explicit exception when using add_function.
What I tried back then was.
REPORT zzy.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA: lt_table TYPE STANDARD TABLE OF t000.
TRY .
cl_salv_table=>factory(
IMPORTING
r_salv_table = DATA(lo_salv_table)
CHANGING
t_table = lt_table
).
DATA(lo_salv_functions) = lo_salv_table->get_functions( ).
lo_salv_functions->add_function(
name = 'EXPORT_TO_EXCEL'
icon = '#J2#'
tooltip = 'Export as Excel file'
position = if_salv_c_function_position=>right_of_salv_functions
).
lo_salv_functions->set_all( abap_true ).
lo_salv_table->display( ).
CATCH cx_salv_error.
ASSERT 0 = 1.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).
It ends with a short dumped caused by unhandled exception CX_SALV_METHOD_NOT_SUPPORTED. What I see in the SAP standard code is
if lr_controller->r_model->get_display_object( )
ne IF_SALV_C_TABLE_OBJECTS=>GRID
and lr_controller->r_model->get_display_object( )
ne IF_SALV_C_TABLE_OBJECTS=>TREE.
text = text-001.
l_name = name.
raise exception type CX_SALV_METHOD_NOT_SUPPORTED
exporting class = 'CL_SALV_FUNCTIONS'
method = 'ENABLE_FUNCTION'
object = l_name
key = text.
endif.
From this piece of code one could suppose that it is possible to add a new function with add_function method for the object IF_SALV_C_TABLE_OBJECTS=>TREE.
So far I used the following workaround.
REPORT zzy.
CLASS lcl_controller DEFINITION FINAL.
PUBLIC SECTION.
INTERFACES:
if_salv_csqt_content_manager.
METHODS:
constructor.
DATA:
mo_salv_tree TYPE REF TO cl_salv_tree,
mt_table TYPE STANDARD TABLE OF t000.
ENDCLASS.
CLASS lcl_controller IMPLEMENTATION.
METHOD constructor.
CALL FUNCTION 'SALV_CSQT_CREATE_CONTAINER'
EXPORTING
r_content_manager = me
title = 'Workaround'.
ENDMETHOD.
METHOD if_salv_csqt_content_manager~fill_container_content.
TRY .
cl_salv_tree=>factory(
EXPORTING
r_container = r_container
IMPORTING
r_salv_tree = DATA(mo_salv_tree)
CHANGING
t_table = mt_table
).
DATA(lo_tree_settings) = mo_salv_tree->get_tree_settings( ).
lo_tree_settings->set_hierarchy_header( `Hierarchy` ).
lo_tree_settings->set_hierarchy_size( 30 ).
lo_tree_settings->set_header( |{ sy-title }| ).
DATA(lo_salv_functions) = mo_salv_tree->get_functions( ).
lo_salv_functions->add_function(
name = 'EXPORT_TO_EXCEL'
icon = '#J2#'
tooltip = 'Export as Excel file'
position = if_salv_c_function_position=>right_of_salv_functions
).
lo_salv_functions->set_all( abap_true ).
DATA(lo_salv_nodes) = mo_salv_tree->get_nodes( ).
DATA(lo_root) = lo_salv_nodes->add_node(
related_node = space
relationship = if_salv_c_node_relation=>last_child
data_row = VALUE t000( mandt = '100' )
text = `Test`
).
lo_salv_nodes->add_node(
related_node = lo_root->get_key( )
relationship = cl_gui_column_tree=>relat_last_child
data_row = VALUE t000( mandt = '200' )
text = `Test2`
).
mo_salv_tree->display( ).
CATCH cx_salv_error.
ASSERT 0 = 1.
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA(lo_controller) = NEW lcl_controller( ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).
Unfortunately the buttons appear in such case in a different location, directly before the tree and not in the status bar.
Short answer - no, you can't, you need a GUI Status (CUAD). You can hide functions at runtime, but you can't add new functions at runtime.