Skip to Content

SAP NetWeaver AS for ABAP 7.52 is available now.

It is mainly a “major step on the way to efficient development of SAP HANA optimized SAP Fiori apps is the use of the new RESTful ABAP programming model which includes technologies such as CDS, Business Object Processing Framework (BOPF), SAP Gateway and SAPUI5.”

But there are some news in the ABAP language too.

One of those is virtual sorting of internal tables.

Virtual Sorting of Internal Tables

There is a new method VIRTUAL_SORT of class CL_ABAP_ITAB_UTILITIES. With that method, you can virtually sort a set of internal tables. The internal tables of such a set must contain the same number of lines. The method VIRTUAL_SORT treats the set of internal tables as one combined table containing all the columns of the involved internal tables. It sorts that virtual combined table ascending or descending by the columns whose names are passed to the method and returns an array of line numbers of the virtually sorted combined table. This allows you to sort internal tables without changing the order of lines of the internal tables itself, e.g. to generate various sorted output data without affecting the original data.

Step by Step

Let me show it to you in a step by step example.

First, we create some example data in three internal tables.

TYPES:
  BEGIN OF flight,
    carrid   TYPE s_carr_id,
    connid   TYPE s_conn_id,
    cityfrom TYPE s_city,
    cityto   TYPE s_city,
  END OF flight,
  flights TYPE STANDARD TABLE OF flight
          WITH EMPTY KEY,
  BEGIN OF city,
    city      TYPE  s_city,
    latitude  TYPE  s_lati,
    longitude TYPE  s_long,
  END OF city,
  cities TYPE STANDARD TABLE OF city
              WITH EMPTY KEY.
DATA:
  flight_tab    TYPE flights,
  from_city_tab TYPE cities,
  to_city_tab   TYPE cities.


SELECT carrid, connid, cityfrom, cityto
       FROM spfli
       INTO CORRESPONDING FIELDS OF TABLE @flight_tab.

SELECT city, latitude, longitude
       FROM sgeocity
       INTO TABLE @DATA(cities).

TRY.
    from_city_tab = VALUE #( FOR <fs> IN flight_tab
                             ( cities[ city = <fs>-cityfrom ] ) ).
    to_city_tab   = VALUE #( FOR <fs> IN flight_tab
                             ( cities[ city = <fs>-cityto ] ) ).
  CATCH cx_sy_itab_line_not_found.
    MESSAGE 'Flight model data not consistent,' &&
            ' use program SAPBC_DATA_GENERATOR' &&
            ' to create the data.' TYPE 'X'.
ENDTRY.

There is an internal table flight_tab containing flight data. Two additional tables from_city_tab and to_city_tab are constructed with lines containing the longitudes and latitudes of the departure and arrival cities from the respective lines of flight_tab.

Let’s sort the flight data virtually by the longitudes and latitudes of the departure and arrival cities, ascending and descending:

DATA(sort_asc) = cl_abap_itab_utilities=>virtual_sort(
                   im_virtual_source =
                     VALUE #(
                       ( source     = REF #( from_city_tab )
                         components =
                           VALUE #( ( name = 'latitude' )
                                    ( name = 'longitude' ) ) )
                       ( source     = REF #( to_city_tab )
                         components =
                           VALUE #( ( name = 'latitude' )
                                    ( name = 'longitude' ) ) )
                       ( source     = REF #( flight_tab )
                         components =
                           VALUE #( ( name = 'carrid' )
                                    ( name = 'connid' ) ) ) ) ).

cl_demo_output=>display( sort_asc ).

DATA(sort_desc) = cl_abap_itab_utilities=>virtual_sort(
                   im_virtual_source =
                     VALUE #(
                       ( source     = REF #( from_city_tab )
                         components =
                           VALUE #( ( name = 'latitude'
                                      descending = abap_true )
                                    ( name = 'longitude'
                                      descending = abap_true ) ) )
                       ( source     = REF #( to_city_tab )
                         components =
                           VALUE #( ( name = 'latitude'
                                      descending = abap_true )
                                    ( name = 'longitude'
                                      descending = abap_true ) ) )
                       ( source     = REF #( flight_tab )
                         components =
                           VALUE #( ( name = 'carrid' )
                                    ( name = 'connid' ) ) ) ) ).
cl_demo_output=>display( sort_desc ).

The virtual sorting involves all three internal tables.We simply pass references to the internal tables, the names of the columns used for sorting, and the sort order to method cl_abap_itab_utilities=>virtual_sort. The results are arrays of the line numbers resulting from the ascending and descending sortings.

Normally, you do not want to look at these values, but use them for constructing an output:

DATA sorted_tab TYPE flights.

LOOP AT sort_asc ASSIGNING FIELD-SYMBOL(<idx>).
  APPEND flight_tab[ <idx> ] TO sorted_tab.
ENDLOOP.

cl_demo_output=>display( sorted_tab ).

CLEAR sorted_tab.
LOOP AT sort_desc ASSIGNING <idx>.
  APPEND flight_tab[ <idx> ] TO sorted_tab.
ENDLOOP.

cl_demo_output=>display( sorted_tab ).

You see the flight data sorted ascending and descending by the longitudes and latitudes of the departure and arrival cities.

If you don’t need the data later, declaring and filling an explicit helper table sorted_tab is not necessary in modern times. Therefore, let’s put it together.

Putting it Together

The following coding shows the same virtual sorting as above in one single statement.

cl_demo_output=>new(

  )->next_section(
  `Ascending Sort by Latitude, Longitude of CITYFROM, CITYTO`

  )->write( VALUE flights(
              FOR <idx>
              IN cl_abap_itab_utilities=>virtual_sort(
                   im_virtual_source =
                     VALUE #(
                       ( source     = REF #( from_city_tab )
                         components =
                           VALUE #( ( name = 'latitude' )
                                    ( name = 'longitude' ) ) )
                       ( source     = REF #( to_city_tab )
                         components =
                           VALUE #( ( name = 'latitude' )
                                    ( name = 'longitude' ) ) )
                       ( source     = REF #( flight_tab )
                         components =
                           VALUE #( ( name = 'carrid' )
                                    ( name = 'connid' ) ) ) ) )
              ( flight_tab[ <idx> ] ) )

  )->next_section(
  `Descending Sort by Latitude, Longitude of CITYFROM, CITYTO`

  )->write( VALUE flights(
              FOR <idx>
              IN cl_abap_itab_utilities=>virtual_sort(
                   im_virtual_source =
                     VALUE #(
                       ( source     = REF #( from_city_tab )
                         components =
                           VALUE #( ( name = 'latitude'
                                      descending = abap_true )
                                    ( name = 'longitude'
                                      descending = abap_true ) ) )
                       ( source     = REF #( to_city_tab )
                         components =
                           VALUE #( ( name = 'latitude'
                                      descending = abap_true )
                                    ( name = 'longitude'
                                      descending = abap_true ) ) )
                       ( source     = REF #( flight_tab )
                         components =
                           VALUE #( ( name = 'carrid' )
                                    ( name = 'connid' ) ) ) ) )
              ( flight_tab[ <idx> ] ) )

  )->display( ).

Now the virtual sorting with the method VIRTUAL_SORT of class CL_ABAP_ITAB_UTILITIES takes place at the operand position of a FOR expression for a table iteration. The temporary result of the sorting is used to construct a sorted internal table from the lines of flight_tab. This table is also only temporary and is an input parameter of the method WRITE of class CL_DEMO_OUTPUT.

The sorting in ascending order and in descending order does not change the order of the lines in the internal tables that are involved. These remain in their original unsorted state.

Bottom Line

Virtual sorting makes it possible to generate various sorted output data without affecting the original data.

 

 

To report this post you need to login first.

12 Comments

You must be Logged on to comment or reply to a post.

  1. Raphael Pacheco

    Hmmm, this looks good, waiting for download this version and test it (also to know more about 7.52) 🙂

    About performance, what change for us using this new statment?

    BR,

    Raphael Pacheco.

    (0) 
  2. Michelle Crapo

    Hi Horst,

    I love this!!!   Now I have to bookmark it for the future.   It seems like I’ve been doing that a lot lately.

    Teched information and year – it tends to blur if you’ve been to a lot of them.  I just remember some of the good information shared.   And if I’m trying something new – I tend to look up to see if it was covered in one of the techeds – or – I bookmarked it.

    So I can’t use it now, but will in the future.

    Thank you!

    Michelle

    (0) 
  3. Paul Hardy

    Is anyone at SAP going to say explicitly that ABAP 7.50 is the final release for ECC 6.0?

    My guess is that if SAP keep making ECC 6.0 better, that reduces the incentive to go to S/4 HANA….

     

    (0) 
  4. Daniel Gent

    Interesting, I hope I’ll remember this post when the time comes and I could need this. But if I understand it correctly, i could also use this method to use a “virtually” sorted version of a single internal table somewhere within another expression.

    (0) 

Leave a Reply