Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
New vs. Old ABAP Table Summarizing

 

Introduction

 

In this blog series, the goal is to focus on comparing older ABAP language features with a detailed explanation of the new ABAP syntax.

 

I recently wrote a program to explain older and newer ways to do a summary on an internal table. This blog will dissect that program. We will show the various ways to accomplish the same thing for a table summary, and how the ABAP language has evolved over the years. This blog will be useful for both new ABAPers, as well as experienced ABAPers trying to get familiar with the new ABAP.

 

This Blog is organized as follows:

  1. Program Overview

    1. Radio Button Options

    2. Record Generator



  2. Table Processing Options

    1. Standard Table

    2. Sorted Table

    3. New ABAP



  3. Performance

  4. Complete Program

  5. References


 

Software Versions:

  • 7.52 of SAP, SAPGUI Version 750.

  • Eclipse Version: Oxygen.1a Release (4.7.1a)


 

Program Overview

 

The program will have the following select options:



The program will perform the following steps:

  1. Take the “Number of Records” field from the selection screen and generate a table of sample records.

  2. Process the table according to the selected Radio Button option.

  3. Display the resulting summary table in ALV.


Newer ABAP supports method chaining, so to run the program, we simply do the following at START-OF-SELECTION:
START-OF-SELECTION.
lcl_my_class=>main( )->execute( ).

Broken into parts:

  • lcl_my_class=>main( ) – Instantiates a new instance of LCL_MY_CLASS. This is a static factory method, which simply returns an instance of itself.

  • execute( ) – All of the main logic is contained in the EXECUTE method of LCL_MY_CLASS.


 

Radio button Options

  1. Standard Table: With this option, we will show the old school method for performing a summary by sorting and collecting.

  2. Sorted Table: With this option, we will do a read on a sorted table, then update the summary field using a field symbol.

  3. New ABAP: With this option, we will utilize the new ABAP language features to update the records and increment the summary field.


All 3 options, above, will perform the same logic, described below, but with different table reads and updates.

Here is an overview of what the 3 methods will do:



You may have guessed, this simply doubles the value in SUMMARY_FIELD, since the table was cloned from the original.

Example:

IT_TEST_TABLE, passed into the method (unsorted):



Resulting ALV (sorted by keys), after adding the temporary tables. Simply doubles the SumField (SUMMARY_FIELD):



When executing each of the 3 options, the results will be identical to the above.

 

Record Generator

All 3 of the above methods will use the following generated sample table. We will use the new ABAP features to create the random records with the following method lm_build_records:
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_build_records: Build a table with nn records...
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_build_records.
DO p_recs TIMES.
APPEND VALUE lty_struct( key1 = 900 + sy-index
key2 = sy-index
field1 = |A Text Field - { sy-index }|
a_date_field = sy-datum + sy-index
summary_field = sy-index * 10 )
TO et_test_table.
ENDDO.
ENDMETHOD. " lm_build_records

The parameter p_recs is the “Number of Records” field on the selection screen. To further explain the above new ABAP code, here is how the random records are generated…

We will loop and create P_RECS number of records.

For each loop pass, it will dynamically generate a new record of type LTY_STRUCT. No intermediate variables needed with the new ABAP.

VALUE lty_struct(…) – This tells the compiler to generate a new record of type LTY_STRUCT. This structure was declared in our private global section for our class:
  PRIVATE SECTION.
TYPES: BEGIN OF lty_struct,
key1 TYPE matnr,
key2 TYPE rsrnumc10,
field1 TYPE string,
a_date_field TYPE sydatum,
summary_field TYPE i,
END OF lty_struct,
lty_tab TYPE STANDARD TABLE OF lty_struct,
lty_stab TYPE SORTED TABLE OF lty_struct WITH UNIQUE KEY key1 key2.

This will randomly generate the following values for the fields:

  • KEY1 – Take 900 plus the current loop pass number contained in SY-INDEX (i.e. 901, 902, etc.)

  • KEY2 – The current loop pass contained in SY-INDEX.

  • FIELD1 – The text “A Text Field”, plus the current loop pass number in SY-INDEX. The new string templates in the new ABAP, generates the exact string contained within the Pipe (|) symbols (no more CONCATENATE statement needed!). Also, within your string, you can dynamically specify a variable within your string within curly braces {}. So, |A Text Field – { sy-index }| will be “A Text Field – 1” on the first loop pass.

  • A_DATE_FIELD – Take today’s date and add the current loop pass number (SY-INDEX) in days.

  • SUMMARY_FIELD – Take the current loop pass multiplied by 10.


After this record is generated, it is appended to ET_TEST_TABLE, an export table parameter for the method.

 

Now, on to the table code…

 

Table Processing Options

 

Standard Table

The COLLECT statement was one original ABAP statement for adding numeric fields together in an internal table. If summarizing a standard table with no keys, it will compare all non-numeric fields, and will sum the numeric field. In our case, we have the following structure:
    TYPES: BEGIN OF lty_struct,
key1 TYPE matnr,
key2 TYPE rsrnumc10,
field1 TYPE string,
a_date_field TYPE sydatum,
summary_field TYPE i,
END OF lty_struct,

Because SUMMARY_FIELD is our only numeric field, it will sum those values.

Example:

Table 1:



Table 2:



If adding the above 2 identical tables together with the COLLECT statement, it will give the following:

Summary Table:



Logic for the above results:
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_process_standard_table: Pre-740 Method to process a
* standard table.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_process_standard_table.
DATA: lt_temp_table TYPE lty_tab,
lt_sum_table TYPE lty_tab,
lw_rec TYPE lty_struct.
lt_temp_table[] = it_test_table[].
lt_sum_table[] = it_test_table[].
SORT lt_temp_table BY key1 key2.
SORT lt_sum_table BY key1 key2.

"This will double the summary_field entries...
LOOP AT lt_temp_table INTO lw_rec.
COLLECT lw_rec INTO lt_sum_table.
ENDLOOP.
lm_display( CHANGING ct_report = lt_sum_table ).
ENDMETHOD. " lm_process_standard_table

The above code for a Standard Table was a classical way of performing a summary, and should work in most older SAP versions. Of course, what if you have 2 numeric fields, but you only want to add up one of them? Let’s say we add an additional numeric field at the end, that we do not want to summarize. For example, let’s add a field named DO_NOT_ADD, which is also an integer:

Table 1:



Table 2:



Summary Table:



If we only wanted to add together the field SUMMARY_FIELD, then this would require a read and update of that record, and the COLLECT statement would not work. In this case, a Sorted Table or Hashed Table would be a good candidate to handle a fast read and update of existing records in an internal table.

 

Sorted Table

In this example, we will update a specific field, and summarize it by reading the record from a Sorted Table.

 

The code for a Sorted Table summary, to achieve the same results as the Standard Table example:
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_process_sorted_table: Pre-740 Logic to process a
* sorted table.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_process_sorted_table.
DATA: lt_temp_table TYPE lty_stab,
lt_sum_table TYPE lty_stab,
lt_pass_table TYPE lty_tab,
lw_rec TYPE lty_struct.
FIELD-SYMBOLS: <lw_rec> TYPE lty_struct.

LOOP AT it_test_table INTO lw_rec.
INSERT lw_rec INTO TABLE lt_temp_table.
INSERT lw_rec INTO TABLE lt_sum_table.
ENDLOOP.

"This will double the summary_field entries...
CLEAR lw_rec.
LOOP AT lt_temp_table INTO lw_rec.
UNASSIGN <lw_rec>.
READ TABLE lt_sum_table ASSIGNING <lw_rec>
WITH TABLE KEY key1 = lw_rec-key1
key2 = lw_rec-key2.
IF <lw_rec> IS ASSIGNED.
"Add the summary_field...
<lw_rec>-summary_field = <lw_rec>-summary_field + lw_rec-summary_field.
ENDIF.
ENDLOOP.
lt_pass_table[] = lt_sum_table[].
lm_display( CHANGING ct_report = lt_pass_table ).
ENDMETHOD. " lm_process_sorted_table

The above code uses a read on the sorted table using the keys and into a field symbol to update the SUMMARY_FIELD.

New ABAP

Finally, let’s look at the new ABAP way of achieving the same results. With 740, table indexes have been added with the bracket notation []. For example, to retrieve record #5 into a work area, you could specify:
data(lw_record5) = lt_sum_table[ 5 ].

For this table:



For Record 5, it would retrieve the following:



You can also specify values for your key fields to lookup a record.

Let’s try this:
data(lw_record5) = lt_sum_table[ key1 = '905' key2 = '5' ].

Ooops, that gives us a short dump saying “This line is not contained in the table”:



Because we are attempting to use a record that could not be found and assign it to the work area lw_record5, we get a short dump. To handle this, SAP added the “line_exists” function in order to verify that the line actually exists, before trying to use it. So, we must always do this:
    if line_exists( lt_sum_table[ key1 = '905' key2 = '5' ] ).
data(lw_record5) = lt_sum_table[ key1 = '905' key2 = '5' ].
endif.

 

We can now avoid a short dump.

But wait, why doesn’t it exist? As you guessed, if we look at the data type for key1 and key2, it is of type MATNR and RSRNUMC10:



If I copy the variable exactly as it appears in the Eclipse Debugger, I get:

KEY1 (MATNR) as:

“                                    905”

KEY2 is “0000000005”.

So, if we try the following, we can find the record:
    if line_exists( lt_sum_table[ key1 = '                                    905' key2 = '0000000005' ] ).
data(lw_record5) = lt_sum_table[ key1 = ' 905' key2 = '0000000005' ].
endif.

So, the keys must match exactly, with leading zeros, spaces, etc.

Alternatively, you could do the following, and compare it to record 5 in our duplicate table:
data(lw_record5) = lt_sum_table[ key1 = lt_temp_table[ 5 ]-key1 key2 = lt_temp_table[ 5 ]-key2 ].

 

…enough on that, here is the method for new ABAP:
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_process_new_abap: Use New ABAP Features to process a table.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_process_new_abap.
DATA: lt_temp_table TYPE lty_stab,
lt_sum_table TYPE lty_stab,
lt_pass_table TYPE lty_tab.

LOOP AT it_test_table INTO DATA(lw_rec).
INSERT lw_rec INTO TABLE lt_temp_table.
INSERT lw_rec INTO TABLE lt_sum_table.
ENDLOOP.

"This will double the summary_field entries...
"The bracket notation [] finds the record with that key, then we can update it...
CLEAR lw_rec.
LOOP AT lt_temp_table INTO lw_rec.
IF line_exists( lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ] ).
lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ]-summary_field =
lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ]-summary_field + lw_rec-summary_field.
ENDIF.
ENDLOOP.
lt_pass_table[] = lt_sum_table[].
lm_display( CHANGING ct_report = lt_pass_table ).
ENDMETHOD. " lm_process_new_abap

Performance

As I was looking at the following code, I became curious about performance:
      IF line_exists( lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ] ).
lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ]-summary_field =
lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ]-summary_field + lw_rec-summary_field.
ENDIF.

Is the bracket notation, for the above, doing 3 reads on the same record, 3 different times? Perhaps we could eliminate these by assigning it to a field-symbol, then updating the summary_field. I don’t know the answer to this, does it matter? To answer that question, let’s just do a very un-scientific runtime analysis and see if there is a difference in runtimes. Also, I would like to see which of the 3 methods – Standard, Sorted and the new ABAP technique has a performance difference, if any.

 

Since we have the “Number of Records” parameter on the selection screen, let’s crank it up to a number that is large, but acceptable enough to run multiple times. 40,000 records seems like a bearable number to test.

 

Execute the SAP transaction “SAT” and enter the program name:



Click on the “Execute” button, and it will take you to the selection screen:



Enter 40,000 for number of records (or more or less, depending on your system).

Execute the transaction, to get the results:



Click on the Exit button twice, to get back to the SAT measurement screen:



Note the call to our “LM_PROCESS_STANDARD_TABLE” method took 24,927,504 microseconds:



Perform these same steps with the other 2 options for Sorted Table and New ABAP. We get the following runtimes:

Sorted Table:



New ABAP:



So, overall, we have:

Standard Table: 24,927,504

Sorted Table: 1,137,987

New ABAP: 1,200,210

Because the New ABAP technique and the Sorted Table option both use sorted tables, this just tells us that the New ABAP is about the same speed as the other sorted technique. A standard table is slow, simply because it’s doing a sequential read. Now, let’s change the code, and compare the “3 reads” we brought up earlier, to see if using a field-symbol makes a difference.

Here is our current code for the New ABAP option, which got us the above results:
    LOOP AT lt_temp_table INTO lw_rec.
IF line_exists( lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ] ).
lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ]-summary_field =
lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ]-summary_field + lw_rec-summary_field.
ENDIF.
ENDLOOP.

We could change it to a single read, as follows:
    FIELD-SYMBOLS: <lfs_sum> TYPE lty_struct.
LOOP AT lt_temp_table INTO lw_rec.
UNASSIGN <lfs_sum>.
ASSIGN lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ] TO <lfs_sum>.
IF <lfs_sum> IS ASSIGNED.
<lfs_sum>-summary_field = <lfs_sum>-summary_field + lw_rec-summary_field.
ENDIF.
ENDLOOP.

When doing the same runtime analysis in SAT for 40K records, we get runtimes of:

Run1:



Run2:



Run3:



So, when running 3 times, each one was slightly faster by using the field symbol.

 

Complete Program

Here is the complete program:
REPORT zjctest_tables.

SELECTION-SCREEN BEGIN OF BLOCK b1.
PARAMETERS: rb_std RADIOBUTTON GROUP g1,
rb_sort RADIOBUTTON GROUP g1,
rb_new RADIOBUTTON GROUP g1,
p_recs TYPE syindex DEFAULT '20000'.
SELECTION-SCREEN END OF BLOCK b1.

CLASS lcl_my_class DEFINITION CREATE PRIVATE FINAL.
PUBLIC SECTION.
CLASS-METHODS:
main
RETURNING VALUE(r_obj) TYPE REF TO lcl_my_class.
METHODS:
execute.

PRIVATE SECTION.
TYPES: BEGIN OF lty_struct,
key1 TYPE matnr,
key2 TYPE rsrnumc10,
field1 TYPE string,
a_date_field TYPE sydatum,
summary_field TYPE i,
END OF lty_struct,
lty_tab TYPE STANDARD TABLE OF lty_struct,
lty_stab TYPE SORTED TABLE OF lty_struct WITH UNIQUE KEY key1 key2.
METHODS:
constructor,
lm_process_standard_table
IMPORTING it_test_table TYPE lty_tab,
lm_process_sorted_table
IMPORTING it_test_table TYPE lty_tab,
lm_process_new_abap
IMPORTING it_test_table TYPE lty_tab,
lm_display
CHANGING ct_report TYPE table,
lm_build_alv_table
CHANGING ct_report TYPE table
RETURNING VALUE(rt_alv) TYPE REF TO cl_salv_table,
lm_build_records
EXPORTING et_test_table TYPE lty_tab.
ENDCLASS.

CLASS lcl_my_class IMPLEMENTATION.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD constructor: Initialize my object.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD constructor.

ENDMETHOD. " constructor

*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD main: Instantiate the object
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD main.
CREATE OBJECT r_obj.
ENDMETHOD. "MAIN

*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_process_standard_table: Pre-740 Method to process a
* standard table.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_process_standard_table.
DATA: lt_temp_table TYPE lty_tab,
lt_sum_table TYPE lty_tab,
lw_rec TYPE lty_struct.
lt_temp_table[] = it_test_table[].
lt_sum_table[] = it_test_table[].
SORT lt_temp_table BY key1 key2.
SORT lt_sum_table BY key1 key2.

"This will double the summary_field entries...
LOOP AT lt_temp_table INTO lw_rec.
COLLECT lw_rec INTO lt_sum_table.
ENDLOOP.
lm_display( CHANGING ct_report = lt_sum_table ).
ENDMETHOD. " lm_process_standard_table

*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_process_sorted_table: Pre-740 Logic to process a
* sorted table.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_process_sorted_table.
DATA: lt_temp_table TYPE lty_stab,
lt_sum_table TYPE lty_stab,
lt_pass_table TYPE lty_tab,
lw_rec TYPE lty_struct.
FIELD-SYMBOLS: <lw_rec> TYPE lty_struct.

LOOP AT it_test_table INTO lw_rec.
INSERT lw_rec INTO TABLE lt_temp_table.
INSERT lw_rec INTO TABLE lt_sum_table.
ENDLOOP.

"This will double the summary_field entries...
CLEAR lw_rec.
LOOP AT lt_temp_table INTO lw_rec.
UNASSIGN <lw_rec>.
READ TABLE lt_sum_table ASSIGNING <lw_rec>
WITH TABLE KEY key1 = lw_rec-key1
key2 = lw_rec-key2.
IF <lw_rec> IS ASSIGNED.
"Add the summary_field...
<lw_rec>-summary_field = <lw_rec>-summary_field + lw_rec-summary_field.
ENDIF.
ENDLOOP.
lt_pass_table[] = lt_sum_table[].
lm_display( CHANGING ct_report = lt_pass_table ).
ENDMETHOD. " lm_process_sorted_table

*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_process_new_abap: Use New ABAP Features to process a table.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_process_new_abap.
DATA: lt_temp_table TYPE lty_stab,
lt_sum_table TYPE lty_stab,
lt_pass_table TYPE lty_tab.
FIELD-SYMBOLS: <lfs_sum> TYPE lty_struct.

LOOP AT it_test_table INTO DATA(lw_rec).
INSERT lw_rec INTO TABLE lt_temp_table.
INSERT lw_rec INTO TABLE lt_sum_table.
ENDLOOP.

"This will double the summary_field entries...
"The bracket notation [] finds the record with that key, then we can update it...
CLEAR lw_rec.
LOOP AT lt_temp_table INTO lw_rec.
UNASSIGN <lfs_sum>.
ASSIGN lt_sum_table[ key1 = lw_rec-key1 key2 = lw_rec-key2 ] TO <lfs_sum>.
IF <lfs_sum> IS ASSIGNED.
<lfs_sum>-summary_field = <lfs_sum>-summary_field + lw_rec-summary_field.
ENDIF.
ENDLOOP.
lt_pass_table[] = lt_sum_table[].

lm_display( CHANGING ct_report = lt_pass_table ).
ENDMETHOD. " lm_process_new_abap

*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_build_records: Build a table with nn records...
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_build_records.
DO p_recs TIMES.
APPEND VALUE lty_struct( key1 = 900 + sy-index
key2 = sy-index
field1 = |A Text Field - { sy-index }|
a_date_field = sy-datum + sy-index
summary_field = sy-index * 10 )
TO et_test_table.
ENDDO.
ENDMETHOD. " lm_build_records

*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD execute: Execute the work for my object.
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD execute.
DATA: lt_report TYPE lty_tab.
"Create records...
lm_build_records( IMPORTING et_test_table = lt_report ).
"Mess up the sorting, so that we can process and test, below...
SORT lt_report DESCENDING.

IF rb_std = abap_true.
lm_process_standard_table( lt_report ).
ELSEIF rb_sort = abap_true.
lm_process_sorted_table( lt_report ).
ELSEIF rb_new = abap_true.
lm_process_new_abap( lt_report ).
ENDIF.
ENDMETHOD. "execute

*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_display: Show the report...
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_display.
lm_build_alv_table( CHANGING ct_report = ct_report )->display( ).
ENDMETHOD. "display

*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* METHOD lm_build_alv_table: Build the ALV Table...
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
METHOD lm_build_alv_table.
DATA: lv_functions TYPE REF TO cl_salv_functions_list,
lv_columns TYPE REF TO cl_salv_columns_table,
lv_display TYPE REF TO cl_salv_display_settings,
lv_col_tab TYPE salv_t_column_ref,
lv_key TYPE salv_s_layout_key,
lv_layout TYPE REF TO cl_salv_layout,
lv_oref TYPE REF TO cx_root,
lv_text TYPE bapi_msg,
lv_ltext TYPE scrtext_l,
lv_mtext TYPE scrtext_m,
lv_stext TYPE scrtext_s,
lv_select TYPE REF TO cl_salv_selections.
FIELD-SYMBOLS: <lfs_w_col> TYPE salv_s_column_ref.

CLEAR lv_text.
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = rt_alv
CHANGING
t_table = ct_report ).
CATCH cx_salv_msg INTO lv_oref.
lv_text = lv_oref->get_text( ).
RETURN.
ENDTRY.

lv_functions = rt_alv->get_functions( ).
lv_functions->set_all( ).
lv_columns = rt_alv->get_columns( ).
lv_columns->set_optimize( if_salv_c_bool_sap=>true ).
lv_col_tab = lv_columns->get( ).

LOOP AT lv_col_tab ASSIGNING <lfs_w_col>.
CASE <lfs_w_col>-columnname.
WHEN 'KEY1'.
<lfs_w_col>-r_column->set_short_text( 'Key1' ).
<lfs_w_col>-r_column->set_medium_text( 'Key Field #1' ).
<lfs_w_col>-r_column->set_long_text( 'Key Field #1' ).
WHEN 'KEY2'.
<lfs_w_col>-r_column->set_short_text( 'Key2' ).
<lfs_w_col>-r_column->set_medium_text( 'Key Field #2' ).
<lfs_w_col>-r_column->set_long_text( 'Key Field #2' ).
WHEN 'FIELD1'.
<lfs_w_col>-r_column->set_short_text( 'Field1' ).
<lfs_w_col>-r_column->set_medium_text( 'Text Field1' ).
<lfs_w_col>-r_column->set_long_text( 'Text Field1' ).
WHEN 'A_DATE_FIELD'.
<lfs_w_col>-r_column->set_short_text( 'DateField' ).
<lfs_w_col>-r_column->set_medium_text( 'A Date Field' ).
<lfs_w_col>-r_column->set_long_text( 'The First Date Field' ).
WHEN 'SUMMARY_FIELD'.
<lfs_w_col>-r_column->set_short_text( 'SumField' ).
<lfs_w_col>-r_column->set_medium_text( 'Summary Field' ).
<lfs_w_col>-r_column->set_long_text( 'Summary Field' ).
ENDCASE.
ENDLOOP.
lv_display = rt_alv->get_display_settings( ).
lv_display->set_striped_pattern( if_salv_c_bool_sap=>true ).
lv_layout = rt_alv->get_layout( ).
lv_key-report = sy-repid.
lv_layout->set_key( lv_key ).
lv_layout->set_default( abap_true ).
lv_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).
lv_select = rt_alv->get_selections( ).
lv_select->set_selection_mode( if_salv_c_selection_mode=>multiple ).
ENDMETHOD. "lm_build_alv_table
ENDCLASS.

*---------------------------------------------------------------------*
* I N I T I A L I Z A T I O N *
*---------------------------------------------------------------------*
INITIALIZATION.
%_rb_std_%_app_%-text = 'Standard Table'.
%_rb_sort_%_app_%-text = 'Sorted Table'.
%_rb_new_%_app_%-text = 'New ABAP'.
%_p_recs_%_app_%-text = 'Number of Records'.

*---------------------------------------------------------------------*
* S T A R T O F S E L E C T I O N
*---------------------------------------------------------------------*
START-OF-SELECTION.
lcl_my_class=>main( )->execute( ).

*---------------------------------------------------------------------*
* E N D O F S E L E C T I O N
*---------------------------------------------------------------------*
END-OF-SELECTION.

 

References

 

Some excellent blogs for new ABAP Language features:

https://blogs.sap.com/2015/10/25/abap-740-quick-reference/

https://blogs.sap.com/2016/03/02/old-and-new-abap-syntax-overview-sheet/

 

What if you wanted to sort your cloned tables internally, without affecting the sort order of the original table? Checkout this blog…

Blog on Virtual Sorting of Internal Tables:

https://blogs.sap.com/2017/09/20/abap-news-for-release-7.52-virtual-sorting-of-internal-tables/
22 Comments