Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

ABAP New Syntax - Delete

0 Likes
26,224

Hello experts!

Is there any new syntax regarding this example?

The following Table is given as an internal table (itab) with the two columns C1/C2:

C1 C2

X 1

X 2

Y 1

Y 5

Z 5

Now I want to delete all entries where C2 = 1 occurs, with the condition that if one entry of C1 has C2 = 1, that all the same entries of C1 are also deleted..

The result should be as follows:

C1 C2

Z 5

That means:

C1 C2

X 1 --> C2 = 1!

X 2 --> C2 was 1, so that entries gets deleted as well

Y 1 --> Same as X 1

Y 5 --> Same as X 2

Z 5 --> no occurence of C2 = 1 and thats the reason for keeping this record.

Is there any new syntax?

Also..how to achieve this result?

Kind regards

1 ACCEPTED SOLUTION
Read only

Sandra_Rossi
Active Contributor
0 Likes
16,480

There's no "new syntax" (you mean a constructor expression) specific to your exact requirement.

But of course you can write it with a constructor expression, not sure if it will be readable by majority of developers though), it could be something like this, more or less:

itab = VALUE #(
  LET c1_values = VALUE #( FOR <line> IN itab WHERE ( c2 = 1 ) ( <line>-c1 ) )
      itab2     = itab
  IN FOR <line> IN itab2
  ( LINES OF COND #( WHEN NOT line_exists( c1_values[ <line>-c1 ] THEN <line> ) ) ) ).

Hello experts!

Is there any new syntax regarding this example?

The following Table is given as an internal table (itab) with the two columns C1/C2:

C1 C2

X 1

X 2

Y 1

Y 5

Z 5

Now I want to delete all entries where C2 = 1 occurs, with the condition that if one entry of C1 has C2 = 1, that all the same entries of C1 are also deleted..

The result should be as follows:

C1 C2

Z 5

That means:

C1 C2

X 1 --> C2 = 1!

X 2 --> C2 was 1, so that entries gets deleted as well

Y 1 --> Same as X 1

Y 5 --> Same as X 2

Z 5 --> no occurence of C2 = 1 and thats the reason for keeping this record.

Is there any new syntax?

Also..how to achieve this result?

Kind regards

14 REPLIES 14
Read only

Sathya_Gunasekaran
Contributor
0 Likes
16,480

If I understood your requirement right...

LOOP AT TABLE itab INTO wa1.

IF wa1-c2 NE '1'.

REATD TABLE itab INTO wa2 WITH KEY c1 = wa1-c1 c2 = 1.

IF sy-subrc NE 0. " This record's C2 NE 1 and C1 value of the row doesn't contain 1 in any other record either.

Move it to a temporary ITAB.

ENDIF.

ENDLOOP.

Now the temporary itab should have the records that you need to keep. Does this make sense?

Read only

0 Likes
16,480

Sorry, I missed the 'New Syntax' part of your question. As far as I know, No. But our expert friends might have a better idea.

Read only

0 Likes
16,480

I am thinking a bit loud here. This is not New syntax though.

SELECT c1, c2

FROM db

WHERE c2 NE 1

AND c1 NOT IN ( SELECT c1 from db where c2 NE 1 )

Read only

former_member1716
Active Contributor
16,480

coding1407,

Which GUI Version are you using?

If you are using 7.5 or above, you can directly write select query in the internal table as mentioned below.

1) Try fetching the values of C1 from the internal table where C2 = 1

2) Now Just delete the entries from internal table where value of C1 is equal to the value fetched from above.

Regards!

Read only

0 Likes
16,480

to 2)

How to delete the entries from Itab1?

Delete itab1 where c1 = itab2-c1?

Read only

0 Likes
16,480

GUI version? You mean ABAP version.

Read only

0 Likes
16,480

Sandra Rossi, yes the ABAP version.

Read only

0 Likes
16,480

Pascal Ditzel,

You can do that in two way.

1) Either create a range table out of the C1 Column Values and then use the simple query as below

DELETE ITAB1 WHERE C1 IN R_RANGE.

2) Else you can simply write another Select query non ITAB1 using for all entries where c1 NE itab2-C1.

Regards!
Read only

0 Likes
16,480

Select query on itab1 using for all entries itab two will not work, as FOR ALL ENTRIES and @itab cannot be used together.

Read only

gayathri_jayajeevan2
Participant
0 Likes
16,480

C1 and C2 fetched from the same table?

Read only

Sandra_Rossi
Active Contributor
0 Likes
16,481

There's no "new syntax" (you mean a constructor expression) specific to your exact requirement.

But of course you can write it with a constructor expression, not sure if it will be readable by majority of developers though), it could be something like this, more or less:

itab = VALUE #(
  LET c1_values = VALUE #( FOR <line> IN itab WHERE ( c2 = 1 ) ( <line>-c1 ) )
      itab2     = itab
  IN FOR <line> IN itab2
  ( LINES OF COND #( WHEN NOT line_exists( c1_values[ <line>-c1 ] THEN <line> ) ) ) ).
Read only

0 Likes
16,480
coding1407 You have a syntax error, well, but you don't provide the code. I said "something like this, more or less", because my code doesn't compile, you didn't provide some code to reproduce. c1_values doesn't exist either. I think you can find what the syntax error is. I prefer to avoid spoon feeding and let people search a little bit...
Read only

16,480

Spoon feeding. Tested.

TYPES: BEGIN OF ty_line,
  c1 type c length 1,
  c2 type i,
  END OF ty_line,
  ty_itab type STANDARD TABLE OF ty_line WITH EMPTY KEY,
  ty_c1_values type SORTED TABLE OF ty_line-c1 WITH NON-UNIQUE KEY table_line.
data(itab) = value TY_itab( ( c1 = 'X' c2 = 1 ) ( c1 = 'X' c2 = 2 )
  ( c1 = 'Y' c2 = 1 ) ( c1 = 'Y' c2 = 5 ) ( c1 = 'Z' c2 = 5 ) ).
itab = VALUE #(
  LET c1_values = VALUE ty_c1_values( FOR <line> IN itab WHERE ( c2 = 1 ) ( <line>-c1 ) )
      itab2     = itab
  IN FOR <line> IN itab2
  ( LINES OF COND #( WHEN NOT line_exists( c1_values[ table_line = <line>-c1 ] ) THEN value #( ( <line> ) ) ) ) ).
Read only

16,480

If "LOOP AT GROUP BY" is considered as new syntax then there is this other variant :

*I reused declaration lines of  Sandra Rossi answer
TYPES: BEGIN OF ty_line,
         c1 TYPE c LENGTH 1,
         c2 TYPE i,
       END OF ty_line,
       ty_itab      TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
DATA(itab) = VALUE ty_itab( ( c1 = 'X' c2 = 1 )
                            ( c1 = 'X' c2 = 2 )
                            ( c1 = 'Y' c2 = 1 )
                            ( c1 = 'Y' c2 = 5 )
                            ( c1 = 'Z' c2 = 5 ) ).


LOOP AT itab INTO DATA(wa) WHERE c2 = 1 GROUP BY ( c1 = wa-c1 )
  WITHOUT MEMBERS REFERENCE INTO DATA(gr) .
  DELETE itab WHERE c1 = gr->*. "DELETE inside a LOOP
ENDLOOP.


There is also this one (use of range) :

*I reused declaration lines of  Sandra Rossi answer
TYPES: BEGIN OF ty_line,
         c1 TYPE c LENGTH 1,
         c2 TYPE i,
       END OF ty_line,
       ty_itab      TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
DATA(itab) = VALUE ty_itab( ( c1 = 'X' c2 = 1 )
                            ( c1 = 'X' c2 = 2 )
                            ( c1 = 'Y' c2 = 1 )
                            ( c1 = 'Y' c2 = 5 )
                            ( c1 = 'Z' c2 = 5 ) ).

DATA lr TYPE RANGE OF ty_line-c1.
LOOP AT itab INTO DATA(wa) WHERE c2 = 1 GROUP BY ( c1 = wa-c1 )
  WITHOUT MEMBERS REFERENCE INTO DATA(gr) .
  APPEND VALUE #( sign = 'I' option = 'EQ' low = gr->* ) TO lr.
ENDLOOP.

IF lr IS NOT INITIAL.
  DELETE itab WHERE c1 IN lr. "DELETE outside LOOP
ENDIF.