Skip to Content
Technical Articles

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! )


You must be Logged on to comment or reply to a post.
  • 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


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

      • 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( ).
        • 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.

    • 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)

    • 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

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

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


  • 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( ).