Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

SALV : Load and change saved layout from ALV screen in one click

bertrand_delvallee
Active Participant
6,640

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

1 ACCEPTED SOLUTION

NTeunckens
Active Contributor
2,340

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.

10 REPLIES 10

naimesh_patel
Active Contributor
0 Kudos
2,340

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.

bertrand_delvallee
Active Participant
0 Kudos
2,340

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 🙂

NTeunckens
Active Contributor
0 Kudos
2,340

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.

0 Kudos
2,340

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

NTeunckens
Active Contributor
0 Kudos
2,340

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 :

  • Use a Z-table with multiple Layouts you want for 'Rapid Selection' ;
  • Copy Standard-Toolbar but added a Custom Button with 'Layouts'-Icon and Custom Description ;
  • Populate (all or a Subset via Z-table of) Layouts as Drop-Down Values ...


... 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 ...

0 Kudos
2,340

I can't see the picture...

2,340

Something went wrong in the upload of the picture ...

So here it is again?

0 Kudos
2,340

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 ?

NTeunckens
Active Contributor
2,341

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.

0 Kudos
2,340

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)