@linkup-ai/abap-ai 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +384 -0
  2. package/dist/adt-client.js +364 -0
  3. package/dist/cli/activate.js +113 -0
  4. package/dist/cli/init.js +333 -0
  5. package/dist/cli/remove.js +80 -0
  6. package/dist/cli/status.js +229 -0
  7. package/dist/cli/systems.js +68 -0
  8. package/dist/cli.js +81 -0
  9. package/dist/index.js +1318 -0
  10. package/dist/knowledge/abap/abap-dictionary.md +199 -0
  11. package/dist/knowledge/abap/abap-sql.md +296 -0
  12. package/dist/knowledge/abap/amdp.md +273 -0
  13. package/dist/knowledge/abap/clean-code.md +293 -0
  14. package/dist/knowledge/abap/cloud-background-processing.md +250 -0
  15. package/dist/knowledge/abap/cloud-communication.md +265 -0
  16. package/dist/knowledge/abap/cloud-development.md +176 -0
  17. package/dist/knowledge/abap/cloud-extensibility.md +252 -0
  18. package/dist/knowledge/abap/cloud-released-apis.md +261 -0
  19. package/dist/knowledge/abap/constructor-expressions.md +289 -0
  20. package/dist/knowledge/abap/enhancements.md +232 -0
  21. package/dist/knowledge/abap/exceptions.md +271 -0
  22. package/dist/knowledge/abap/internal-tables.md +205 -0
  23. package/dist/knowledge/abap/object-orientation.md +298 -0
  24. package/dist/knowledge/abap/performance.md +216 -0
  25. package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
  26. package/dist/knowledge/abap/rap-business-events.md +216 -0
  27. package/dist/knowledge/abap/rap-draft.md +191 -0
  28. package/dist/knowledge/abap/rap-eml.md +453 -0
  29. package/dist/knowledge/abap/rap-end-to-end.md +486 -0
  30. package/dist/knowledge/abap/rap-feature-control.md +185 -0
  31. package/dist/knowledge/abap/rap-numbering.md +280 -0
  32. package/dist/knowledge/abap/rap-service-exposure.md +163 -0
  33. package/dist/knowledge/abap/rap-unmanaged.md +468 -0
  34. package/dist/knowledge/abap/string-processing.md +180 -0
  35. package/dist/knowledge/abap/unit-testing.md +303 -0
  36. package/dist/knowledge/abap-cds/access-control.md +241 -0
  37. package/dist/knowledge/abap-cds/annotations.md +331 -0
  38. package/dist/knowledge/abap-cds/associations.md +254 -0
  39. package/dist/knowledge/abap-cds/expressions.md +230 -0
  40. package/dist/knowledge/abap-cds/functions.md +245 -0
  41. package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
  42. package/dist/knowledge/cap/authentication.md +278 -0
  43. package/dist/knowledge/cap/cdl-syntax.md +247 -0
  44. package/dist/knowledge/cap/cql-queries.md +266 -0
  45. package/dist/knowledge/cap/deployment.md +343 -0
  46. package/dist/knowledge/cap/event-handlers.md +287 -0
  47. package/dist/knowledge/cap/fiori-integration.md +303 -0
  48. package/dist/knowledge/cap/service-definitions.md +287 -0
  49. package/dist/knowledge/fiori/annotations.md +347 -0
  50. package/dist/knowledge/fiori/deployment.md +340 -0
  51. package/dist/knowledge/fiori/fiori-elements.md +332 -0
  52. package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
  53. package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
  54. package/dist/knowledge/fiori/ui5-controllers.md +358 -0
  55. package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
  56. package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
  57. package/dist/knowledge/fiori/ui5-manifest.md +411 -0
  58. package/dist/knowledge/fiori/ui5-routing.md +303 -0
  59. package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
  60. package/dist/logger.js +114 -0
  61. package/dist/system-profile.js +207 -0
  62. package/dist/tools/abap-doc.js +72 -0
  63. package/dist/tools/abapgit.js +161 -0
  64. package/dist/tools/activate.js +68 -0
  65. package/dist/tools/atc-check.js +117 -0
  66. package/dist/tools/auth-object.js +56 -0
  67. package/dist/tools/breakpoints.js +76 -0
  68. package/dist/tools/call-hierarchy.js +84 -0
  69. package/dist/tools/cds-annotations.js +98 -0
  70. package/dist/tools/cds-dependencies.js +65 -0
  71. package/dist/tools/check.js +47 -0
  72. package/dist/tools/code-completion.js +70 -0
  73. package/dist/tools/code-coverage.js +111 -0
  74. package/dist/tools/create-amdp.js +111 -0
  75. package/dist/tools/create-dcl.js +81 -0
  76. package/dist/tools/create-transport.js +38 -0
  77. package/dist/tools/create.js +285 -0
  78. package/dist/tools/data-preview.js +37 -0
  79. package/dist/tools/delete.js +45 -0
  80. package/dist/tools/deploy-bsp.js +298 -0
  81. package/dist/tools/discovery.js +59 -0
  82. package/dist/tools/element-info.js +93 -0
  83. package/dist/tools/enhancements.js +186 -0
  84. package/dist/tools/extract-method.js +44 -0
  85. package/dist/tools/function-group.js +59 -0
  86. package/dist/tools/knowledge.js +275 -0
  87. package/dist/tools/lock-object.js +75 -0
  88. package/dist/tools/message-class.js +67 -0
  89. package/dist/tools/navigate.js +80 -0
  90. package/dist/tools/number-range.js +57 -0
  91. package/dist/tools/object-documentation.js +43 -0
  92. package/dist/tools/object-structure.js +78 -0
  93. package/dist/tools/object-versions.js +57 -0
  94. package/dist/tools/package-contents.js +60 -0
  95. package/dist/tools/pretty-printer.js +35 -0
  96. package/dist/tools/publish-binding.js +49 -0
  97. package/dist/tools/quick-fix.js +69 -0
  98. package/dist/tools/read.js +167 -0
  99. package/dist/tools/refactor-rename.js +60 -0
  100. package/dist/tools/release-transport.js +24 -0
  101. package/dist/tools/released-apis.js +51 -0
  102. package/dist/tools/repository-tree.js +90 -0
  103. package/dist/tools/scaffold-rap.js +642 -0
  104. package/dist/tools/search.js +73 -0
  105. package/dist/tools/shared/data-format.js +101 -0
  106. package/dist/tools/sql-console.js +17 -0
  107. package/dist/tools/system-info.js +270 -0
  108. package/dist/tools/traces.js +66 -0
  109. package/dist/tools/transport-contents.js +83 -0
  110. package/dist/tools/transports.js +67 -0
  111. package/dist/tools/unit-test.js +135 -0
  112. package/dist/tools/where-used.js +59 -0
  113. package/dist/tools/write.js +101 -0
  114. package/package.json +49 -0
@@ -0,0 +1,271 @@
1
+ # Exceptions — class-based, message class, RAP reporting
2
+
3
+ ## Exception Hierarchy
4
+
5
+ ```
6
+ CX_ROOT (abstract)
7
+ ├── CX_STATIC_CHECK — caller MUST handle (compile-time check)
8
+ ├── CX_DYNAMIC_CHECK — caller SHOULD handle (runtime check)
9
+ └── CX_NO_CHECK — programming errors (should not catch)
10
+ ```
11
+
12
+ ## Defining Exception Class
13
+
14
+ ```abap
15
+ CLASS zcx_order_error DEFINITION
16
+ INHERITING FROM cx_static_check
17
+ PUBLIC FINAL CREATE PUBLIC.
18
+
19
+ PUBLIC SECTION.
20
+ INTERFACES if_t100_message.
21
+ INTERFACES if_t100_dyn_msg.
22
+
23
+ CONSTANTS:
24
+ BEGIN OF customer_not_found,
25
+ msgid TYPE symsgid VALUE 'ZORDER',
26
+ msgno TYPE symsgno VALUE '001',
27
+ attr1 TYPE scx_attrname VALUE 'MV_CUSTOMER_ID',
28
+ attr2 TYPE scx_attrname VALUE '',
29
+ attr3 TYPE scx_attrname VALUE '',
30
+ attr4 TYPE scx_attrname VALUE '',
31
+ END OF customer_not_found,
32
+ BEGIN OF invalid_amount,
33
+ msgid TYPE symsgid VALUE 'ZORDER',
34
+ msgno TYPE symsgno VALUE '002',
35
+ attr1 TYPE scx_attrname VALUE 'MV_AMOUNT',
36
+ attr2 TYPE scx_attrname VALUE '',
37
+ attr3 TYPE scx_attrname VALUE '',
38
+ attr4 TYPE scx_attrname VALUE '',
39
+ END OF invalid_amount.
40
+
41
+ DATA mv_customer_id TYPE kunnr READ-ONLY.
42
+ DATA mv_amount TYPE netwr READ-ONLY.
43
+
44
+ METHODS constructor
45
+ IMPORTING textid LIKE if_t100_message=>t100key OPTIONAL
46
+ previous LIKE previous OPTIONAL
47
+ mv_customer_id TYPE kunnr OPTIONAL
48
+ mv_amount TYPE netwr OPTIONAL.
49
+ ENDCLASS.
50
+
51
+ CLASS zcx_order_error IMPLEMENTATION.
52
+ METHOD constructor.
53
+ super->constructor( previous = previous ).
54
+ me->mv_customer_id = mv_customer_id.
55
+ me->mv_amount = mv_amount.
56
+ CLEAR me->textid.
57
+ IF textid IS INITIAL.
58
+ if_t100_message~t100key = if_t100_message=>default_textid.
59
+ ELSE.
60
+ if_t100_message~t100key = textid.
61
+ ENDIF.
62
+ ENDMETHOD.
63
+ ENDCLASS.
64
+ ```
65
+
66
+ ## Raising Exceptions
67
+
68
+ ```abap
69
+ " With text ID (message class)
70
+ RAISE EXCEPTION TYPE zcx_order_error
71
+ EXPORTING textid = zcx_order_error=>customer_not_found
72
+ mv_customer_id = lv_customer.
73
+
74
+ " With previous (chained)
75
+ TRY.
76
+ lo_service->process( ).
77
+ CATCH cx_static_check INTO DATA(lx_prev).
78
+ RAISE EXCEPTION TYPE zcx_order_error
79
+ EXPORTING textid = zcx_order_error=>invalid_amount
80
+ previous = lx_prev
81
+ mv_amount = lv_amount.
82
+ ENDTRY.
83
+
84
+ " Quick message (without custom exception class)
85
+ RAISE EXCEPTION TYPE cx_abap_message_digest
86
+ EXPORTING text = |Customer { lv_id } not found|.
87
+ ```
88
+
89
+ ## Catching Exceptions
90
+
91
+ ```abap
92
+ TRY.
93
+ lo_processor->execute( iv_data = lv_input ).
94
+ CATCH zcx_order_error INTO DATA(lx_order).
95
+ DATA(lv_msg) = lx_order->get_text( ).
96
+ DATA(lv_long) = lx_order->get_longtext( ).
97
+ CATCH cx_static_check INTO DATA(lx_generic).
98
+ " Fallback for any checked exception
99
+ ENDTRY.
100
+
101
+ " Multiple CATCH
102
+ TRY.
103
+ process( ).
104
+ CATCH zcx_order_error INTO DATA(lx1).
105
+ " Handle order errors
106
+ CATCH zcx_auth_error INTO DATA(lx2).
107
+ " Handle auth errors
108
+ CATCH cx_static_check INTO DATA(lx3).
109
+ " Handle all other checked exceptions
110
+ ENDTRY.
111
+
112
+ " RETRY
113
+ TRY.
114
+ lo_api->call( ).
115
+ CATCH cx_sy_remote_call_error.
116
+ IF lv_retries < 3.
117
+ lv_retries += 1.
118
+ RETRY.
119
+ ENDIF.
120
+ ENDTRY.
121
+
122
+ " CLEANUP (runs before leaving TRY block on exception)
123
+ TRY.
124
+ lo_file->open( ).
125
+ lo_file->write( ).
126
+ CLEANUP.
127
+ lo_file->close( ).
128
+ ENDTRY.
129
+ ```
130
+
131
+ ## Message Class (SE91)
132
+
133
+ ```abap
134
+ " Message class ZORDER:
135
+ " 001: Customer &1 not found
136
+ " 002: Amount &1 is invalid
137
+ " 003: Order &1 created successfully
138
+
139
+ " Using in code
140
+ MESSAGE e001(zorder) WITH lv_customer INTO DATA(lv_msg).
141
+
142
+ " Accessing SY-MSG* after MESSAGE ... INTO
143
+ " sy-msgid = 'ZORDER'
144
+ " sy-msgno = '001'
145
+ " sy-msgty = 'E'
146
+ " sy-msgv1 = lv_customer
147
+ ```
148
+
149
+ ## RAP — Error Reporting in Validations
150
+
151
+ ```abap
152
+ METHOD validate_customer.
153
+ READ ENTITIES OF ZI_Order IN LOCAL MODE
154
+ ENTITY Order FIELDS ( CustomerID )
155
+ WITH CORRESPONDING #( keys )
156
+ RESULT DATA(orders).
157
+
158
+ LOOP AT orders INTO DATA(order).
159
+ APPEND VALUE #( %tky = order-%tky ) TO result.
160
+
161
+ IF order-CustomerID IS INITIAL.
162
+ " Using message class
163
+ APPEND VALUE #(
164
+ %tky = order-%tky
165
+ %state_area = 'VALIDATE_CUSTOMER'
166
+ %msg = NEW zcm_order(
167
+ textid = zcm_order=>customer_required
168
+ severity = if_abap_behv_message=>severity-error )
169
+ %element-CustomerID = if_abap_behv=>mk-on
170
+ ) TO reported-order.
171
+
172
+ APPEND VALUE #( %tky = order-%tky ) TO failed-order.
173
+ ENDIF.
174
+ ENDLOOP.
175
+ ENDMETHOD.
176
+ ```
177
+
178
+ ## RAP — Message Class for RAP (zcm_*)
179
+
180
+ ```abap
181
+ " Convention: ZCM_<bo_name> inheriting from CX_STATIC_CHECK
182
+ CLASS zcm_order DEFINITION
183
+ INHERITING FROM cx_static_check
184
+ PUBLIC FINAL CREATE PUBLIC.
185
+
186
+ PUBLIC SECTION.
187
+ INTERFACES if_abap_behv_message.
188
+ INTERFACES if_t100_message.
189
+ INTERFACES if_t100_dyn_msg.
190
+
191
+ CONSTANTS:
192
+ BEGIN OF customer_required,
193
+ msgid TYPE symsgid VALUE 'ZORDER',
194
+ msgno TYPE symsgno VALUE '010',
195
+ attr1 TYPE scx_attrname VALUE '',
196
+ attr2 TYPE scx_attrname VALUE '',
197
+ attr3 TYPE scx_attrname VALUE '',
198
+ attr4 TYPE scx_attrname VALUE '',
199
+ END OF customer_required.
200
+
201
+ METHODS constructor
202
+ IMPORTING severity TYPE if_abap_behv_message=>t_severity DEFAULT if_abap_behv_message=>severity-error
203
+ textid LIKE if_t100_message=>t100key OPTIONAL
204
+ previous LIKE previous OPTIONAL.
205
+ ENDCLASS.
206
+
207
+ CLASS zcm_order IMPLEMENTATION.
208
+ METHOD constructor.
209
+ super->constructor( previous = previous ).
210
+ if_abap_behv_message~m_severity = severity.
211
+ CLEAR me->textid.
212
+ IF textid IS INITIAL.
213
+ if_t100_message~t100key = if_t100_message=>default_textid.
214
+ ELSE.
215
+ if_t100_message~t100key = textid.
216
+ ENDIF.
217
+ ENDMETHOD.
218
+ ENDCLASS.
219
+ ```
220
+
221
+ ## Quick Messages in RAP (without custom message class)
222
+
223
+ ```abap
224
+ " new_message_with_text — simple, no message class needed
225
+ APPEND VALUE #(
226
+ %tky = order-%tky
227
+ %msg = new_message_with_text(
228
+ severity = if_abap_behv_message=>severity-error
229
+ text = |Customer { order-CustomerID } is invalid| )
230
+ %element-CustomerID = if_abap_behv=>mk-on
231
+ ) TO reported-order.
232
+
233
+ " new_message — using message class directly
234
+ APPEND VALUE #(
235
+ %tky = order-%tky
236
+ %msg = new_message(
237
+ id = 'ZORDER'
238
+ number = '001'
239
+ severity = if_abap_behv_message=>severity-error
240
+ v1 = order-CustomerID )
241
+ ) TO reported-order.
242
+ ```
243
+
244
+ ## Severity Levels
245
+
246
+ | Constant | Value | Fiori Display |
247
+ |----------|:-----:|---------------|
248
+ | `if_abap_behv_message=>severity-error` | 'E' | Red, blocks save |
249
+ | `if_abap_behv_message=>severity-warning` | 'W' | Yellow, allows save |
250
+ | `if_abap_behv_message=>severity-information` | 'I' | Blue, informational |
251
+ | `if_abap_behv_message=>severity-success` | 'S' | Green, success |
252
+
253
+ ## Rules
254
+ - Use `cx_static_check` for expected business errors (caller must handle)
255
+ - Use `cx_no_check` only for programming bugs (null reference, division by zero)
256
+ - RAP validations: NEVER raise exceptions — always use `reported` + `failed`
257
+ - RAP: use `%state_area` to group related messages (field group in Fiori)
258
+ - RAP: use `%element-FieldName = if_abap_behv=>mk-on` to highlight field in UI
259
+ - Prefer message class (SE91) over hardcoded text for i18n support
260
+ - Convention: `zcx_*` for general exceptions, `zcm_*` for RAP behavior messages
261
+
262
+ ## Anti-Patterns
263
+ | Anti-Pattern | Correct |
264
+ |---|---|
265
+ | `CATCH cx_root` everywhere | Catch specific exception types |
266
+ | Empty CATCH block | At minimum log or re-raise |
267
+ | `RAISE EXCEPTION` in RAP validation | Use `reported` + `failed` |
268
+ | Hardcoded text in `new_message_with_text` for production | Use message class for i18n |
269
+ | `cx_static_check` for programming errors | Use `cx_no_check` |
270
+ | Missing `%element` in RAP reported | Field not highlighted in Fiori UI |
271
+ | Missing `%state_area` in RAP reported | Messages not grouped properly |
@@ -0,0 +1,205 @@
1
+ # Internal Tables — declaration, access, iteration, performance
2
+
3
+ ## Table Types
4
+
5
+ ```abap
6
+ " Standard — index + key, non-unique, sequential processing
7
+ DATA zt_items TYPE STANDARD TABLE OF zs_item WITH EMPTY KEY.
8
+
9
+ " Sorted — index + key, binary search O(log n)
10
+ DATA zt_sorted TYPE SORTED TABLE OF zs_item WITH UNIQUE KEY id.
11
+ DATA zt_nonuniq TYPE SORTED TABLE OF zs_item WITH NON-UNIQUE KEY category.
12
+
13
+ " Hashed — key only, O(1) lookup, unique key required
14
+ DATA zt_hashed TYPE HASHED TABLE OF zs_item WITH UNIQUE KEY id.
15
+ ```
16
+
17
+ ## Declaration Patterns
18
+
19
+ ```abap
20
+ " Inline with VALUE
21
+ DATA(zt_names) = VALUE string_table( ( `Alpha` ) ( `Beta` ) ( `Gamma` ) ).
22
+
23
+ " Structured line type
24
+ DATA(zt_data) = VALUE zt_item_tab(
25
+ ( id = 1 name = `First` )
26
+ ( id = 2 name = `Second` ) ).
27
+
28
+ " Secondary keys
29
+ DATA zt_multi TYPE TABLE OF zs_item
30
+ WITH EMPTY KEY
31
+ WITH NON-UNIQUE SORTED KEY by_name COMPONENTS name
32
+ WITH UNIQUE HASHED KEY by_id COMPONENTS id.
33
+ ```
34
+
35
+ ## Populating Tables
36
+
37
+ ```abap
38
+ " VALUE with BASE (append)
39
+ zt_data = VALUE #( BASE zt_data ( id = 3 name = `Third` ) ).
40
+
41
+ " LINES OF (merge)
42
+ zt_data = VALUE #( BASE zt_data ( LINES OF zt_other ) ).
43
+
44
+ " FOR iteration
45
+ DATA(zt_gen) = VALUE zt_item_tab(
46
+ FOR i = 1 UNTIL i > 10
47
+ ( id = i name = |Entry { i }| ) ).
48
+
49
+ " FOR from source with WHERE
50
+ DATA(zt_active) = VALUE zt_item_tab(
51
+ FOR wa IN zt_source WHERE ( status = 'A' )
52
+ ( wa ) ).
53
+
54
+ " APPEND with field-symbol
55
+ APPEND INITIAL LINE TO zt_data ASSIGNING FIELD-SYMBOL(<zs_new>).
56
+ <zs_new>-id = 99.
57
+ ```
58
+
59
+ ## Reading Entries
60
+
61
+ ```abap
62
+ " Table expression — preferred
63
+ DATA(zs_line) = zt_data[ id = 1 ].
64
+ DATA(lv_name) = zt_data[ 1 ]-name.
65
+
66
+ " Safe access — OPTIONAL returns initial if not found
67
+ DATA(zs_safe) = VALUE #( zt_data[ id = 999 ] OPTIONAL ).
68
+
69
+ " Safe access — DEFAULT
70
+ DATA(zs_def) = VALUE #( zt_data[ id = 999 ] DEFAULT VALUE #( id = 0 ) ).
71
+
72
+ " Existence check
73
+ IF line_exists( zt_data[ id = 1 ] ).
74
+ ENDIF.
75
+
76
+ " Index lookup
77
+ DATA(lv_idx) = line_index( zt_data[ name = `First` ] ).
78
+
79
+ " Secondary key access
80
+ DATA(zs_by_name) = zt_multi[ KEY by_name name = `Alpha` ].
81
+
82
+ " READ TABLE with field-symbol (for modification)
83
+ READ TABLE zt_data ASSIGNING FIELD-SYMBOL(<zs_fs>) WITH KEY id = 1.
84
+ IF sy-subrc = 0.
85
+ <zs_fs>-name = `Updated`.
86
+ ENDIF.
87
+ ```
88
+
89
+ ## Modifying Entries
90
+
91
+ ```abap
92
+ " Direct via table expression
93
+ zt_data[ 1 ]-name = `Changed`.
94
+
95
+ " Via field-symbol in LOOP
96
+ LOOP AT zt_data ASSIGNING FIELD-SYMBOL(<zs_line>).
97
+ <zs_line>-name = to_upper( <zs_line>-name ).
98
+ ENDLOOP.
99
+
100
+ " MODIFY with WHERE
101
+ MODIFY zt_data FROM VALUE #( status = 'X' )
102
+ TRANSPORTING status WHERE category = 'A'.
103
+ ```
104
+
105
+ ## Deleting Entries
106
+
107
+ ```abap
108
+ DELETE zt_data WHERE status = 'D'.
109
+ DELETE TABLE zt_data WITH TABLE KEY id = 1.
110
+ DELETE ADJACENT DUPLICATES FROM zt_data COMPARING name.
111
+ FREE zt_data. " Clear + release memory
112
+ ```
113
+
114
+ ## Iteration
115
+
116
+ ```abap
117
+ " LOOP with field-symbol — preferred
118
+ LOOP AT zt_data ASSIGNING FIELD-SYMBOL(<zs_row>) WHERE status = 'A'.
119
+ ENDLOOP.
120
+
121
+ " LOOP with data reference
122
+ LOOP AT zt_data REFERENCE INTO DATA(zr_row).
123
+ zr_row->*-counter += 1.
124
+ ENDLOOP.
125
+
126
+ " LOOP using secondary key
127
+ LOOP AT zt_multi USING KEY by_name ASSIGNING FIELD-SYMBOL(<zs_named>)
128
+ WHERE name CS `test`.
129
+ ENDLOOP.
130
+
131
+ " Group processing
132
+ LOOP AT zt_data INTO DATA(zs_rep) GROUP BY ( cat = zs_rep-category
133
+ size = GROUP SIZE )
134
+ ASSIGNING FIELD-SYMBOL(<zg_grp>).
135
+ LOOP AT GROUP <zg_grp> ASSIGNING FIELD-SYMBOL(<zs_member>).
136
+ ENDLOOP.
137
+ ENDLOOP.
138
+ ```
139
+
140
+ ## FILTER Expression
141
+
142
+ ```abap
143
+ " Basic filter (requires sorted/hashed key)
144
+ DATA(zt_active) = FILTER #( zt_multi USING KEY by_name WHERE name = `Alpha` ).
145
+
146
+ " EXCEPT — exclude matching
147
+ DATA(zt_rest) = FILTER #( zt_multi EXCEPT WHERE status = 'A' ).
148
+
149
+ " Filter with IN (filter table)
150
+ DATA zt_fvals TYPE SORTED TABLE OF string WITH UNIQUE KEY table_line.
151
+ zt_fvals = VALUE #( ( `A` ) ( `B` ) ).
152
+ DATA(zt_matched) = FILTER #( zt_data IN zt_fvals WHERE status = table_line ).
153
+ ```
154
+
155
+ ## REDUCE Aggregation
156
+
157
+ ```abap
158
+ DATA(lv_sum) = REDUCE i( INIT s = 0
159
+ FOR wa IN zt_data
160
+ NEXT s = s + wa-amount ).
161
+
162
+ DATA(lv_max) = REDUCE i( INIT m = 0
163
+ FOR wa IN zt_data
164
+ NEXT m = COND #( WHEN wa-value > m THEN wa-value ELSE m ) ).
165
+
166
+ DATA(lv_csv) = REDUCE string( INIT str = ``
167
+ FOR wa IN zt_data
168
+ NEXT str = str && wa-name && `, ` ).
169
+ ```
170
+
171
+ ## Sorting
172
+
173
+ ```abap
174
+ SORT zt_data BY category ASCENDING amount DESCENDING.
175
+ SORT zt_data BY name AS TEXT STABLE.
176
+ ```
177
+
178
+ ---
179
+
180
+ ## Rules
181
+
182
+ - Use SORTED TABLE for frequent key lookups on medium tables
183
+ - Use HASHED TABLE for large tables with unique key access
184
+ - Always use FIELD-SYMBOL in LOOP when modifying rows
185
+ - Use table expressions `itab[ key = val ]` over READ TABLE for reads
186
+ - Use OPTIONAL or DEFAULT for safe access — avoids CX_SY_ITAB_LINE_NOT_FOUND
187
+ - Use secondary keys instead of repeated SORT for multiple access patterns
188
+ - Use FILTER with USING KEY for efficient subset extraction
189
+ - Check `IS NOT INITIAL` before FOR ALL ENTRIES (same principle applies)
190
+ - Prefer `FREE itab` over `CLEAR itab` when memory should be released
191
+
192
+ ## Anti-Patterns
193
+
194
+ | Anti-Pattern | Correct Approach |
195
+ |---|---|
196
+ | `READ TABLE ... INTO wa` then modify wa (copy, not reference) | `READ TABLE ... ASSIGNING FIELD-SYMBOL(<fs>)` |
197
+ | `LOOP AT itab INTO wa` for modification | `LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs>)` |
198
+ | `READ TABLE itab ... BINARY SEARCH` on unsorted standard table | Use SORTED TABLE or SORT before BINARY SEARCH |
199
+ | `LOOP AT + IF` to filter | `LOOP AT ... WHERE` or FILTER expression |
200
+ | `DESCRIBE TABLE itab LINES lv_count` | `lines( itab )` |
201
+ | `READ TABLE ... sy-subrc` just to check existence | `line_exists( itab[ ... ] )` |
202
+ | Nested LOOP AT for lookup (O(n*m)) | Use HASHED TABLE or secondary key for inner lookup |
203
+ | `DELETE ADJACENT DUPLICATES` without prior SORT | Always SORT first or use SORTED TABLE |
204
+ | `SELECT ... ENDSELECT` appending one by one | `SELECT ... INTO TABLE` |
205
+ | Using DEFAULT KEY on typed tables | Use EMPTY KEY or explicit key fields |