Field-Symbols are a central concept in ABAP for dynamic access to memory areas. Unlike regular variables that copy data, a field symbol points directly to the memory area of another variable – similar to pointers in other programming languages.
Basic Concept
- A field symbol is a placeholder that points to a memory area
- It is “assigned” to a concrete variable with
ASSIGN - Changes to the field symbol directly change the original variable
- No data copying = better performance
Syntax
Declare Field Symbol
" With concrete typeFIELD-SYMBOLS: <fs_name> TYPE <type>.
" With generic typeFIELD-SYMBOLS: <fs_any> TYPE any.FIELD-SYMBOLS: <fs_data> TYPE data.FIELD-SYMBOLS: <fs_table> TYPE ANY TABLE.FIELD-SYMBOLS: <fs_structure> TYPE any.
" Inline declaration (from 7.40)ASSIGN variable TO FIELD-SYMBOL(<fs_inline>).ASSIGN Variants
" Static assignmentASSIGN <variable> TO <fs>.
" Dynamic assignment (field name as string)ASSIGN (lv_fieldname) TO <fs>.
" Component of a structureASSIGN COMPONENT <name_or_index> OF STRUCTURE <structure> TO <fs>.
" With type castingASSIGN <variable> TO <fs> CASTING TYPE <type>.System Fields
After ASSIGN:
sy-subrc:0: Assignment successful4: Assignment failed (variable doesn’t exist or type incompatible)
Examples
1. Basic Usage
DATA: lv_number TYPE i VALUE 100.FIELD-SYMBOLS: <fs_num> TYPE i.
" Assign field symbol to variableASSIGN lv_number TO <fs_num>.
IF sy-subrc = 0. " Change via field symbol <fs_num> = 200.
WRITE: / 'Original:', lv_number. " Output: 200ENDIF.2. Check Field Symbol
FIELD-SYMBOLS: <fs> TYPE any.
" Check before using!IF <fs> IS ASSIGNED. " Field symbol points to valid data WRITE: / <fs>.ELSE. " Field symbol is not assigned WRITE: / 'Field symbol not assigned!'.ENDIF.
" Remove assignmentUNASSIGN <fs>.3. Field Symbols with Internal Tables (LOOP)
The most common use case – direct access to table rows:
TYPES: BEGIN OF ty_material, matnr TYPE matnr, menge TYPE i, preis TYPE p DECIMALS 2, END OF ty_material.
DATA: lt_materials TYPE TABLE OF ty_material.
lt_materials = VALUE #( ( matnr = 'MAT001' menge = 100 preis = '10.00' ) ( matnr = 'MAT002' menge = 200 preis = '20.00' ) ( matnr = 'MAT003' menge = 150 preis = '15.00' )).
" With field symbol: Direct access, no copyFIELD-SYMBOLS: <fs_mat> TYPE ty_material.
LOOP AT lt_materials ASSIGNING <fs_mat>. " Change takes effect directly in the table <fs_mat>-preis = <fs_mat>-preis * '1.1'. " 10% increaseENDLOOP.
" Table is now changed!4. Inline Field Symbol Declaration
" Modern (from 7.40): Inline declarationLOOP AT lt_materials ASSIGNING FIELD-SYMBOL(<fs_inline>). <fs_inline>-menge = <fs_inline>-menge + 50.ENDLOOP.
" Also with READ TABLEREAD TABLE lt_materials ASSIGNING FIELD-SYMBOL(<fs_read>) WITH KEY matnr = 'MAT001'.
IF sy-subrc = 0. <fs_read>-preis = 99.ENDIF.5. Dynamic Access to Structure Components
TYPES: BEGIN OF ty_person, firstname TYPE string, lastname TYPE string, age TYPE i, END OF ty_person.
DATA: ls_person TYPE ty_person.FIELD-SYMBOLS: <fs_field> TYPE any.
ls_person = VALUE #( firstname = 'Max' lastname = 'Miller' age = 30 ).
" Access via component indexDO 3 TIMES. ASSIGN COMPONENT sy-index OF STRUCTURE ls_person TO <fs_field>. IF sy-subrc = 0. WRITE: / 'Field', sy-index, ':', <fs_field>. ENDIF.ENDDO.
" Access via component name (as string)DATA: lv_fieldname TYPE string VALUE 'LASTNAME'.
ASSIGN COMPONENT lv_fieldname OF STRUCTURE ls_person TO <fs_field>.IF sy-subrc = 0. WRITE: / 'Lastname:', <fs_field>.ENDIF.6. Dynamic Variable Access
DATA: lv_var1 TYPE string VALUE 'Value 1', lv_var2 TYPE string VALUE 'Value 2', lv_name TYPE string.
FIELD-SYMBOLS: <fs_dynamic> TYPE any.
" Variable name dynamically from stringlv_name = 'LV_VAR1'.ASSIGN (lv_name) TO <fs_dynamic>.
IF sy-subrc = 0. WRITE: / 'Dynamic:', <fs_dynamic>. " Value 1ENDIF.
" Also for global variables with full path" ASSIGN ('(PROGRAMNAME)GLOBALVAR') TO <fs>.7. CASTING - Type Conversion
DATA: lv_hex TYPE x LENGTH 4 VALUE '41424344'.FIELD-SYMBOLS: <fs_char> TYPE c.
" Interpret hex data as charactersASSIGN lv_hex TO <fs_char> CASTING TYPE c.
WRITE: / <fs_char>. " Output: ABCD
" Casting with structuresDATA: lv_raw TYPE x LENGTH 8.FIELD-SYMBOLS: <fs_struct> TYPE ty_small_struct.
ASSIGN lv_raw TO <fs_struct> CASTING.8. Generic Field Symbols
FIELD-SYMBOLS: <fs_any> TYPE any, " Any data type <fs_data> TYPE data, " Any data (not objects) <fs_table> TYPE ANY TABLE. " Any internal table
DATA: lt_any TYPE TABLE OF string.
" Generic field symbol for tablesASSIGN lt_any TO <fs_table>.
IF <fs_table> IS ASSIGNED. LOOP AT <fs_table> ASSIGNING <fs_any>. WRITE: / <fs_any>. ENDLOOP.ENDIF.9. Field Symbol on Table Row with Index
DATA: lt_data TYPE TABLE OF string.
lt_data = VALUE #( ( `One` ) ( `Two` ) ( `Three` ) ).
FIELD-SYMBOLS: <fs_line> TYPE string.
" Direct access to row 2ASSIGN lt_data[ 2 ] TO <fs_line>.
IF sy-subrc = 0. <fs_line> = 'CHANGED'.ENDIF.
" lt_data now contains: One, CHANGED, Three10. Dynamically Iterate Nested Structures
DATA: lo_struct_descr TYPE REF TO cl_abap_structdescr, lt_components TYPE abap_compdescr_tab.
FIELD-SYMBOLS: <fs_comp> TYPE abap_compdescr, <fs_val> TYPE any.
" Get structure descriptionlo_struct_descr ?= cl_abap_typedescr=>describe_by_data( ls_person ).lt_components = lo_struct_descr->components.
" Iterate all componentsLOOP AT lt_components ASSIGNING <fs_comp>. ASSIGN COMPONENT <fs_comp>-name OF STRUCTURE ls_person TO <fs_val>. IF sy-subrc = 0. WRITE: / <fs_comp>-name, '=', <fs_val>. ENDIF.ENDLOOP.Field Symbol vs. INTO (Performance)
| Aspect | ASSIGNING (Field Symbol) | INTO (Work Area) |
|---|---|---|
| Data copy | No | Yes |
| Performance | Faster | Slower |
| Changes | Directly in table | Requires MODIFY |
| Memory | Minimal | Additional memory |
" SLOW: Copy and write backLOOP AT lt_materials INTO ls_material. ls_material-preis = ls_material-preis * 2. MODIFY lt_materials FROM ls_material.ENDLOOP.
" FAST: Direct accessLOOP AT lt_materials ASSIGNING <fs_mat>. <fs_mat>-preis = <fs_mat>-preis * 2.ENDLOOP.Common Errors
1. Using Unassigned Field Symbol
FIELD-SYMBOLS: <fs> TYPE any.
" ERROR: Field symbol not assigned!" WRITE: / <fs>. " Runtime Error!
" CORRECT: Always checkIF <fs> IS ASSIGNED. WRITE: / <fs>.ENDIF.2. Field Symbol Becomes Invalid After Table Change
LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<fs>). " CAUTION: DELETE can invalidate the field symbol! IF <fs>-status = 'X'. DELETE lt_data. " <fs> now points to nothing! ENDIF.ENDLOOP.3. Type Incompatibility
DATA: lv_string TYPE string VALUE 'Test'.FIELD-SYMBOLS: <fs_int> TYPE i.
" ERROR: Incompatible typesASSIGN lv_string TO <fs_int>.IF sy-subrc <> 0. WRITE: / 'Assignment failed!'.ENDIF.Important Notes / Best Practice
- Always check
sy-subrcafterASSIGNorIS ASSIGNEDbefore use. - Use ASSIGNING in
LOOP ATinstead of INTO for better performance. - Field symbols are ideal for dynamic programming.
- Use the inline declaration (
FIELD-SYMBOL(<fs>)) for shorter code. - With generic types (
TYPE any), CASTING is often required. - Field symbols can become invalid when the original data is deleted.
- For object references, use
Data Referencesinstead. - Combine with
READ TABLEfor efficient single access.