Thursday, 21 September 2017

ABAP News for Release 7.52 – Virtual Sorting of Internal Tables

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.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

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.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

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.

SAP ABAP Tutorials and Materials, SAP ABAP Certifications, SAP ABAP Guides

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.

No comments:

Post a Comment