SAP ABAP Guide Part 3 Expressions and Operators Part 2 : The Latest and Greatest
George Drakos
SAP Technical Consultant | S/4 HANA and SAP UI5/Fiori | On Premise and Cloud | SAP Certified Development Specialist | MBA
George Drakos - Dimitrios Valouxis
Hello SAP world,
We both are Electrical and Computer Engineering graduates. Specifically, we specialize in Programming and Machine learning implementations. At the time being, we work as ABAP developers. The former works in one of the greatest world’s Consulting companies and the latter in Greece’s biggest Retail company.
We decided to enter the Sap world with the intention of offering our knowledge and eagerness aiming to evolve this field.
Notwithstanding we are new in the field, we are determined to develop innovative ideas to transform problems into solutions.
This article constitutes the fourth of the series 'Guide to level up a beginner' and it is actually the Part 2 of the third article 'Expressions and Operators'. Our main scope isn't to teach the basics to an ABAP beginner but to teach a beginner how he can step up his game. Consequently, we will try to analyze special techniques and unique functionalities a newbie can follow to complete a difficult task. In this article, we will focus on new expressions and operators that SAP introduced in ABAP versions 7.4 and 7.5. This is the part 2 of our previous article "Expressions and Operators". This article contains 6 more operators alongside their codes. Without further ado let's dive deep into ABAP's latest and greatest features.
1.The NEW Operator
The New Operator, which is similar to VALUE operator, is a constructor operator. This means that you can use the NEW operator in order to create data objects but more importantly we can create instances of a class. It is a really handy operator since you can declare and instantiate object in just one line of code. We recommend using the VALUE instead of NEW operator for data object creation. The NEW is mainly used for object creation and instantiation. Lets see how it works:
"Creating and Instantiating object "OLD WAY DATA lo_class1 TYPE REF TO ZCL_CLASS1 CREATE OBJECT lo_class1 EXPORTING ARTICLE = 'ARTICLE 4' "NEW WAY 1 DATA(lo_class1) = NEW ZCL_CLASS1 (ARTICLE = 'ARTICLE 4') "NEW WAY 2 DATA lo_class1 TYPE REF TO ZCL_CLASS1 lo_class1 = NEW #(ARTICLE = 'ARTICLE 4'). "Creating Data Object DATA lv_article TYPE REF TO data. lv_article = NEW string('Article 4')."String Creation DATA lv_integer TYPE REF TO data. lv_integer = NEW i( 4 )."Integer Creation
2.The casting operator CAST
Cast is a more unique operator and you have to use it sincerely. It's scope is to down cast or up cast an argument in order to create a reference variable of a static type as a result.
Pros:
- It is suitable for avoiding the declaration of helper variables.
- Up cast can declare a general type of a declared reference variable in inline declaration.
- Cast is related to Conv, but it performs a casting instead of a conversion.
Ok, let's make it a little bit more complex now. Below there is an example which shows how to dynamically take the components of a table .There are 2 ways doing that. The old way where you declare the variable and call line by line the methods and the newer one where you use inline declaration with casting. Amazing, isn't it? Finally we will show you a complete example where you can see how value can be used in a block of code combined with conv and let. Expressions are so good if you know how to use them. Make them count.
"Example One DATA : IT_TABDESCR TYPE ABAP_COMPDESCR_TAB, WA_TABDESCR TYPE ABAP_COMPDESCR. DATA : REF_TABLE_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR. "Before: REF_TABLE_DESCR ?= CL_ABAP_TYPEDESCR=>DESCRIBE_BY_NAME( P_TABLE ). IT_TABDESCR[] = REF_TABLE_DESCR->COMPONENTS[]. "After: DATA(STRUCT_COMPONENTS_L) = CAST CL_ABAP_STRUCTDESCR( CL_ABAP_TYPEDESCR=>DESCRIBE_BY_NAME( P_TABLE ) )->COMPONENTS. "Example Two TYPES: BEGIN OF TY_DATES, YEAR TYPE STRING, MONTH TYPE STRING, DAY TYPE STRING, END OF TY_DATES. TYPES: TT_DATES TYPE TABLE OF TY_DATES WITH EMPTY KEY. DATA(LT_DATES) = VALUE TT_DATES( ( YEAR = '2020' MONTH = '09' DAY = '15' ) ( YEAR = '2021' MONTH = '09' DAY = '30' ) ). DO LINES( LT_DATES ) TIMES. DATA(FORMAT_DATE) = CONV STRING( LET DATE = LT_DATES[ SY-INDEX ] SEP = '-' IN DATE-YEAR && SEP && DATE-MONTH && SEP && DATE-DAY ). WRITE: / FORMAT_DATE. ENDDO.
3.The component operator CORRESPONDING
Here is another very useful constructor operator. It seems like move-corresponding for structures or internal tables but it has something unique. Besides assigning components with the same technical name you can also define the mapping you want. You will understand it completely with the following example. Let's see:
DATA: BEGIN OF LT_VBAK OCCURS 0, VBELN LIKE VBAK-VBELN, KUNNR LIKE VBAK-KUNNR, END OF LT_VBAK. DATA: BEGIN OF LT_OUT OCCURS 0, VBELN LIKE VBAK-KUNNR, CUSTOMER LIKE VBAK-KUNNR, END OF LT_OUT. SELECT * UP TO 2 ROWS FROM VBAK INTO CORRESPONDING FIELDS OF TABLE LT_VBAK. LT_OUT[] = CORRESPONDING #( LT_VBAK[] MAPPING CUSTOMER = KUNNR ).
As you can see lt_vbak has a matnr component but lt_out hasn't. In order to "move-corresponding" you can map the customer component to the kunnr component.
4.LOOP : GROUP BY, FOR
We think that you all use LOOP statement daily in your codes. It is true that LOOP is one of the most famous statements to read, modify and append internal tables. From ABAP 740 and above we can now use GROUP BY in order to group data in an internal table based on a column value (just like how we used GROUP BY on the SELECT statement). Also we can use optional keywords to further enhance GROUP BY potential. These are SIZE, INDEX, ASCENDING/DESCENDING and WITHOUT MEMBERS. Ready?
DATA : lt_spfli TYPE STANDARD TABLE OF spfli. LOOP AT lt_spfli INTO DATA (ls_spfli) GROUP BY (value = ls_spfli-carrid size = GROUP SIZE "Stores the number of members in the group index = GROUP INDEX " Stores the group index ) "DESCENDING "Optional-Default is Ascending. "WITHOUT MEMBERS "Optional-Restricts access to group members INTO DATA(lt_group). LOOP AT GROUP lt_group INTO DATA(ls_group). WRITE:/ ls_group-connid. ENDLOOP. ENDLOOP.
Now let's talk about FOR loop. It's really helpful to loop and change the values of an internal table using FOR, alongside with value operator, but keep in mind that you cannot debug the FOR loop. So we recommend not to use the FOR loop when you have to do complex modifications to an internal table. WHILE and UNTIL are also possible inside FOR iteration but due to lack of debugging it is better to avoid it completely and go with LOOP AT. Lets see three simple examples to clarify things:
"We increase the flight time by 1 hour DATA(lt_loop_spfli) = VALUE tt_loop (FOR ls_loop_spfli IN lt_spfli (fltime = ls_loop_spfli-fltime + 1)). "We can also use WHERE condition DATA(lt_loop_spfli) = VALUE tt_loop (FOR ls_loop_spfli IN lt_spfli WHERE (cityto = 'Athens') (fltime = ls_loop_spfli-fltime + 1)). "And finally you can use LET that we previously analyzed DATA(lt_loop_spfli) = VALUE tt_loop (FOR ls_loop_spfli IN lt_spfli LET flight_time = 1 IN fltime = ls_loop_spfli-fltime + flight_time).
5. Relational Expression IS INSTANCE OF
This relational expression is easy to understand but offers big value to the developers who make use of it. If you want to check whether a reference variable points to an object or not you can use the IS INSTANCE OF expression. Then you can cast the reference variable to another reference variable either by using CAST or even better using INTO DATA when you choose CASE as the control structure. Straight to the code now:
DATA(lv_object) = cl_abap_article1=>method_article(parameters) "Using CASE CASE TYPE OF lv_object. WHEN TYPE cl_abap_article1 INTO DATA(article1). WHEN TYPE cl_abap_article2 INTO DATA(article2). WHEN OTHERS. ENDCASE. "Using IF IF lv_object IS INSTACE OF cl_abap_article1. DATA(article1) = CAST cl_abap_article1(lv_object) ELSEIF lv_object IS INSTANCE OF cl_abap_article2. DATA(article2) = CASE cl_abap_article2(lv_object). ELSE. "Handle accordingly ENDIF.
6. The Reduce Operator REDUCE
Using reduction operator creates a result of a data type specified using type from one or more iteration expressions. You can either use a non-generic data type or the # character as a symbol for the operand type. It is an operator which can be useful in many ways.
"A simple Example DATA(V1) = REDUCE I( INIT SUM = 0 FOR I = 1 THEN I + 1 UNTIL I > 10 NEXT SUM = SUM + I ).
So what is it about? We use an inline declaration of V1 as a result. At this example we add 10 numbers starting from 1 and adding the next number to the result every time. Here is another example which has a real use in a productive code:
data(orders) = reduce i( init x = 0 for wa in lt_order where ( vbeln = space ) next x = x + 1 ).
As you have already understood the code above returns the entries of the table lt_order where vbeln is equal to space.
That's it with Expressions and Operators in ABAP 7.4-7.5.
Stay Tuned because special articles are about to be published with special techniques and complete codes to analyze.