forked from SAP-samples/abap-cheat-sheets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
zcl_demo_abap_internal_tables.clas.abap
1892 lines (1371 loc) · 67.7 KB
/
zcl_demo_abap_internal_tables.clas.abap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
***********************************************************************
*
* ABAP cheat sheet: Internal tables
*
* -------------------------- PURPOSE ----------------------------------
* - Example to demonstrate various syntax options for working with
* internal tables.
* - Topics covered: Creating, filling, reading from, sorting, modifying
* internal tables
*
* ----------------------- GETTING STARTED -----------------------------
* - Open the class with the ABAP development tools for Eclipse (ADT).
* - Choose F9 to run the class.
* - Check the console output.
* - To understand the context and the ABAP syntax used, refer to the
* notes included in the class as comments or refer to the respective
* topic in the ABAP Keyword Documentation.
* - Due to the amount of console output, the examples contain numbers
* (e.g. 1) ..., 2) ..., 3) ...) for the individual example sections.
* Also, the variable name is displayed in most cases. So to find
* the relevant output in the console easier and faster, just search
* for the number/variable name in the console (CTRL+F in the console)
* or use the debugger.
*
* ----------------------------- NOTE -----------------------------------
* The code presented in this class is intended only to support the ABAP
* cheat sheets. It is not intended for direct use in a production system
* environment. The code examples in the ABAP cheat sheets are primarily
* intended to provide a better explanation and visualization of the
* syntax and semantics of ABAP statements, not to solve concrete
* programming tasks. For production application programs, you should
* always work out your own solution for each individual case. There is
* no guarantee for the correctness or completeness of the code.
* Furthermore, there is no legal responsibility or liability for any
* errors or their consequences that may occur when using the the example
* code.
*
***********************************************************************
"! <p class="shorttext synchronized">ABAP cheat sheet: Internal tables</p>
"! Example to demonstrate working with internal tables.<br>Choose F9 in ADT to run the class.
CLASS zcl_demo_abap_internal_tables DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: if_oo_adt_classrun.
CLASS-METHODS: class_constructor.
PRIVATE SECTION.
"Creating structured data types.
TYPES: "Line types for internal tables
BEGIN OF struc1,
a TYPE i,
b TYPE c LENGTH 3,
c TYPE c LENGTH 3,
d TYPE c LENGTH 3,
END OF struc1,
BEGIN OF struc2,
a TYPE i,
b TYPE c LENGTH 3,
e TYPE c LENGTH 3,
f TYPE string,
END OF struc2,
"Types for demonstrating nested internal tables
BEGIN OF l_type1,
key_field TYPE i,
char1 TYPE c LENGTH 10,
char2 TYPE c LENGTH 10,
num1 TYPE i,
num2 TYPE i,
END OF l_type1,
BEGIN OF l_type2,
key_field TYPE i,
num1 TYPE i,
num2 TYPE i,
END OF l_type2,
BEGIN OF nested1,
key_field TYPE i,
char1 TYPE c LENGTH 10,
tab TYPE STANDARD TABLE OF l_type2 WITH EMPTY KEY,
END OF nested1,
BEGIN OF nested2,
key_field TYPE i,
char2 TYPE c LENGTH 10,
tab TYPE STANDARD TABLE OF l_type1 WITH EMPTY KEY,
END OF nested2,
"Declaring internal table types.
"Types for demonstrating nested internal tables
ty_nested1 TYPE STANDARD TABLE OF nested1 WITH EMPTY KEY,
ty_nested2 TYPE STANDARD TABLE OF nested2 WITH EMPTY KEY.
CLASS-DATA:
"Declaring internal tables.
"Internal tables for demonstrating nested internal tables
itab_nested1 TYPE ty_nested1,
itab_nested2 TYPE ty_nested2,
"Internal tables for CORRESPONDING/MOVE-CORRESPONDING demo
tab1 TYPE TABLE OF struc1 WITH NON-UNIQUE KEY a,
tab2 TYPE TABLE OF struc2 WITH NON-UNIQUE KEY a,
tab3 TYPE SORTED TABLE OF struc1 WITH UNIQUE KEY a,
tab4 TYPE SORTED TABLE OF struc2 WITH UNIQUE KEY a.
CLASS-METHODS:
fill_dbtabs,
fill_itabs_for_corresponding.
ENDCLASS.
CLASS ZCL_DEMO_ABAP_INTERNAL_TABLES IMPLEMENTATION.
METHOD class_constructor.
fill_dbtabs( ).
ENDMETHOD.
METHOD fill_dbtabs.
"Initializing and filling of database tables to have data to work with
DELETE FROM zdemo_abap_tab1.
DELETE FROM zdemo_abap_tab2.
MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #(
( key_field = 100 char1 = 'aaa' char2 = 'bbb' num1 = 1 num2 = 2 )
( key_field = 200 char1 = 'ccc' char2 = 'ddd' num1 = 3 num2 = 4 )
( key_field = 300 char1 = 'eee' char2 = 'fff' num1 = 5 num2 = 6 )
( key_field = 400 char1 = 'ggg' char2 = 'hhh' num1 = 7 num2 = 8 ) ) ).
MODIFY zdemo_abap_tab2 FROM TABLE @( VALUE #(
( key_field = 500 char1 = 'iii' num1 = 10 numlong = 1000 )
( key_field = 600 char1 = 'kkk' num1 = 12 numlong = 2000 )
( key_field = 700 char1 = 'mmm' num1 = 14 numlong = 3000 )
( key_field = 800 char1 = 'ooo' num1 = 15 numlong = 4000 ) ) ).
ENDMETHOD.
METHOD fill_itabs_for_corresponding.
tab1 = VALUE #( ( a = 1 b = 'aaa' c = 'aaa' d = 'A' )
( a = 2 b = 'bbb' c = 'bbb' d = 'B' ) ).
tab2 = VALUE #( ( a = 3 b = 'ccc' e = 'ccc' f = `CCC` )
( a = 4 b = 'ddd' e = 'ddd' f = `DDD` ) ).
tab3 = VALUE #( ( LINES OF tab1 ) ).
tab4 = VALUE #( ( a = 1 b = 'xxx' e = 'yyy' f = `ZZZ` )
( LINES OF tab2 ) ).
itab_nested1 = VALUE #(
( key_field = 1 char1 = 'aaa'
tab = VALUE #( ( key_field = 1 num1 = 2 num2 = 3 )
( key_field = 2 num1 = 3 num2 = 4 )
( key_field = 3 num1 = 4 num2 = 5 ) ) )
( key_field = 2 char1 = 'bbb'
tab = VALUE #( ( key_field = 4 num1 = 5 num2 = 6 )
( key_field = 5 num1 = 6 num2 = 7 )
( key_field = 6 num1 = 7 num2 = 8 ) ) ) ).
itab_nested2 = VALUE #(
( key_field = 99 char2 = 'yyy' tab = VALUE #(
( key_field = 10 char1 = 'aaa'
char2 = 'bbb' num1 = 100 num2 = 200 )
( key_field = 20 char1 = 'ccc'
char2 = 'ddd' num1 = 300 num2 = 400 )
( key_field = 30 char1 = 'eee'
char2 = 'fff' num1 = 500 num2 = 600 ) ) )
( key_field = 100 char2 = 'zzz' tab = VALUE #(
( key_field = 40 char1 = 'ggg'
char2 = 'hhh' num1 = 700 num2 = 800 )
( key_field = 50 char1 = 'iii'
char2 = 'jjj' num1 = 900 num2 = 1000 )
( key_field = 60 char1 = 'kkk'
char2 = 'lll' num1 = 1100 num2 = 1200 ) ) ) ).
ENDMETHOD.
METHOD if_oo_adt_classrun~main.
out->write( |ABAP Cheat Sheet Example: Internal Tables\n\n| ).
out->write( |Filling and Copying Internal Table Content\n| ).
out->write( |1) Adding single lines using APPEND/INSERT\n\n| ).
"Two internal tables, a standard and sorted internal table.
"Both have the same line type and one field as (non-)unique key.
DATA it_st TYPE TABLE OF struc1 WITH NON-UNIQUE KEY a.
DATA it_so TYPE SORTED TABLE OF struc1 WITH UNIQUE KEY a.
"APPEND
"Standard table
APPEND VALUE #( a = 1 b = 'aaa' c = 'bbb' d = 'ccc' ) TO it_st.
"A line is created and filled to be used for the APPEND statement.
"The line type matches the line type of the internal table.
DATA(line) = VALUE struc1( a = 2 b = 'd' c = 'e' d = 'f' ).
"Sorted table
"APPEND works here with a sorted table. At this stage, the
"internal table is empty, so there is no issue (lines are only
"appended if they match the sort order and do not create
"duplicate entries if the primary table key is unique).
APPEND line TO it_so.
"INSERT
"INSERT has same effect as APPEND with standard tables
INSERT VALUE #( a = 2 b = 'ddd' c = 'eee' d = 'fff' )
INTO TABLE it_st.
INSERT VALUE #( a = 1 b = 'a' c = 'b' d = 'c' ) INTO TABLE it_so.
out->write( data = it_st name = `it_st` ).
out->write( |\n| ).
out->write( data = it_so name = `it_so` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `2) Adding initial line` ) ).
APPEND INITIAL LINE TO it_st.
INSERT INITIAL LINE INTO TABLE it_so.
out->write( data = it_st name = `it_st` ).
out->write( |\n| ).
out->write( data = it_so name = `it_so` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `3) Adding mutliple lines of an internal table to another one` ) ).
"No additions: All lines are added to the target internal table
APPEND LINES OF it_so TO it_st.
"Creating a new itab and filling it.
DATA it_so2 LIKE it_so.
INSERT VALUE #( a = 3 b = 'g' c = 'h' d = 'i' ) INTO TABLE it_so2.
INSERT VALUE #( a = 4 b = 'j' c = 'k' d = 'l' ) INTO TABLE it_so2.
"Inserting all lines of previously created internal table.
INSERT LINES OF it_so2 INTO TABLE it_so.
out->write( data = it_st name = `it_st` ).
out->write( |\n| ).
out->write( data = it_so name = `it_so` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `4) Adding lines of an internal table to another one by specifying the index range.` ) ).
"When using only FROM, all lines are respected until the final
"table entry. When using only TO, all lines are respected
"starting from the first table entry.
APPEND LINES OF it_so FROM 2 TO 3 TO it_st.
INSERT LINES OF it_so FROM 3 INTO TABLE it_st.
APPEND LINES OF it_so TO 2 TO it_st.
out->write( data = it_st name = `it_st` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `5) Inserting lines of an internal table into another one at a specific position` ) ).
"Inserting a single line
INSERT VALUE #( a = 10 b = 'ggg' c = 'hhh' d = 'iii' )
INTO it_st INDEX 1.
"Inserting multiple lines
INSERT LINES OF it_so2 INTO it_st INDEX 2.
out->write( data = it_st name = `it_st` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `6) Adding lines using constructor expressions` ) ).
"Creating a line to be added to an internal table.
line = VALUE #( a = 1 b = 'aaa' c = 'bbb' d = 'ccc' ).
"Table on the right is constructed inline using VALUE and assigned
"Note: This way, existing table content is cleared.
it_st = VALUE #( ( line )
( a = 2 b = 'ddd' c = 'eee' d = 'fff' ) ).
out->write( data = it_st name = `it_st` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `7) Creating a new table inline and adding lines using a constructor expression` ) ).
"Internal table type
TYPES it_type LIKE it_st.
"Creating an internal table inline and filling in one go
DATA(it_st2) = VALUE it_type( ( a = 3 b = 'ggg'
c = 'hhh' d = 'iii' )
( a = 4 b = 'jjj'
c = 'kkk' d = 'lll' ) ).
out->write( data = it_st2 name = `it_st2` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `8) Adding lines using constructor expressions and keeping existing table content` ) ).
"BASE addition: existing table content is not removed
it_st = VALUE #( BASE it_st ( a = 5 b = 'mmm' c = 'nnn' d = 'ooo' )
( a = 6 b = 'ppp' c = 'qqq' d = 'rrr' )
).
out->write( data = it_st name = `it_st` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `9) Adding lines from other internal tables using constructor expressions` ) ).
"With LINES OF itab specified within the pair of parentheses,
"all lines of the internal table are added; here, in the same
"expression another line is added as well
it_st = VALUE #( BASE it_st ( LINES OF it_st2 )
( a = 7 b = 'sss' c = 'ttt' d = 'uuu' )
).
out->write( data = it_st name = `it_st` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `10) Copying table content (without constructor expression)` ) ).
"Assignment of a table to another one having a matching line type
it_st = it_st2.
out->write( data = it_st name = `it_st` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `11) CORRESPONDING Operator and MOVE-CORRESPONDING` ) ).
out->write( |Internal table content before assignments\n\n| ).
"Note: Before the following statements, the table content is reset
"to this state to work with the same set of values.
fill_itabs_for_corresponding( ).
out->write( data = tab1 name = `tab1` ).
out->write( |\n| ).
out->write( data = tab2 name = `tab2` ).
out->write( |\n| ).
out->write( data = tab3 name = `tab3` ).
out->write( |\n| ).
out->write( data = tab4 name = `tab4` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `Copying content from another table that has a different line type ...` ) ).
out->write( |12) ... and deleting existing table content using the CORRESPONDING operator\n\n| ).
tab1 = CORRESPONDING #( tab2 ).
out->write( data = tab1 name = `tab1` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `13) ... and deleting existing table content using MOVE-CORRESPONDING` ) ).
MOVE-CORRESPONDING tab2 TO tab1.
out->write( data = tab1 name = `tab1` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `14) ... and keeping existing table content using the CORRESPONDING operator` ) ).
tab1 = CORRESPONDING #( BASE ( tab1 ) tab2 ).
out->write( data = tab1 name = `tab1` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `15) ... and keeping existing table content using MOVE-CORRESPONDING` ) ).
MOVE-CORRESPONDING tab2 TO tab1 KEEPING TARGET LINES.
out->write( data = tab1 name = `tab1` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `16) ... respecting component mapping` ) ).
"Specifying components of a source table that are assigned to the
"components of a target table in mapping relationships
tab1 = CORRESPONDING #( tab2 MAPPING c = e d = f ).
out->write( data = tab1 name = `tab1` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `17) ... excluding components` ) ).
"Excluding components from the assignment
tab1 = CORRESPONDING #( tab2 EXCEPT b ).
out->write( data = tab1 name = `tab1` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `18) ... excluding components and using MAPPING` ) ).
"EXCEPT * means that all components remain initial not specified
"for mapping
tab1 = CORRESPONDING #( tab2 MAPPING d = f EXCEPT * ).
out->write( data = tab1 name = `tab1` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `19) ... discarding duplicates` ) ).
"Preventing runtime errors if duplicate lines are assigned to
"target table that is defined to only accept unique keys.
"Note: Other tables than above are used here.
tab3 = CORRESPONDING #( BASE ( tab3 ) tab4 DISCARDING DUPLICATES ).
out->write( data = tab3 name = `tab3` ).
out->write( |\n| ).
fill_itabs_for_corresponding( ).
tab3 = CORRESPONDING #( BASE ( tab3 ) tab4 DISCARDING DUPLICATES
MAPPING d = f EXCEPT b ).
out->write( data = tab3 name = `tab3` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `20) Copying data from a deep internal table to another deep internal table` ) ).
out->write( `Original table content` ).
out->write( |\n| ).
out->write( |\n| ).
out->write( data = itab_nested1 name = `itab_nested1` ).
out->write( |\n| ).
out->write( data = itab_nested2 name = `itab_nested2` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `21) ... deleting existing content (CORRESPONDING operator)` ) ).
itab_nested2 = CORRESPONDING #( DEEP itab_nested1 ).
out->write( data = itab_nested2 name = `itab_nested2` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `22) ... deleting existing content (MOVE-CORRESPONDING)` ) ).
MOVE-CORRESPONDING itab_nested1 TO itab_nested2
EXPANDING NESTED TABLES.
out->write( data = itab_nested2 name = `itab_nested2` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `23) ... keeping existing content (CORRESPONDING operator)` ) ).
itab_nested2 = CORRESPONDING #( DEEP BASE ( itab_nested2 )
itab_nested1 ).
out->write( data = itab_nested2 name = `itab_nested2` ).
fill_itabs_for_corresponding( ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `24) ... keeping existing content (MOVE-CORRESPONDING)` ) ).
MOVE-CORRESPONDING itab_nested1 TO itab_nested2
EXPANDING NESTED TABLES KEEPING TARGET LINES.
out->write( data = itab_nested2 name = `itab_nested2` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `Filling internal tables: Excursions` ) ).
out->write( |25) Selecting multiple rows from a database table into an internal table\n\n| ).
SELECT FROM zdemo_abap_tab1
FIELDS key_field, char1, char2, num1, num2
WHERE num1 > 3
INTO TABLE @DATA(itab_select1).
out->write( data = itab_select1 name = `itab_select1` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `26) Sequentially adding multiple rows from a database table to an internal table` ) ).
DATA itab TYPE TABLE OF zdemo_abap_tab1 WITH NON-UNIQUE KEY client key_field.
SELECT FROM zdemo_abap_tab1
FIELDS *
WHERE num1 > 3
INTO @DATA(struc_select).
IF sy-subrc = 0.
"Some modifications on the read lines (capitalizing letters)
struc_select-char1 = to_upper( struc_select-char1 ).
struc_select-char2 = to_upper( struc_select-char2 ).
"Adding modified line to an internal table
APPEND struc_select TO itab.
ENDIF.
ENDSELECT.
out->write( data = itab name = `itab` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `27) Adding multiple rows from a database table ` &&
`to an internal table that has a different line type than the ` &&
`database table and keeping existing table content` ) ).
SELECT FROM zdemo_abap_tab2
FIELDS *
WHERE num1 > 10
APPENDING CORRESPONDING FIELDS OF TABLE @itab.
out->write( data = itab name = `itab` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `28) Adding multiple rows from a database table ` &&
`to an internal table that has a different line type than the ` &&
`database table and deleting existing table content` ) ).
SELECT FROM zdemo_abap_tab2
FIELDS *
WHERE num1 > 10
INTO CORRESPONDING FIELDS OF TABLE @itab.
out->write( data = itab name = `itab` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `29) Adding multiple rows from an internal table ` &&
`to an internal table using SELECT` ) ).
SELECT key_field, char1, char2, num1, num2
FROM @itab AS itab_alias
INTO TABLE @DATA(itab_clone).
out->write( data = itab_clone name = `itab_clone` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `30) Combining data of multiple tables into an` &&
` internal table using an inner join` ) ).
"Filling table to be selected from
itab = VALUE #( ( key_field = 500 char1 = 'uuu' char2 = 'vvv'
num1 = 501 num2 = 502 )
( key_field = 600 char1 = 'www' char2 = 'xxx'
num1 = 601 num2 = 602 ) ).
"SELECT list includes fields from both tables
"If there are no equivalent entries in the first or second table,
"the rows are not joined.
SELECT itab_alias1~key_field, itab_alias1~char2,
zdemo_abap_tab2~numlong
FROM @itab AS itab_alias1
INNER JOIN zdemo_abap_tab2
ON itab_alias1~key_field = zdemo_abap_tab2~key_field
INTO TABLE @DATA(join_result).
out->write( data = join_result name = `join_result` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `31) Filling internal table ` &&
`using a subquery (1)` ) ).
"A subquery is specified in the WHERE clause
"Here, data is selected from a database table depending on
"whether the value of a certain field is not among the
"values specified in parentheses.
SELECT key_field, char1, numlong
FROM zdemo_abap_tab2
WHERE char1 NOT IN ( 'iii', 'mmm', 'ooo', 'ppp' )
INTO TABLE @DATA(subquery_result1).
out->write( data = subquery_result1 name = `subquery_result1` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `32) Filling internal table ` &&
`using a subquery (2)` ) ).
"A subquery using EXISTS in the WHERE clause.
"In the example, data is selected from a database table depending
"on the existence of data in an internal table. Only if a line
"with a matching value of the specified field exists in both
"database and internal table, data is read.
SELECT key_field, numlong
FROM zdemo_abap_tab2
WHERE EXISTS
( SELECT 'X' FROM @itab AS itab_alias2
WHERE key_field = zdemo_abap_tab2~key_field )
INTO TABLE @DATA(subquery_result2).
out->write( data = subquery_result2 name = `subquery_result2` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `33) Filling an internal table from a table ` &&
`depending on the existence of data in another internal table ` &&
`using the addition FOR ALL ENTRIES` ) ).
"In the example, data is selected from a database table depending
"on the existence of data in an internal table. Only if a line
"with a matching value of the specified field exists in both
"database and internal table, data is read.
"Ensure that the internal table from which to read is not initial.
IF ( 0 < lines( itab ) ).
SELECT key_field, char1, numlong
FROM zdemo_abap_tab2
FOR ALL ENTRIES IN @itab
WHERE key_field = @itab-key_field
INTO TABLE @DATA(select_result).
ENDIF.
out->write( data = select_result name = `select_result` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `34) Adding content from a database to internal` &&
` table by using alias names in the SELECT list` ) ).
DATA itab2 TYPE TABLE OF zdemo_abap_tab2 WITH EMPTY KEY.
"Specifying alias names can help fill an existing internal
"table that has not a matching line type to the database table.
"Here, two fields are specified with an alias name to match the
"names of components contained in the existing internal table.
"The individual types of the fields match, too.
SELECT key_field, char2 AS char1, num2 AS num1
FROM zdemo_abap_tab1
INTO CORRESPONDING FIELDS OF TABLE @itab2 UP TO 3 ROWS.
out->write( data = itab2 name = `itab2` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `35) FILTER: Filtering internal table by condition` ) ).
"This section covers multiple examples demonstrating the syntactical variety
"of the FILTER operator.
TYPES: BEGIN OF fi_str,
a TYPE i,
b TYPE c LENGTH 3,
c TYPE c LENGTH 3,
END OF fi_str.
"basic form, condition created with single values
"itab must have at least one sorted key or one hash key used for access.
"This variant of the filter operator is not possible for an internal table itab without a sorted key or hash key.
DATA fi_tab1 TYPE SORTED TABLE OF fi_str WITH NON-UNIQUE KEY a.
DATA fi_tab2 TYPE STANDARD TABLE OF fi_str WITH NON-UNIQUE SORTED KEY sec_key COMPONENTS a.
DATA fi_tab3 TYPE HASHED TABLE OF fi_str WITH UNIQUE KEY a.
"Filling internal tables
fi_tab1 = VALUE #( ( a = 1 b = 'aaa' c = 'abc' )
( a = 2 b = 'bbb' c = 'def' )
( a = 3 b = 'ccc' c = 'hij' )
( a = 4 b = 'ddd' c = 'klm' )
( a = 5 b = 'eee' c = 'nop' ) ).
fi_tab2 = fi_tab1.
fi_tab3 = fi_tab1.
"The lines meeting the condition are respected.
"Note: The source table must have at least one sorted or hashed key.
"Here, the primary key is used
DATA(f1) = FILTER #( fi_tab1 WHERE a >= 3 ).
out->write( data = f1 name = `f1` ).
out->write( |\n| ).
"USING KEY primary_key explicitly specified; same as above
DATA(f2) = FILTER #( fi_tab1 USING KEY primary_key WHERE a >= 3 ).
out->write( data = f2 name = `f2` ).
out->write( |\n| ).
"EXCEPT addition
DATA(f3) = FILTER #( fi_tab1 EXCEPT WHERE a >= 3 ).
out->write( data = f3 name = `f3` ).
out->write( |\n| ).
DATA(f4) = FILTER #( fi_tab1 EXCEPT USING KEY primary_key WHERE a >= 3 ).
out->write( data = f4 name = `f4` ).
out->write( |\n| ).
"Secondary table key specified after USING KEY
DATA(f5) = FILTER #( fi_tab2 USING KEY sec_key WHERE a >= 4 ).
out->write( data = f5 name = `f5` ).
out->write( |\n| ).
DATA(f6) = FILTER #( fi_tab2 EXCEPT USING KEY sec_key WHERE a >= 3 ).
out->write( data = f6 name = `f6` ).
out->write( |\n| ).
"Note: In case of a hash key, exactly one comparison expression for each key
"component is allowed; only = as comparison operator possible.
DATA(f7) = FILTER #( fi_tab3 WHERE a = 3 ).
out->write( data = f7 name = `f7` ).
out->write( |\n| ).
"Using a filter table
"In the WHERE condition, the columns of source and filter table are compared.
"Those lines in the source table are used for which at least one line in the
"filter table meets the condition. EXCEPT and USING KEY are also possible.
"Declaring and filling filter tables
DATA filter_tab1 TYPE SORTED TABLE OF i
WITH NON-UNIQUE KEY table_line.
DATA filter_tab2 TYPE STANDARD TABLE OF i
WITH EMPTY KEY
WITH UNIQUE SORTED KEY line COMPONENTS table_line.
filter_tab1 = VALUE #( ( 3 ) ( 5 ) ).
filter_tab2 = filter_tab1.
DATA(f8) = FILTER #( fi_tab1 IN filter_tab1 WHERE a = table_line ).
out->write( data = f8 name = `f8` ).
out->write( |\n| ).
"EXCEPT addition
DATA(f9) = FILTER #( fi_tab1 EXCEPT IN filter_tab1 WHERE a = table_line ).
out->write( data = f9 name = `f9` ).
out->write( |\n| ).
"USING KEY is specified for the filter table
DATA(f10) = FILTER #( fi_tab2 IN filter_tab2 USING KEY line WHERE a = table_line ).
out->write( data = f10 name = `f10` ).
out->write( |\n| ).
"USING KEY is specified for the source table, including EXCEPT
DATA(f11) = FILTER #( fi_tab2 USING KEY sec_key EXCEPT IN filter_tab2 WHERE a = table_line ).
out->write( data = f11 name = `f11` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `36) Inserting data into an internal table ` &&
`using a COLLECT statement` ) ).
"Internal table to work with
DATA itab_num TYPE SORTED TABLE OF l_type2
WITH UNIQUE KEY key_field.
itab_num = VALUE #( ( key_field = 1 num1 = 2 num2 = 3 )
( key_field = 2 num1 = 4 num2 = 5 )
( key_field = 3 num1 = 6 num2 = 7 ) ).
"Values of numeric components are added to the
"corresponding values in an internal table
COLLECT VALUE l_type2( key_field = 1 num1 = 10 num2 = 10 )
INTO itab_num.
out->write( data = itab_num name = `itab_num` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `37) Reading from internal tables` ) ).
"Filling internal tables
it_st = VALUE #( ( a = 1 b = 'aaa' c = 'bbb' d = 'ccc' )
( a = 2 b = 'ddd' c = 'eee' d = 'fff' )
( a = 3 b = 'ggg' c = 'hhh' d = 'iii' )
( a = 4 b = 'jjj' c = 'kkk' d = 'lll' ) ).
"Declaring demo sorted/hashed tables having primary and
"secondary keys as well as alias names defined
DATA it_so_sec TYPE SORTED TABLE OF struc1
WITH NON-UNIQUE KEY primary_key ALIAS pk COMPONENTS a
WITH NON-UNIQUE SORTED KEY sec_key ALIAS sk COMPONENTS b.
DATA it_ha_sec TYPE HASHED TABLE OF struc1
WITH UNIQUE KEY primary_key ALIAS pkh COMPONENTS a
WITH NON-UNIQUE SORTED KEY sec_key_h ALIAS skh COMPONENTS b.
"Filling internal table
it_so_sec = VALUE #( ( a = 1 b = 'bbb' c = '###' d = '###' )
( a = 2 b = 'ccc' c = '###' d = '###' )
( a = 3 b = 'aaa' c = 'zzz' d = '###' )
( a = 4 b = 'ddd' c = '###' d = '###' ) ).
"Filling internal table with the content above
it_ha_sec = it_so_sec.
out->write( `Original table content` ).
out->write( |\n| ).
out->write( |\n| ).
out->write( data = it_so_sec name = `it_so_sec` ).
out->write( |\n| ).
out->write( data = it_ha_sec name = `it_ha_sec` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `38) Reading a single line into target area` ) ).
"The examples anticipate the reading of a line by index since the
"syntax requires to specify the reading via index or key. Both
"inline declarations and existing target areas are demonstrated.
"Work area
READ TABLE it_so_sec INTO DATA(wa1) INDEX 1.
DATA wa2 LIKE LINE OF it_so_sec.
"The addition TRANSPORTING specifies which components are to be
"respected for the copying. If it is not specified, all components
"are respected.
READ TABLE it_so_sec INTO wa2 INDEX 2 TRANSPORTING a b c.
"Field symbol
READ TABLE it_so_sec ASSIGNING FIELD-SYMBOL(<fs>) INDEX 3.
FIELD-SYMBOLS <fs2> LIKE LINE OF it_so_sec.
READ TABLE it_st ASSIGNING <fs2> INDEX 1.
"Data reference variable
READ TABLE it_so_sec REFERENCE INTO DATA(dref) INDEX 4.
DATA dref2 LIKE REF TO wa2.
READ TABLE it_so_sec REFERENCE INTO dref2 INDEX 2.
out->write( data = wa1 name = `wa1` ).
out->write( |\n| ).
out->write( data = wa2 name = `wa2` ).
out->write( |\n| ).
out->write( data = <fs> name = `<fs>` ).
out->write( |\n| ).
out->write( data = <fs2> name = `<fs2>` ).
out->write( |\n| ).
out->write( data = dref->* name = `dref->*` ).
out->write( |\n| ).
out->write( data = dref2->* name = `dref2->*` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `Reading a single line via index ...` ) ).
out->write( |39) ... using READ TABLE\n\n| ).
"Primary table index used implicitly
READ TABLE it_so_sec INTO DATA(wa3) INDEX 1.
"Primary table index used implicitly; result here: same as above
READ TABLE it_so_sec INTO DATA(wa4) INDEX 1 USING KEY primary_key.
"Primary table key alias; result here: same as above
READ TABLE it_so_sec INTO DATA(wa5) INDEX 1 USING KEY pk.
"Secondary table key; secondary table index used
READ TABLE it_so_sec INTO DATA(wa6) INDEX 1 USING KEY sec_key.
"Secondary table key alias; secondary table index used
"result here: same as above
READ TABLE it_so_sec INTO DATA(wa7) INDEX 1 USING KEY sk.
"Index access for hashed tables using secondary table index
READ TABLE it_ha_sec INTO DATA(wa8) INDEX 1 USING KEY sec_key_h.
out->write( data = wa3 name = `wa3` ).
out->write( |\n| ).
out->write( data = wa4 name = `wa4` ).
out->write( |\n| ).
out->write( data = wa5 name = `wa5` ).
out->write( |\n| ).
out->write( data = wa6 name = `wa6` ).
out->write( |\n| ).
out->write( data = wa7 name = `wa7` ).
out->write( |\n| ).
out->write( data = wa8 name = `wa8` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `40) ... table expressions (1)` ) ).
"Reading via index; primary table index is used implicitly
DATA(lv1) = it_so_sec[ 2 ].
"Note: A line that is not found results in an runtime error.
DATA(idx) = 10.
TRY.
DATA(lv2) = it_so_sec[ idx ].
CATCH cx_sy_itab_line_not_found.
DATA(error) = |Line with index { idx } does not exist.|.
ENDTRY.
"Reading via index and specifying the table index (via the key)
"to be read from
DATA(lv3) = it_so_sec[ KEY primary_key INDEX 1 ].
DATA(lv4) = it_so_sec[ KEY sec_key INDEX 4 ].
"Hashed table example (secondary table index)
DATA(lv5) = it_ha_sec[ KEY sec_key_h INDEX 3 ].
out->write( data = lv1 name = `lv1` ).
out->write( |\n| ).
IF lv2 IS NOT INITIAL.
out->write( data = lv2 name = `lv2` ).
out->write( |\n| ).
ENDIF.
IF error IS NOT INITIAL.
out->write( data = error name = `error` ).
out->write( |\n| ).
ENDIF.
out->write( data = lv3 name = `lv3` ).
out->write( |\n| ).
out->write( data = lv4 name = `lv4` ).
out->write( |\n| ).
out->write( data = lv5 name = `lv5` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `41) ... table expressions (2)` ) ).
"Copying a table line via table expression and embedding in
"a constructor expression
DATA(lv6) = VALUE #( it_so_sec[ 2 ] ).
"Reading into data reference variable using the REF operator
DATA(dref3) = REF #( it_so_sec[ 4 ] ).
"OPTIONAL/DEFAULT additions: An unsuccessful reading operation
"does not raise the exception; returns either an initial or
"default line in case of an unsuccessful reading operation
DATA(lv7) = VALUE #( it_so_sec[ 10 ] OPTIONAL ).
DATA(lv8) = VALUE #( it_so_sec[ 10 ] DEFAULT it_so_sec[ 2 ] ).
out->write( data = lv6 name = `lv6` ).
out->write( |\n| ).
out->write( data = dref3->* name = `dref3->*` ).
out->write( |\n| ).
out->write( data = lv7 name = `lv7` ).
out->write( |\n| ).
out->write( data = lv8 name = `lv8` ).
**********************************************************************
out->write( zcl_demo_abap_aux=>heading( `Reading a single line via table keys ...` ) ).
out->write( |42) ... using READ TABLE (1)\n| ).
"Primary table key (COMPONENTS addition is optional)
READ TABLE it_so_sec INTO DATA(wa9)
WITH TABLE KEY primary_key COMPONENTS a = 1.
READ TABLE it_so_sec INTO DATA(wa10) WITH TABLE KEY a = 2.
"Primary table key alias
READ TABLE it_so_sec INTO DATA(wa11)