2016 Oct 13 11:27 AM
Hello dear colleagues,
I try to allow users to switch ALV layout (and gui status) in one click on a button from ALV screen.
I use cl_salv_table and everything is fine doing standard actions manually : click on &OAD button, select a variant layout in the list (/DETAILED_VUE or /SIMPLE_VUE), apply it (and screen auto-refresh). I have created some dynamic buttons to allow users to switch status gui (it changes buttons labels and restrict some actions).
My wish is to change layout used in the same time the status gui is changed.
I know I can do that "hard coding" (depending on DETAILED or SIMPLE mode) what columns to be displayed (cl_salv_column_table=>set_visible, cl_salv_columns=>set_column_position), what filters to add or remove (cl_salv_filter=>add_filter) . But it will require an inelegant ABAP maintenance for future minor changes. ^_^
I tryed several ways (macro simulating opening popup and clicking on list with BDC_OKCODE =&OAD, CL_SALV_CONTROLLER_METADATA=>SET_VARIANT, cl_salv_layout=>set_initial_layout, ...) but none works.
Do you have any ideas? How can I apply at will a dynamic layout content from ALV screen?
Best regards
2016 Nov 16 10:56 AM
Bertrand, see my working sample below :
REPORT ztmp_testreport.
DATA:
container TYPE REF TO cl_gui_custom_container,
grid TYPE REF TO cl_gui_alv_grid,
it_display TYPE TABLE OF mara,
wa_display TYPE mara,
gv_variant TYPE slis_vari.
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
DATA wa_toolbar TYPE stb_button.
METHODS: toolbar_handle FOR EVENT toolbar OF cl_gui_alv_grid
IMPORTING e_object
e_interactive,
menu_bt_handle FOR EVENT menu_button OF cl_gui_alv_grid
IMPORTING e_object
e_ucomm,
ucomm_handle FOR EVENT user_command OF cl_gui_alv_grid
IMPORTING e_ucomm.
ENDCLASS. "lcl_event_handler DEFINITION
CLASS lcl_event_handler IMPLEMENTATION.
METHOD toolbar_handle.
MOVE 3 TO wa_toolbar-butn_type.
APPEND wa_toolbar TO e_object->mt_toolbar.
MOVE : 2 TO wa_toolbar-butn_type,
'Select Layout' TO wa_toolbar-text,
'$MENU' TO wa_toolbar-function,
'@0R@' TO wa_toolbar-icon,
'Layouts' TO wa_toolbar-quickinfo.
APPEND wa_toolbar TO e_object->mt_toolbar.
ENDMETHOD. "toolbar_handle
METHOD menu_bt_handle.
IF e_ucomm = '$MENU'.
*---> Read from Config or Z-tab with your Layouts
* LOOP AT ztab ASSIGNING FIELD-SYMBOL(<zline>).
* CALL METHOD e_object->add_function
* EXPORTING
* fcode = <zline>-fcode
* text = <zline>-layout_id.
* ENDLOOP.
* UNASSIGN <zline>.
*---> No ZTAB, so just fill as a DEMO
CALL METHOD e_object->add_function
EXPORTING
fcode = 'Z1'
text = 'ZLAY1'.
CALL METHOD e_object->add_function
EXPORTING
fcode = 'Z2'
text = 'ZLAY2'.
ENDIF.
ENDMETHOD. "menu_bt_handle
METHOD ucomm_handle.
CHECK e_ucomm IS NOT INITIAL.
*---> Read from Config or Z-tab with E_UCOMM
* lv_fcode = e_ucomm.
* READ TABLE ztab ASSIGNING FIELD-SYMBOL(<zline>)
* WITH KEY fcode = lv_fcode.
* IF sy-subrc = 0.
* gv_variant = <zline>-text.
* PERFORM create_objects.
* ENDIF.
* UNASSIGN <zline>.
*---> As a DEMO
CASE e_ucomm.
WHEN 'Z1'.
gv_variant = 'ZLAY1'.
WHEN 'Z2'.
gv_variant = 'ZLAY2'.
ENDCASE.
PERFORM create_objects. "RE-CREATE Grid with GV_VARIANT as new LAYOUT
ENDMETHOD. "ucomm_handle
ENDCLASS. "lcl_event_handler IMPLEMENTATION
DATA event TYPE REF TO lcl_event_handler.
INITIALIZATION.
CLEAR gv_variant.
START-OF-SELECTION.
CALL SCREEN 100.
MODULE status_0100 OUTPUT.
SET PF-STATUS 'STANDARD'.
PERFORM build_it_display.
PERFORM create_objects.
ENDMODULE. " STATUS_0100 OUTPUT
MODULE user_command_0100 INPUT.
CASE sy-ucomm.
WHEN 'BACK'.
SET SCREEN 0.
LEAVE SCREEN.
WHEN 'EXIT'.
SET SCREEN 0.
LEAVE SCREEN.
WHEN 'CANC'.
SET SCREEN 0.
LEAVE SCREEN.
ENDCASE.
ENDMODULE. " USER_COMMAND_0100 INPUT
FORM build_it_display.
SELECT * FROM mara UP TO 15 ROWS INTO TABLE it_display.
ENDFORM. " build_it_display
FORM create_objects.
*---> SET THE LAYOUT
DATA variant TYPE disvariant.
variant-report = sy-repid.
variant-variant = gv_variant.
IF container IS INITIAL.
CREATE OBJECT container
EXPORTING
container_name = 'CUSTOM'.
CREATE OBJECT event.
CREATE OBJECT grid
EXPORTING
i_parent = container.
SET HANDLER event->toolbar_handle FOR grid.
SET HANDLER event->menu_bt_handle FOR grid.
SET HANDLER event->ucomm_handle FOR grid.
ENDIF.
CALL METHOD grid->set_table_for_first_display
EXPORTING
i_structure_name = 'MARA'
is_variant = variant "SET LAYOUT
i_save = 'A' "ENABLE SAVE LAYOUT
CHANGING
it_outtab = it_display.
cl_gui_cfw=>flush( ).
ENDFORM. " create_objects
This is probably not the best sample to promote Good Practices (OO + FORM-routines, Global VAR's, Refresh-method absent, no CL_SALV_TABLE, etc.), but it does the trick ...
I created 2 Layouts 'ZLAY1' / 'ZLAY2' and they are used when Selected from the Menu Drop-Down.
So the 'USER_COMMAND' event for the 'CL_GUI_ALV_GRID' can be used.
Hope this is useful as a Demo ...
Kind regards
Nic T.
2016 Nov 02 4:08 PM
Hello There, I don't get your question fully. Do you want to get the layout or Save the layout? Do you want to save the layout automatically? or anything else?
Regards.
2016 Nov 09 4:08 PM
Hello Naimesh,
First of all, I thank you for your interest. I apology for my delay to answer (I didn't received any notification by mail, that's annoying). Well, my wish is to load an existing layout in just 1 click.
Several layouts have been created with the report and each one do emphasis (by sorting and changing columns displayed) on something to notice about this data.
The problem is : when users want to switch from one vue to one another they have to : click on ALV standard button to list layouts, find the one they want in a list containing custom and default layout, and double-click on it.
I would like to allow them to click on some "Use this layout>" buttons from ALV screen.
Best regards and many thanks 🙂
2016 Nov 09 10:03 PM
Hello Bertrand
I haven't done this myself, but I do remember some posts where people examined the possibility of a custom 'GOS'-like dropdown either on a PF-STATUS or on the (S)ALV-Toolbar. So I went searching for it and found these references :
In any case, you could determine the number of entries via a Custom Table in which the TOP-Layouts were maintained? That would avoid code-changes when the list needs adjusting ...
Hope this helps in determining whether the requirement is worth the effort ...
Kind regards
Nic T.
2016 Nov 14 2:18 PM
Hello Nic,
I thank you for your help. As add a dropdown list in ALV tool bar seems a nice functionality, I don't think it could help me to solve my problem. Or do I miss a useful function in source codes in links?
Best regards
2016 Nov 14 3:26 PM
Hi Betrand,
Well I just (shamelessly) copied the code from the 2nd Resource and made some Text-adjustements. In that adjustement, I kind of simulated reading the Configuration of <X>-layouts you want in a Dropdown list for rapid-modification of the ALV-Output :
... looks something like this ...
That could work, or am I mistaken?
When a change from one Layout to another is Selected, you can receive the Event and Handle it appropriately, that is, change your Layout and Refresh the ALV-Display with the new Layout ...
2016 Nov 14 5:25 PM
2016 Nov 14 7:01 PM
2016 Nov 16 9:37 AM
Hello Nic,
I thank you again for your help.
When you write "[Click on the list will] change your Layout and Refresh the ALV-Display with the new Layout", that's exactly what I'm not able to do. How do you manage this?
I guess I could create an event with layout id in attribute and raise it. And it will be catch by standard "layout change" listener.
But which sort of event ?
2016 Nov 16 10:56 AM
Bertrand, see my working sample below :
REPORT ztmp_testreport.
DATA:
container TYPE REF TO cl_gui_custom_container,
grid TYPE REF TO cl_gui_alv_grid,
it_display TYPE TABLE OF mara,
wa_display TYPE mara,
gv_variant TYPE slis_vari.
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
DATA wa_toolbar TYPE stb_button.
METHODS: toolbar_handle FOR EVENT toolbar OF cl_gui_alv_grid
IMPORTING e_object
e_interactive,
menu_bt_handle FOR EVENT menu_button OF cl_gui_alv_grid
IMPORTING e_object
e_ucomm,
ucomm_handle FOR EVENT user_command OF cl_gui_alv_grid
IMPORTING e_ucomm.
ENDCLASS. "lcl_event_handler DEFINITION
CLASS lcl_event_handler IMPLEMENTATION.
METHOD toolbar_handle.
MOVE 3 TO wa_toolbar-butn_type.
APPEND wa_toolbar TO e_object->mt_toolbar.
MOVE : 2 TO wa_toolbar-butn_type,
'Select Layout' TO wa_toolbar-text,
'$MENU' TO wa_toolbar-function,
'@0R@' TO wa_toolbar-icon,
'Layouts' TO wa_toolbar-quickinfo.
APPEND wa_toolbar TO e_object->mt_toolbar.
ENDMETHOD. "toolbar_handle
METHOD menu_bt_handle.
IF e_ucomm = '$MENU'.
*---> Read from Config or Z-tab with your Layouts
* LOOP AT ztab ASSIGNING FIELD-SYMBOL(<zline>).
* CALL METHOD e_object->add_function
* EXPORTING
* fcode = <zline>-fcode
* text = <zline>-layout_id.
* ENDLOOP.
* UNASSIGN <zline>.
*---> No ZTAB, so just fill as a DEMO
CALL METHOD e_object->add_function
EXPORTING
fcode = 'Z1'
text = 'ZLAY1'.
CALL METHOD e_object->add_function
EXPORTING
fcode = 'Z2'
text = 'ZLAY2'.
ENDIF.
ENDMETHOD. "menu_bt_handle
METHOD ucomm_handle.
CHECK e_ucomm IS NOT INITIAL.
*---> Read from Config or Z-tab with E_UCOMM
* lv_fcode = e_ucomm.
* READ TABLE ztab ASSIGNING FIELD-SYMBOL(<zline>)
* WITH KEY fcode = lv_fcode.
* IF sy-subrc = 0.
* gv_variant = <zline>-text.
* PERFORM create_objects.
* ENDIF.
* UNASSIGN <zline>.
*---> As a DEMO
CASE e_ucomm.
WHEN 'Z1'.
gv_variant = 'ZLAY1'.
WHEN 'Z2'.
gv_variant = 'ZLAY2'.
ENDCASE.
PERFORM create_objects. "RE-CREATE Grid with GV_VARIANT as new LAYOUT
ENDMETHOD. "ucomm_handle
ENDCLASS. "lcl_event_handler IMPLEMENTATION
DATA event TYPE REF TO lcl_event_handler.
INITIALIZATION.
CLEAR gv_variant.
START-OF-SELECTION.
CALL SCREEN 100.
MODULE status_0100 OUTPUT.
SET PF-STATUS 'STANDARD'.
PERFORM build_it_display.
PERFORM create_objects.
ENDMODULE. " STATUS_0100 OUTPUT
MODULE user_command_0100 INPUT.
CASE sy-ucomm.
WHEN 'BACK'.
SET SCREEN 0.
LEAVE SCREEN.
WHEN 'EXIT'.
SET SCREEN 0.
LEAVE SCREEN.
WHEN 'CANC'.
SET SCREEN 0.
LEAVE SCREEN.
ENDCASE.
ENDMODULE. " USER_COMMAND_0100 INPUT
FORM build_it_display.
SELECT * FROM mara UP TO 15 ROWS INTO TABLE it_display.
ENDFORM. " build_it_display
FORM create_objects.
*---> SET THE LAYOUT
DATA variant TYPE disvariant.
variant-report = sy-repid.
variant-variant = gv_variant.
IF container IS INITIAL.
CREATE OBJECT container
EXPORTING
container_name = 'CUSTOM'.
CREATE OBJECT event.
CREATE OBJECT grid
EXPORTING
i_parent = container.
SET HANDLER event->toolbar_handle FOR grid.
SET HANDLER event->menu_bt_handle FOR grid.
SET HANDLER event->ucomm_handle FOR grid.
ENDIF.
CALL METHOD grid->set_table_for_first_display
EXPORTING
i_structure_name = 'MARA'
is_variant = variant "SET LAYOUT
i_save = 'A' "ENABLE SAVE LAYOUT
CHANGING
it_outtab = it_display.
cl_gui_cfw=>flush( ).
ENDFORM. " create_objects
This is probably not the best sample to promote Good Practices (OO + FORM-routines, Global VAR's, Refresh-method absent, no CL_SALV_TABLE, etc.), but it does the trick ...
I created 2 Layouts 'ZLAY1' / 'ZLAY2' and they are used when Selected from the Menu Drop-Down.
So the 'USER_COMMAND' event for the 'CL_GUI_ALV_GRID' can be used.
Hope this is useful as a Demo ...
Kind regards
Nic T.
2016 Nov 16 1:50 PM
Ok, I understand now.
In fact, the problem is that I used cl_salv_table while your solution is based on cl_gui_alv_grid. It seems a lot more easier with this object with its method "set_table_for_first_display". ^_^
I understand why your answer imply that is an easy thing to do.
Many thanks Nic!
(I try to accept your answer but it seems I don't have enough rights to do so)