423 lines
8.2 KiB
Markdown
423 lines
8.2 KiB
Markdown
# SAP ABAP Programming Reference
|
|
|
|
**Source**: [https://codezentrale.de/category/sap/sap-abap/](https://codezentrale.de/category/sap/sap-abap/)
|
|
**Language**: Translated from German
|
|
|
|
This reference covers ABAP programming patterns relevant to SAP HANA development.
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [SQL Operations](#sql-operations)
|
|
2. [Internal Tables](#internal-tables)
|
|
3. [String Operations](#string-operations)
|
|
4. [JSON Processing](#json-processing)
|
|
5. [XML Processing](#xml-processing)
|
|
6. [Regular Expressions](#regular-expressions)
|
|
7. [Exception Handling](#exception-handling)
|
|
8. [Performance Optimization](#performance-optimization)
|
|
|
|
---
|
|
|
|
## SQL Operations
|
|
|
|
### Open SQL
|
|
|
|
#### Common Table Expressions (CTE)
|
|
|
|
```abap
|
|
WITH
|
|
+cte1 AS ( SELECT * FROM table1 WHERE condition ),
|
|
+cte2 AS ( SELECT * FROM +cte1 WHERE condition2 )
|
|
SELECT * FROM +cte2 INTO TABLE @DATA(lt_result).
|
|
```
|
|
|
|
#### String Aggregation
|
|
|
|
```abap
|
|
SELECT STRING_AGG( field, ',' ) AS aggregated
|
|
FROM table
|
|
INTO @DATA(lv_result).
|
|
```
|
|
|
|
#### Global Temporary Tables (GTT)
|
|
|
|
```abap
|
|
" Use GTT for intermediate data storage
|
|
```
|
|
|
|
### Performance Comparison
|
|
|
|
| Method | Performance |
|
|
|--------|-------------|
|
|
| RANGE clause | ~0.086 seconds |
|
|
| FOR ALL ENTRIES | ~0.073 seconds |
|
|
| JOIN | ~0.012 seconds (fastest) |
|
|
|
|
**Best Practice**: Use JOINs instead of FOR ALL ENTRIES when possible.
|
|
|
|
### AMDP (ABAP Managed Database Procedures)
|
|
|
|
Convert RANGES to WHERE clause for AMDP:
|
|
|
|
```abap
|
|
" Using cl_shdb_seltab
|
|
DATA(lv_where) = cl_shdb_seltab=>combine_seltabs(
|
|
it_named_seltabs = VALUE #(
|
|
( name = 'FIELD' dref = REF #( lr_range ) )
|
|
)
|
|
)->sql_where_condition( ).
|
|
```
|
|
|
|
---
|
|
|
|
## Internal Tables
|
|
|
|
### TABLE_LINE Pseudo-Component
|
|
|
|
```abap
|
|
" Access complete row without structure
|
|
DATA(lv_vbeln) = it_vbeln[ table_line = '2345678901' ].
|
|
```
|
|
|
|
### REDUCE Operator
|
|
|
|
```abap
|
|
" Sum values
|
|
DATA(lv_sum) = REDUCE decfloat34(
|
|
INIT sum = CONV decfloat34( 0 )
|
|
FOR wa IN it_costs
|
|
NEXT sum = sum + wa-amount ).
|
|
```
|
|
|
|
### OPTIONAL Clause
|
|
|
|
```abap
|
|
" Avoid exceptions for missing entries
|
|
DATA(ls_person) = VALUE #( it_persons[ name = 'John' ] OPTIONAL ).
|
|
```
|
|
|
|
### DEFAULT VALUE
|
|
|
|
```abap
|
|
" Provide fallback value
|
|
DATA(ls_person) = VALUE #(
|
|
it_persons[ name = 'John' ]
|
|
DEFAULT VALUE #( name = '<empty>' age = -1 )
|
|
).
|
|
```
|
|
|
|
### BASE Operator
|
|
|
|
```abap
|
|
" Prepend existing data
|
|
it_result = VALUE #( BASE it_existing ( field = 'new' ) ).
|
|
```
|
|
|
|
### Line Index
|
|
|
|
```abap
|
|
" Get index without exceptions
|
|
DATA(lv_idx) = line_index( itab[ col = '123' ] ).
|
|
```
|
|
|
|
### Search Operations
|
|
|
|
```abap
|
|
" Case-insensitive search
|
|
FIND 'pattern' IN TABLE it_data IGNORING CASE.
|
|
|
|
" All occurrences
|
|
FIND ALL OCCURRENCES OF 'pattern' IN it_data
|
|
RESULTS DATA(lt_results).
|
|
```
|
|
|
|
---
|
|
|
|
## String Operations
|
|
|
|
### Substring Extraction
|
|
|
|
```abap
|
|
" Offset and length syntax
|
|
DATA(lv_first) = CONV string( lv_string+0(1) ).
|
|
DATA(lv_middle) = CONV string( lv_string+5(3) ).
|
|
```
|
|
|
|
### Transliteration
|
|
|
|
```abap
|
|
" Convert special characters
|
|
CALL FUNCTION 'SCP_REPLACE_STRANGE_CHARS'
|
|
EXPORTING
|
|
intext = lv_input
|
|
IMPORTING
|
|
outtext = lv_output.
|
|
" Result: ÄÖÜ → AeOeUe
|
|
```
|
|
|
|
### Codepage Conversion
|
|
|
|
```abap
|
|
" SAP codepage to HTTP encoding
|
|
DATA(lv_encoding) = cl_abap_codepage=>sap_codepage(
|
|
http_encoding = 'UTF-8' ).
|
|
```
|
|
|
|
### Pattern Matching (CP Operator)
|
|
|
|
```abap
|
|
" Wildcard matching
|
|
IF lv_string CP '*-*'. " Contains dash
|
|
IF lv_string CP '+++*'. " Three+ characters
|
|
```
|
|
|
|
### Message Text Splitting
|
|
|
|
```abap
|
|
" Distribute text across message fields
|
|
cl_message_helper=>set_msg_vars_for_clike(
|
|
EXPORTING i_text = lv_long_text ).
|
|
" Access via sy-msgv1, sy-msgv2, sy-msgv3, sy-msgv4
|
|
```
|
|
|
|
---
|
|
|
|
## JSON Processing
|
|
|
|
### ABAP to JSON
|
|
|
|
```abap
|
|
" Using xco_cp_json (modern)
|
|
DATA(lv_json) = xco_cp_json=>data->from_abap( ls_data )->to_string( ).
|
|
|
|
" Using /ui2/cl_json
|
|
DATA(lv_json) = /ui2/cl_json=>serialize(
|
|
data = ls_data
|
|
pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).
|
|
```
|
|
|
|
### JSON to ABAP
|
|
|
|
```abap
|
|
" Using xco_cp_json
|
|
xco_cp_json=>data->from_string( lv_json )->apply(
|
|
VALUE #( ( xco_cp_json=>transformation->boolean_to_abap_bool )
|
|
( xco_cp_json=>transformation->pascal_case_to_underscore ) )
|
|
)->write_to( REF #( ls_data ) ).
|
|
|
|
" Using /ui2/cl_json
|
|
/ui2/cl_json=>deserialize(
|
|
EXPORTING json = lv_json
|
|
CHANGING data = ls_data ).
|
|
```
|
|
|
|
### Internal Table to JSON
|
|
|
|
```abap
|
|
" Using transformation
|
|
CALL TRANSFORMATION id
|
|
SOURCE values = it_data
|
|
RESULT XML DATA(lv_json).
|
|
```
|
|
|
|
---
|
|
|
|
## XML Processing
|
|
|
|
### XML to Internal Table
|
|
|
|
```abap
|
|
" Using cl_xml_document
|
|
DATA(lo_xml) = cl_xml_document=>create( ).
|
|
lo_xml->import_from_file( lv_filename ).
|
|
|
|
CALL FUNCTION 'SMUM_XML_PARSE'
|
|
EXPORTING
|
|
xml_input = lo_xml->get_document_xml_string( )
|
|
TABLES
|
|
return = lt_return
|
|
xml_table = lt_xml_data.
|
|
```
|
|
|
|
### Display XML in Browser
|
|
|
|
```abap
|
|
cl_soap_xml_helper=>xml_show(
|
|
xml_xstring = lv_xml_xstring ).
|
|
```
|
|
|
|
### ABAP to XML
|
|
|
|
```abap
|
|
DATA(lv_xml) = cl_proxy_xml_transform=>abap_to_xml_xstring(
|
|
abap_data = ls_structure ).
|
|
```
|
|
|
|
---
|
|
|
|
## Regular Expressions
|
|
|
|
### Replace Non-Alphanumeric
|
|
|
|
```abap
|
|
REPLACE ALL OCCURRENCES OF REGEX '[^\w]+' IN lv_str WITH '_'.
|
|
```
|
|
|
|
### Using cl_abap_matcher
|
|
|
|
```abap
|
|
DATA(lo_matcher) = cl_abap_matcher=>create(
|
|
pattern = '<placeholder>'
|
|
text = lv_text
|
|
ignore_case = abap_true ).
|
|
|
|
IF lo_matcher->replace_all( ' and ' ) > 0.
|
|
DATA(lv_result) = lo_matcher->text.
|
|
ENDIF.
|
|
```
|
|
|
|
### Extract Submatches
|
|
|
|
```abap
|
|
DATA(lo_matcher) = cl_abap_matcher=>create(
|
|
pattern = '^/category/([0-9]+)/item/([0-9]+)$'
|
|
text = '/category/12345/item/12' ).
|
|
|
|
IF lo_matcher->match( ).
|
|
DATA(lv_category) = lo_matcher->get_submatch( 1 ). " 12345
|
|
DATA(lv_item) = lo_matcher->get_submatch( 2 ). " 12
|
|
ENDIF.
|
|
```
|
|
|
|
### Remove HTML Tags
|
|
|
|
```abap
|
|
DATA(lo_matcher) = cl_abap_matcher=>create(
|
|
pattern = '<([!A-Za-z][A-Za-z0-9]*)|</([A-Za-z][A-Za-z0-9]*)>'
|
|
text = lv_html ).
|
|
lo_matcher->replace_all( '' ).
|
|
```
|
|
|
|
### Common Patterns
|
|
|
|
| Pattern | Purpose |
|
|
|---------|---------|
|
|
| `[^\w]+` | Non-alphanumeric characters |
|
|
| `\s` | Whitespace |
|
|
| `[0-9]` | Digits |
|
|
| `^(AA\|BB).*$` | String prefix match |
|
|
| `\d{5}` | German postal code |
|
|
|
|
---
|
|
|
|
## Exception Handling
|
|
|
|
### TRY...CATCH Block
|
|
|
|
```abap
|
|
TRY.
|
|
" Risky operation
|
|
DATA(lv_result) = 1 / 0.
|
|
CATCH cx_sy_zerodivide INTO DATA(lx_error).
|
|
" Handle exception
|
|
DATA(lv_msg) = lx_error->get_text( ).
|
|
ENDTRY.
|
|
```
|
|
|
|
### Custom Exception Class
|
|
|
|
```abap
|
|
CLASS lcx_custom_error DEFINITION
|
|
INHERITING FROM cx_static_check.
|
|
PUBLIC SECTION.
|
|
DATA mv_custom_field TYPE string.
|
|
METHODS constructor
|
|
IMPORTING
|
|
iv_custom_field TYPE string OPTIONAL.
|
|
ENDCLASS.
|
|
|
|
" Raising
|
|
RAISE EXCEPTION TYPE lcx_custom_error
|
|
EXPORTING iv_custom_field = 'Error details'.
|
|
```
|
|
|
|
### Using CX_T100_MSG
|
|
|
|
```abap
|
|
CLASS lcx_message DEFINITION
|
|
INHERITING FROM cx_t100_msg.
|
|
PUBLIC SECTION.
|
|
CONSTANTS:
|
|
BEGIN OF error_occurred,
|
|
msgid TYPE symsgid VALUE 'ZMSG',
|
|
msgno TYPE symsgno VALUE '001',
|
|
attr1 TYPE scx_attrname VALUE 'MV_ATTR1',
|
|
END OF error_occurred.
|
|
ENDCLASS.
|
|
```
|
|
|
|
---
|
|
|
|
## Performance Optimization
|
|
|
|
### Field Symbols vs. References
|
|
|
|
```abap
|
|
" Faster: Field symbols
|
|
LOOP AT it_data ASSIGNING FIELD-SYMBOL(<ls_data>).
|
|
<ls_data>-field = 'value'.
|
|
ENDLOOP.
|
|
|
|
" Slower: References
|
|
LOOP AT it_data REFERENCE INTO DATA(lr_data).
|
|
lr_data->field = 'value'.
|
|
ENDLOOP.
|
|
```
|
|
|
|
### COLLECT for Deduplication
|
|
|
|
```abap
|
|
" Fastest approach - uses internal hash table
|
|
COLLECT ls_line INTO it_aggregated.
|
|
```
|
|
|
|
### Table Copy Efficiency
|
|
|
|
```abap
|
|
" Most efficient: Direct assignment
|
|
it_target = it_source.
|
|
|
|
" Also efficient: CORRESPONDING
|
|
it_target = CORRESPONDING #( it_source ).
|
|
```
|
|
|
|
### SQL Best Practices
|
|
|
|
1. Use JOINs instead of FOR ALL ENTRIES
|
|
2. Use WHERE conditions early
|
|
3. Limit result sets with UP TO n ROWS
|
|
4. Use indexes appropriately
|
|
5. Avoid SELECT * when possible
|
|
|
|
---
|
|
|
|
## Useful Classes Reference
|
|
|
|
| Class | Purpose |
|
|
|-------|---------|
|
|
| `cl_abap_matcher` | Regular expressions |
|
|
| `cl_abap_codepage` | Codepage conversion |
|
|
| `/ui2/cl_json` | JSON serialization |
|
|
| `xco_cp_json` | Modern JSON handling |
|
|
| `cl_xml_document` | XML processing |
|
|
| `cl_salv_table` | ALV display |
|
|
| `cl_gui_alv_grid` | ALV grid control |
|
|
| `cl_abap_typedescr` | Runtime type info |
|
|
| `cl_shdb_seltab` | RANGES to WHERE |
|
|
|
|
---
|
|
|
|
*Source: [https://codezentrale.de/category/sap/sap-abap/*](https://codezentrale.de/category/sap/sap-abap/*)
|