Recently, I encountered a unique challenge while working with a client with an old SAP system.
I had code ( ABAP 7.4 ) ready to deploy to client system but I could not use it due to lower ECC version. So, I downgraded my code syntactically as many of the operators are not supported by EHP 6.0
I am sharing few of my learnings while doing so. I hope the same can be useful for changing the code to and/or learning ABAP 7.4 as well.
This blog will cover Inline declaration of variables and field symbols, inline usage of structure, and operators such as Filter and group by.
1. LOOP-AT Statement: Inline declaration of Variable or Reference.
Inline Declaration.
LOOP AT GT_DATA ASSIGNING FIELD-SYMBOL(<LS_DATA>).
* Code
ENDLOOP.
LOOP AT GT_DATA INTO DATA(LS_DATA).
* Code
ENDLOOP.
First of all, if you find DATA(*) OR FIELD-SYMBOL(*) in code, it means it is inline declaration. This is not supported by old syntax. So, I declared the field symbol and as it is a LOOP-AT, type of field symbol has to be a line of the table.
Old syntax equivalent is as below.
FIELD-SYMBOLS: <LS_DATA> LIKE LINE OF GT_DATA .
LOOP AT GT_DATA ASSIGNING <LS_DATA>.
* Code
ENDLOOP.
* ORR
data: LS_DATA LIKE LINE OF GT_DATA .
LOOP AT GT_DATA INTO LS_DATA.
* Code
ENDLOOP.
Same holds true for inline declaration of Data(*) in LOOP-AT statement.
2. Inline usage of Structure | NO-DECLRATION
IF <LS_DATA>-NUM IS NOT INITIAL.
APPEND VALUE #( BUKRS = <LS_DATA>-BUK
BELNR = <LS_DATA>-BEL
GJAHR = <LS_DATA>-YR ) TO GT_DOC.
ENDIF.
Here, no structure/ work area is declare to hold values. Instead, direct assignment and then append happens.
First of all, declare a work area of type GT_DOC.
DATA: LS_DOC LIKE LINE OF GT_DOC.
Then assign 3 variables from <ls_data> to new work area and append to the table.
IF <LS_DATA>-NUM IS NOT INITIAL.
LS_DOC-BUKRS = <LS_DATA>-BUK.
LS_DOC-BELNR = <LS_DATA>-BEL.
LS_DOC-GJAHR = <LS_DATA>-YR.
APPEND LS_DOC TO GT_DOC.
ENDIF.
3. Filter Operator : an Equivalent of Conditional Move-corresponding.
New syntax looks like below. As the name suggests, Usage of Filter operator is to transfer records , for which the condition holds true, from one table to another
DATA(LT_DATA) = FILTER #( GT_DATA WHERE BUKRS = CONV #( CS_DATA-BUK )
AND BELNR = CONV #( CS_DATA-BEL )
AND GJAHR = CONV #( CS_DATA-YR ) ).
Initially, I suspected that it is move-corresponding operator for work area. But, I later found out that result is a subset table of GT_Data and “where” condition filters the result set.
So, Equivalent code would look like below.
DATA: LT_DATA LIKE GT_DATA.
DATA: LS_DATA LIKE LINE OF GT_DATA.
DATA:LS_BUKRS TYPE BUKRS,
LS_BELNR TYPE BELNR,
LS_GJAHR TYPE GJAHR.
LS_BUKRS = CS_DATA-BUK.
LS_BELNR = CS_DATA-BEL.
LS_GJAHR = CS_DATA-YR.
LOOP AT GT_DATA INTO LS_DATA WHERE BUKRS = LS_BUKRS
AND BELNR = LS_BELNR
AND GJAHR = LS_GJAHR.
APPEND LS_DATA TO LT_DATA.
ENDLOOP.
4. Reduce Operator : Loop-At statement with Aggregation
Usage of Reduce operator is to aggregate value of a particular column of an internal table.
in other words, it reduces a table to single variable by aggregating.
GS_DATA-TAX = REDUCE #( INIT LV_TAX TYPE BSET-HWSTE
FOR LS_DATA IN LT_DATA
NEXT LV_TAX = LV_TAX + COND #
(
WHEN LS_DATA-SHKZG = CS_DATA-DEBIT THEN LS_DATA-HWSTE
WHEN LS_DATA-SHKZG = CS_DATA-CREDIT THEN ( LS_DATA-HWSTE * -1 )
)
).
In above scenario, Reduce operator loops over LT_DATA and cumulatively adds HWSTE value into LV_TAX and finally assigns to GS_DATA-TAX.
For this to work in old ABAP, it would require looping over an internal table, storing record in a work area and writing an IF-ELSE ladder.
DATA: LV_TAX TYPE BSET-HWSTE.
DATA: LS_DATA LIKE LINE OF LT_DATA.
LOOP AT LT_DATA INTO LS_DATA.
IF LS_DATA-SHKZG = CS_DATA-DEBIT.
LV_TAX = LV_TAX + LS_DATA-HWSTE.
ELSEIF LS_DATA-SHKZG = CS_DATA-CREDIT.
LV_TAX = LV_TAX + ( LS_DATA-HWSTE * -1 ).
ENDIF.
ENDLOOP.
GS_DATA-TAX = LV_TAX.
5. GROUP BY on an Internal Table
New Syntax supports group by operator on an internal table while looping over it.
This makes code way easier when dealing with single internal table containing both Header and Item level data.
Group-by table <LT_GRP>, which is reference to original table GT_TABLE, contains item level data of a particular header. ( Grouped by 3 parameters in below example )
LOOP AT GT_DATA INTO LS_DATA WHERE VAR1 = ABAP_TRUE
AND VAR2 IS NOT INITIAL
GROUP BY ( BUKRS = LS_DATA-BUKRS
BELNR = LS_DATA-BELNR
GJHAR = LS_DATA-GJHAR
INDEX = GROUP INDEX )
ASCENDING
ASSIGNING FIELD-SYMBOL(<LT_GRP>).
* Code
LOOP AT GROUP <LT_GRP> ASSIGNING FIELD-SYMBOL(<LS_GRP_DATA>).
* Code
ENDLOOP.
* Code
ENDLOOP.
I found this one really complex to solve.
Old syntax does not support Group-by on an internal table. So I had to find a solution for GROUP-BY.
Create a copy-table of the given table and use it is header table, while GT_TABLE would work as Item table.
I used field symbol for looping over item table, so I would be able to make changes in the GT_TABLE itself.
FIELD-SYMBOL: <LS_GRP_DATA> LIKE LINE OF GT_DATA.
DATA: GT_HEADER_DATA LIKE GT_DATA.
GT_HEADER_DATA[] = GT_DATA[].
SORT GT_HEADER_DATA BY BUKRS
BELNR
GJHAR.
DELETE ADJECENT DUPLICATES FROM GT_HEADER_DATA COMPARING BUKRS
BELNR
GJHAR.
LOOP AT GT_HEADER_DATA INTO LS_DATA WHERE VAR1 = ABAP_TRUE
AND VAR2 IS NOT INITIAL.
* Code
LOOP AT GT_DATA ASSIGNING <LS_GRP_DATA> WHERE VAR1 = ABAP_TRUE
AND VAR2 IS NOT INITIAL
AND BUKRS = LS_DATA-BUKRS
AND BELNR = LS_DATA-BELNR
AND GJHAR = LS_DATA-GJHAR.
* Code
ENDLOOP.
* Code
ENDLOOP.
No comments:
Post a Comment