@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.
- package/README.md +384 -0
- package/dist/adt-client.js +364 -0
- package/dist/cli/activate.js +113 -0
- package/dist/cli/init.js +333 -0
- package/dist/cli/remove.js +80 -0
- package/dist/cli/status.js +229 -0
- package/dist/cli/systems.js +68 -0
- package/dist/cli.js +81 -0
- package/dist/index.js +1318 -0
- package/dist/knowledge/abap/abap-dictionary.md +199 -0
- package/dist/knowledge/abap/abap-sql.md +296 -0
- package/dist/knowledge/abap/amdp.md +273 -0
- package/dist/knowledge/abap/clean-code.md +293 -0
- package/dist/knowledge/abap/cloud-background-processing.md +250 -0
- package/dist/knowledge/abap/cloud-communication.md +265 -0
- package/dist/knowledge/abap/cloud-development.md +176 -0
- package/dist/knowledge/abap/cloud-extensibility.md +252 -0
- package/dist/knowledge/abap/cloud-released-apis.md +261 -0
- package/dist/knowledge/abap/constructor-expressions.md +289 -0
- package/dist/knowledge/abap/enhancements.md +232 -0
- package/dist/knowledge/abap/exceptions.md +271 -0
- package/dist/knowledge/abap/internal-tables.md +205 -0
- package/dist/knowledge/abap/object-orientation.md +298 -0
- package/dist/knowledge/abap/performance.md +216 -0
- package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
- package/dist/knowledge/abap/rap-business-events.md +216 -0
- package/dist/knowledge/abap/rap-draft.md +191 -0
- package/dist/knowledge/abap/rap-eml.md +453 -0
- package/dist/knowledge/abap/rap-end-to-end.md +486 -0
- package/dist/knowledge/abap/rap-feature-control.md +185 -0
- package/dist/knowledge/abap/rap-numbering.md +280 -0
- package/dist/knowledge/abap/rap-service-exposure.md +163 -0
- package/dist/knowledge/abap/rap-unmanaged.md +468 -0
- package/dist/knowledge/abap/string-processing.md +180 -0
- package/dist/knowledge/abap/unit-testing.md +303 -0
- package/dist/knowledge/abap-cds/access-control.md +241 -0
- package/dist/knowledge/abap-cds/annotations.md +331 -0
- package/dist/knowledge/abap-cds/associations.md +254 -0
- package/dist/knowledge/abap-cds/expressions.md +230 -0
- package/dist/knowledge/abap-cds/functions.md +245 -0
- package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
- package/dist/knowledge/cap/authentication.md +278 -0
- package/dist/knowledge/cap/cdl-syntax.md +247 -0
- package/dist/knowledge/cap/cql-queries.md +266 -0
- package/dist/knowledge/cap/deployment.md +343 -0
- package/dist/knowledge/cap/event-handlers.md +287 -0
- package/dist/knowledge/cap/fiori-integration.md +303 -0
- package/dist/knowledge/cap/service-definitions.md +287 -0
- package/dist/knowledge/fiori/annotations.md +347 -0
- package/dist/knowledge/fiori/deployment.md +340 -0
- package/dist/knowledge/fiori/fiori-elements.md +332 -0
- package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
- package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
- package/dist/knowledge/fiori/ui5-controllers.md +358 -0
- package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
- package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
- package/dist/knowledge/fiori/ui5-manifest.md +411 -0
- package/dist/knowledge/fiori/ui5-routing.md +303 -0
- package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
- package/dist/logger.js +114 -0
- package/dist/system-profile.js +207 -0
- package/dist/tools/abap-doc.js +72 -0
- package/dist/tools/abapgit.js +161 -0
- package/dist/tools/activate.js +68 -0
- package/dist/tools/atc-check.js +117 -0
- package/dist/tools/auth-object.js +56 -0
- package/dist/tools/breakpoints.js +76 -0
- package/dist/tools/call-hierarchy.js +84 -0
- package/dist/tools/cds-annotations.js +98 -0
- package/dist/tools/cds-dependencies.js +65 -0
- package/dist/tools/check.js +47 -0
- package/dist/tools/code-completion.js +70 -0
- package/dist/tools/code-coverage.js +111 -0
- package/dist/tools/create-amdp.js +111 -0
- package/dist/tools/create-dcl.js +81 -0
- package/dist/tools/create-transport.js +38 -0
- package/dist/tools/create.js +285 -0
- package/dist/tools/data-preview.js +37 -0
- package/dist/tools/delete.js +45 -0
- package/dist/tools/deploy-bsp.js +298 -0
- package/dist/tools/discovery.js +59 -0
- package/dist/tools/element-info.js +93 -0
- package/dist/tools/enhancements.js +186 -0
- package/dist/tools/extract-method.js +44 -0
- package/dist/tools/function-group.js +59 -0
- package/dist/tools/knowledge.js +275 -0
- package/dist/tools/lock-object.js +75 -0
- package/dist/tools/message-class.js +67 -0
- package/dist/tools/navigate.js +80 -0
- package/dist/tools/number-range.js +57 -0
- package/dist/tools/object-documentation.js +43 -0
- package/dist/tools/object-structure.js +78 -0
- package/dist/tools/object-versions.js +57 -0
- package/dist/tools/package-contents.js +60 -0
- package/dist/tools/pretty-printer.js +35 -0
- package/dist/tools/publish-binding.js +49 -0
- package/dist/tools/quick-fix.js +69 -0
- package/dist/tools/read.js +167 -0
- package/dist/tools/refactor-rename.js +60 -0
- package/dist/tools/release-transport.js +24 -0
- package/dist/tools/released-apis.js +51 -0
- package/dist/tools/repository-tree.js +90 -0
- package/dist/tools/scaffold-rap.js +642 -0
- package/dist/tools/search.js +73 -0
- package/dist/tools/shared/data-format.js +101 -0
- package/dist/tools/sql-console.js +17 -0
- package/dist/tools/system-info.js +270 -0
- package/dist/tools/traces.js +66 -0
- package/dist/tools/transport-contents.js +83 -0
- package/dist/tools/transports.js +67 -0
- package/dist/tools/unit-test.js +135 -0
- package/dist/tools/where-used.js +59 -0
- package/dist/tools/write.js +101 -0
- 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 |
|