ABAP & SAP Fundament
Fundament

Structuren, interne tabellen & field-symbols

De belangrijkste datastructuren in ABAP: structuren, de drie soorten interne tabellen met hun keys, alle bewerkings-statements, en dynamische toegang via field-symbols en data-referenties.

Op deze pagina

01Structuren

Een structuur is een record: één "regel" met vooraf vastgelegde velden. De bouwsteen voor vrijwel alle data-uitwisseling in SAP.

TYPES: BEGIN OF ty_order,
         vbeln TYPE vbeln_va,     " ordernummer
         erdat TYPE erdat,        " aanmaakdatum
         netwr TYPE netwr_ak,     " nettowaarde
       END OF ty_order.

DATA ls_order TYPE ty_order.

ls_order-vbeln = '0000012345'.   " veldtoegang met een koppelteken
ls_order = VALUE #( vbeln = '0000012345' erdat = sy-datum ). " modern, in één keer

Bekende voorgedefinieerde structuren: databasetabel-regels (DATA ls_mara TYPE mara.), BAPI-structuren (BAPIRET2, zie foutafhandeling) en de systeemstructuur sy.

02Interne tabellen: de drie soorten

Een interne tabel is een lijst van structuren in het geheugen — het werkpaard van ABAP. De soort bepaalt hoe regels worden opgeslagen en hoe snel je ze terugvindt.

DATA: lt_std    TYPE STANDARD TABLE OF ty_order WITH EMPTY KEY,
      lt_sorted TYPE SORTED TABLE OF ty_order
                     WITH UNIQUE KEY vbeln,
      lt_hashed TYPE HASHED TABLE OF ty_order
                     WITH UNIQUE KEY vbeln.
SoortOpslagZoeken op keyWanneer
STANDARDVolgorde van toevoegen (index-tabel)Lineair — O(n), tenzij BINARY SEARCH na SORTStandaardkeuze; sequentieel verwerken, APPEND-en
SORTEDAltijd gesorteerd op de key (index-tabel)Binair — O(log n), automatischVaak zoeken op (deel van) de key én index-toegang nodig
HASHEDHash-tabel, geen index/volgordeO(1), alleen op de vólledige unieke keyGrote tabellen met puur key-lookups (bijv. buffers)

03Interne tabellen bewerken

Alle statements om regels toe te voegen, te vinden, te wijzigen en te verwijderen.

Toevoegen

APPEND ls_order TO lt_orders.               " achteraan (alleen standard)
APPEND INITIAL LINE TO lt_orders ASSIGNING FIELD-SYMBOL(<ls_new>).
INSERT ls_order INTO TABLE lt_sorted.        " op de juiste plek (sorted/hashed)
INSERT ls_order INTO lt_orders INDEX 1.      " op positie (index-tabellen)
APPEND LINES OF lt_extra TO lt_orders.       " tabel aan tabel plakken

Bij INSERT INTO TABLE op een unieke key: bestaat de key al, dan wordt níét ingevoegd en is sy-subrc = 4.

Lezen: READ TABLE en table expressions

READ TABLE lt_orders INTO ls_order WITH KEY vbeln = '0000012345'.
IF sy-subrc = 0.  " gevonden
ENDIF.

READ TABLE lt_orders ASSIGNING FIELD-SYMBOL(<ls_order>) INDEX 1.
READ TABLE lt_orders TRANSPORTING NO FIELDS WITH KEY vbeln = lv_vbeln. " alleen bestaanscheck

" Moderne table expression — dumpt (CX_SY_ITAB_LINE_NOT_FOUND) als niet gevonden:
ls_order = lt_orders[ vbeln = '0000012345' ].
ls_order = VALUE #( lt_orders[ vbeln = lv_vbeln ] OPTIONAL ). " leeg i.p.v. dump
IF line_exists( lt_orders[ vbeln = lv_vbeln ] ). " nette bestaanscheck

Loopen

LOOP AT lt_orders INTO ls_order WHERE netwr > 1000.
  " ls_order is een KOPIE — wijzigingen raken de tabel niet
ENDLOOP.

LOOP AT lt_orders ASSIGNING FIELD-SYMBOL(<ls_order>).
  <ls_order>-netwr = <ls_order>-netwr * '1.21'.  " wijzigt de tabel direct
ENDLOOP.

LOOP AT lt_orders INTO ls_order FROM 1 TO 100.  " indexbereik
ENDLOOP.

Binnen een loop is sy-tabix het huidige regelnummer. Groepsverwerking ("control break") kan klassiek met AT NEW veld ... ENDAT (vereist gesorteerde tabel) of modern met LOOP AT ... GROUP BY.

Wijzigen & verwijderen

MODIFY lt_orders FROM ls_order INDEX sy-tabix.        " regel vervangen
MODIFY lt_orders FROM ls_default
       TRANSPORTING status WHERE status IS INITIAL.   " massa-update van één veld
DELETE lt_orders WHERE netwr = 0.
DELETE lt_orders INDEX 3.
DELETE ADJACENT DUPLICATES FROM lt_orders COMPARING vbeln. " na SORT!

Sorteren, optellen, overig

SORT lt_orders BY erdat DESCENDING vbeln ASCENDING.
SORT lt_orders BY netwr STABLE.       " behoudt volgorde bij gelijke waarden

COLLECT ls_som INTO lt_sommen.        " telt numerieke velden op bij gelijke key

DESCRIBE TABLE lt_orders LINES DATA(lv_aantal). " of: lv_aantal = lines( lt_orders ).
CLEAR lt_orders.                       " leegmaken (FREE geeft ook geheugen terug)
Klassieke valkuil — SORT zonder BY sorteert op de (default) key; bij WITH EMPTY KEY doet hij niets zinvols. En DELETE ADJACENT DUPLICATES werkt alleen op aangrenzende regels — altijd eerst sorteren op dezelfde velden.

04Field-symbols

Een field-symbol is geen variabele maar een verwijzing ("alias") naar een bestaand data-object. Herkenbaar aan de punthaken.

FIELD-SYMBOLS <fs_order> TYPE ty_order.
ASSIGN ls_order TO <fs_order>.
<fs_order>-netwr = 100.        " wijzigt ls_order zelf

" Inline (gangbaarst): declaratie op de plek van gebruik
LOOP AT lt_orders ASSIGNING FIELD-SYMBOL(<ls_o>).
  ...
ENDLOOP.

Dynamische toegang

ASSIGN COMPONENT 'NETWR' OF STRUCTURE ls_order TO FIELD-SYMBOL(<fs_veld>).
IF sy-subrc = 0.
  WRITE <fs_veld>.
ENDIF.

ASSIGN ('(SAPLMEPO)EKKO') TO <fs_ekko>.  " berucht: veld in een ANDER programma
" — komt voor in user exits, zie enhancements

De laatste vorm zie je in user exits: daarmee "gluur" je in de globale data van het aanroepende standaardprogramma. Krachtig, maar fragiel — documenteer het altijd.

05Data-referenties

Naast field-symbols kent ABAP echte referenties (pointers) naar data-objecten — nodig voor volledig dynamische structuren.

DATA lr_data TYPE REF TO data.          " generieke data-referentie
CREATE DATA lr_data TYPE ty_order.       " of dynamisch: TYPE (lv_typenaam)
ASSIGN lr_data->* TO FIELD-SYMBOL(<fs_order>). " dereferentie

DATA(lr_bestaand) = REF #( ls_order ).  " referentie naar bestaand object

Typisch gebruik: generieke frameworks (bijv. een ALV die elke tabel aankan), RTTS (Run Time Type Services, classes CL_ABAP_TYPEDESCR en familie) en het dynamisch opbouwen van tabellen waarvan het type pas tijdens runtime bekend is.

Field-symbol of referentie? Field-symbols voor het gangbare werk (loops, componenttoegang). Referenties zodra je een verwijzing wilt bewaren in een structuur/tabel of wilt doorgeven, of data pas runtime wilt creëren.