Skip to Content
Technical Articles
Author's profile photo Joachim Rees

Easily display your internal table – Method display_data using cl_salv_table

In I hinted that I could write a blog about my display_data method.

This is it.

Some years ago, I discovered cl_salv_table – and I liked it a lot (compared to CL_GUI_ALV_GRID), as I didn’t have to care for a dynpro or a container.
Just give it your internal table and it will display it.

This is the simple call I have been using for that:

    DATA: lr_alv          TYPE REF TO cl_salv_table.
        CALL METHOD cl_salv_table=>factory
            list_display = if_salv_c_bool_sap=>false
            r_salv_table = lr_alv
            t_table      = ct_data.
      CATCH cx_salv_msg .
    CALL METHOD lr_alv->display.


But some ALV-functions (like export I think) where missing.

This is solved with:

lr_functions = lr_alv->get_functions( ).
lr_functions->set_all( abap_true ).

Still, a function that is often important to me, was missing: saving (and retrieving) layouts.

This can be achieved with:

lr_layout = lr_alv->get_layout( ).
ls_key-report = sy-repid.
lr_layout->set_key( ls_key ).
lr_layout->set_default( abap_true ).
lr_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).

With a little cleaning and writing things more compact, this is the current state of my display_data method:

  METHOD display_data.
        cl_salv_table=>factory( IMPORTING  salv_table   = data(alv)
                                CHANGING   table        = c_data  ).
      CATCH cx_salv_msg.

    alv->get_layout( )->set_key( VALUE #( report = sy-repid ) ).
    alv->get_layout( )->set_default( abap_true ).
    alv->get_layout( )->set_save_restriction( if_salv_c_layout=>restrict_none ).
    alv->get_functions( )->set_all( abap_true ).
    CALL METHOD alv->display.

What do you think?

Have I missed some features, I could also add?
Could I write things more compact / elegant? How?

Is cl_salv_table even still the latest / best tool for easy-ALV-like displaying of an already existing internal table?!
(Wording brought to you by trying exclude the “Just write a CDS-view and slap a fiori-elements list on top of it” 😉 .
CDS-view + fiori-elements list is actually great and I am using it – I just don’t want to discuss it here! )


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Jacques Nomssi Nzali
      Jacques Nomssi Nzali

      Could I write things more compact / elegant? How?

      Beware what you ask for.

      1. separate the creation of the ALV from the display. So create a method the generate an ALV an returns it, so that the caller can decide when to call the DISPLAY( ) method
      2. CALL METHOD is obsolete if not used in a dynamic context. It hurts my eyes 🙂
      3. CATCH cx_salv_msg.​ It is at the wrong place. If an error occurs, you will still have an exception while trying to access the alv object. So guard the whole code (move CATCH at the end). Better yet, propagate the Exception in the method signature, as you do not know how to handle it.
      4. method chaining can make sense here:
        lr_alv->get_functions( )->set_all( abap_true ).​

      my 2 cents


      Author's profile photo Shai Sinai
      Shai Sinai

      Regarding point 3,

      for the matter of fact, I advise not to catch the CX_SALV_MSG exception.

      This exception isn’t an expected one and shouldn’t occur in a productive program.

      I prefer that the users will run into a runtime error and report about it, than it will be caught by an empty TRY … CATCH block and no one will ever know about the problem.

      Author's profile photo Joachim Rees
      Joachim Rees
      Blog Post Author

      I kind of get your point, and I tried it out, but I can't stand to get a warning from Syntax-Check (not from ATC, from the actual syntax-check). Is there any way (Pragma or something) around that?

      Btw. Report SALV_DEMO_TABLE_SIMPLE does it like me:
      (I probably took the code from there)

      form display_fullscreen .
      *... Dz create an ALV table
      *    Dz.2 just create an instance and do not set LIST_DISPLAY for
      *         displaying the data as a Fullscreen Grid
                r_salv_table = gr_table
                t_table      = gt_outtab ).
          catch cx_salv_msg.                                  "#EC NO_HANDLER
      *... dz Functions
      *... dz.1 activate ALV generic Functions
        data: lr_functions type ref to cl_salv_functions_list.
        lr_functions = gr_table->get_functions( ).
      Author's profile photo Shai Sinai
      Shai Sinai

      As far as I know, I'm afraid it isn't possible to suppress these warnings.

      In my opinion, these exceptions were created with incorrect exception category by SAP.


      As a workaround, you can always declare explicitly the exception (RAISING cx_salv_msg) without catching it in the caller, but I'm not sure it's a better approach.

      Author's profile photo Joachim Rees
      Joachim Rees
      Blog Post Author

      Thanks for your feedback, Jacques!

      Let me go through it:

      1. The idea of the display_data-method (part of all my reports) is, that I can put in an internal table and have it displayed on ALV. If I don't wan't that I will just not call it (and the have no need to have the ALV generated).
      2. I agree! (also on the eye-hurting - I have that with empty lines, too!)
      3. as I see, discussion is still going on! Thanks for all your input.
      4. I agree! (and in the last code block, showing the full method, I already used it)

      Author's profile photo Michael Keller
      Michael Keller

      Beware what you ask for.” I’m now in fear publishing my next blog, Jacques. I should better don’t ask for improvements 😉 Somehow it reminds me on 64k demo competition. More compact, more demo.

      However, it should of course remain readable/maintainable. Demos may be a poor comparison to applications that have been used for 20 years or more.

      Best regards

      Author's profile photo Florian Henninger
      Florian Henninger

      As the SALV-Table doesn't support drag and drop it's always a nogo for me personally. Love to have all enhancing options if there is a time I need it.

      But also have to say, it's a while ago when using such things as for new applications I use other stuff and for existing applications there is more or less never the need to put a newly ALV into.

      Author's profile photo Paul Hardy
      Paul Hardy

      In the end the users always ask to make some fields editable. The CL_SALV_TABLE just cannot do that properly. There are lots of workarounds, but in the end that is what makes CL_GUI_ALV_GRID better, as it does it naturally.

      After years of trying to get CL_SALV_TABLE to do what I want, I would say the best way is to let CL_SALV_TABLE do the one thing it is really good at which CL_GUI_ALV_GRUD cannot do - creating the field catalogue from the internal table, and then passing the result to CL_GUI_ALV_GRID and go from there.

      The best result of course would be for SAP to bring CL_SALV_TABLE up to functional parity with CL_GUI_ALV_GRID but it has been over ten years now, so that's never going to happen.


      Author's profile photo Margaret Kreytak
      Margaret Kreytak

      I agree.  I now use CL_SALV_TABLE only to create the field catalog and I use CL_GUI_ALV_GRID for everything else.

      Author's profile photo Joachim Rees
      Joachim Rees
      Blog Post Author

      I don't want to edit around in the original posts coding to keep references intact, so taking your feedback into account, this is how it could look like:

        METHOD display_data.
              cl_salv_table=>factory( IMPORTING  salv_table   = data(alv)
                                      CHANGING   table        = c_data  ).
          alv->get_layout( )->set_key( VALUE #( report = sy-repid ) ).
          alv->get_layout( )->set_default( abap_true ).
          alv->get_layout( )->set_save_restriction( if_salv_c_layout=>restrict_none ).
          alv->get_functions( )->set_all( abap_true ).
          alv->display( ).
      Author's profile photo Joachim Rees
      Joachim Rees

      I am not putting much thought into it nowadays,nevertheless I feel like sharing my current version of display_data.This is my ADT-Template I can easily pull in whenever I need it:


      • First line is the definition, which I move to the appropriate place
      • Seems I decided to add try/catch (probably due to ATC nagging otherwise)
      • the lr_ an ct_ is due to rules I dont controll, i guess.
      *METHODS: display_data CHANGING ct_data TYPE any table. 
        METHOD display_data.
              cl_salv_table=>factory( IMPORTING  r_salv_table   = data(lr_alv)
                                      CHANGING   t_table        = ct_data  ).
            CATCH cx_salv_msg ##NO_HANDLER.
          lr_alv->get_layout( )->set_key( VALUE #( report = sy-repid ) ).
          lr_alv->get_layout( )->set_default( abap_true ).
          lr_alv->get_layout( )->set_save_restriction( if_salv_c_layout=>restrict_none ).
          lr_alv->get_functions( )->set_all( abap_true ).
          lr_alv->display( ).
      Author's profile photo lenin quispe
      lenin quispe


      Author's profile photo Vijay kumar
      Vijay kumar

      Any one know how to HIDE Grad total  value using cl_salv_table method.? (Like - gs_layout-notataline = 'X' in REUSE_ALV)

      I think couple of unique options are not possible in this method, comparing REUSE_ALV_GRID_DISPLAY.