Die MODIFY-Anweisung wird in ABAP verwendet, um bestehende Zeilen in internen Tabellen zu ändern. Sie kann eine einzelne Zeile (per Index oder Schlüssel) oder mehrere Zeilen gleichzeitig (mit WHERE-Bedingung) aktualisieren. Wenn die Zeile nicht existiert, kann MODIFY sie je nach Variante auch einfügen.
Syntax
Es gibt mehrere Varianten der MODIFY-Anweisung:
1. Zeile per Index ändern
MODIFY <interne_tabelle> FROM <arbeitsbereich> INDEX <index> [TRANSPORTING <komponente1> <komponente2> ...].2. Zeile per Tabellenschlüssel ändern oder einfügen
MODIFY TABLE <interne_tabelle> FROM <arbeitsbereich> [TRANSPORTING <komponente1> <komponente2> ...].3. Mehrere Zeilen mit WHERE-Bedingung ändern
MODIFY <interne_tabelle> FROM <arbeitsbereich> TRANSPORTING <komponente1> [<komponente2> ...] WHERE <bedingung>.4. Aktuelle Zeile im LOOP ändern
LOOP AT <interne_tabelle> INTO <arbeitsbereich>. " <arbeitsbereich> ändern MODIFY <interne_tabelle> FROM <arbeitsbereich>.ENDLOOP.Bestandteile
<interne_tabelle>: Die Tabelle, deren Zeilen geändert werden sollen.<arbeitsbereich>: Eine Struktur mit den neuen Werten. Muss zum Zeilentyp der Tabelle kompatibel sein.INDEX <index>: Die Position der zu ändernden Zeile (nur bei Standardtabellen und sortierten Tabellen).TABLE: Kennzeichnet die Variante mit Schlüsselsuche. Die Zeile wird anhand des Primärschlüssels gesucht.TRANSPORTING <komponenten>: Beschränkt die Änderung auf die angegebenen Komponenten. Andere Felder bleiben unverändert.WHERE <bedingung>: Ändert alle Zeilen, die die Bedingung erfüllen.
Systemfelder
Nach einem MODIFY werden folgende Systemfelder gesetzt:
-
sy-subrc:0: Zeile(n) erfolgreich geändert (oder eingefügt beiMODIFY TABLE).4: Keine passende Zeile gefunden (beiINDEXoderTABLE).
-
sy-tabix: Enthält den Index der geänderten Zeile (bei Einzelzeilenoperationen auf Index-Tabellen).
Funktionsweise nach Variante
MODIFY … INDEX
Ändert die Zeile an der angegebenen Indexposition. Der gesamte Inhalt des Arbeitsbereichs wird in die Zeile kopiert (außer bei TRANSPORTING).
" Zeile 3 komplett ersetzenMODIFY lt_data FROM ls_new_data INDEX 3.
" Nur bestimmte Felder in Zeile 3 ändernMODIFY lt_data FROM ls_new_data INDEX 3 TRANSPORTING field1 field2.MODIFY TABLE
Sucht die Zeile anhand des Primärschlüssels im Arbeitsbereich:
- Gefunden: Die Zeile wird aktualisiert.
- Nicht gefunden: Die Zeile wird eingefügt (wie
INSERT).
" Sucht nach Schlüssel und ändert oder fügt einMODIFY TABLE lt_customers FROM ls_customer.MODIFY … WHERE
Ändert alle Zeilen, die die WHERE-Bedingung erfüllen. TRANSPORTING ist hier Pflicht.
" Alle Zeilen mit status = 'OLD' ändernMODIFY lt_orders FROM ls_update TRANSPORTING status WHERE status = 'OLD'.MODIFY im LOOP (ohne INDEX)
Innerhalb eines LOOP AT ... INTO kann MODIFY ohne INDEX verwendet werden – es ändert dann automatisch die aktuelle Zeile.
LOOP AT lt_data INTO ls_data. ls_data-field = 'Neuer Wert'. MODIFY lt_data FROM ls_data.ENDLOOP.Besser: Verwenden Sie ASSIGNING im Loop, um direkte Änderungen ohne MODIFY zu ermöglichen.
Beispiele
1. Zeile per Index ändern
TYPES: BEGIN OF ty_product, id TYPE i, name TYPE string, price TYPE p DECIMALS 2, END OF ty_product.
DATA: lt_products TYPE STANDARD TABLE OF ty_product WITH EMPTY KEY, ls_product TYPE ty_product.
" Tabelle füllenlt_products = VALUE #( ( id = 1 name = 'Laptop' price = '999.00' ) ( id = 2 name = 'Maus' price = '29.99' ) ( id = 3 name = 'Tastatur' price = '79.00' )).
" Zeile 2 komplett ersetzenls_product = VALUE #( id = 2 name = 'Gaming-Maus' price = '59.99' ).MODIFY lt_products FROM ls_product INDEX 2.
IF sy-subrc = 0. WRITE: / 'Zeile 2 geändert.'.ENDIF.2. Nur bestimmte Felder ändern (TRANSPORTING)
" Nur den Preis in Zeile 1 ändernls_product-price = '899.00'.MODIFY lt_products FROM ls_product INDEX 1 TRANSPORTING price.
" Name und ID bleiben unverändert" Siehe auch: /read-table-statement/READ TABLE lt_products INTO ls_product INDEX 1.WRITE: / 'Produkt:', ls_product-name, 'Preis:', ls_product-price." Ausgabe: Laptop 899.003. MODIFY TABLE (Schlüsselbasiert)
TYPES: BEGIN OF ty_customer, id TYPE i, name TYPE string, city TYPE string, END OF ty_customer.
DATA: lt_customers TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id, ls_customer TYPE ty_customer.
" Tabelle füllenlt_customers = VALUE #( ( id = 1 name = 'Müller GmbH' city = 'Berlin' ) ( id = 2 name = 'Schmidt AG' city = 'München' )).
" Existierenden Kunden ändern (ID 1 existiert)ls_customer = VALUE #( id = 1 name = 'Müller & Co. GmbH' city = 'Berlin' ).MODIFY TABLE lt_customers FROM ls_customer.
IF sy-subrc = 0. WRITE: / 'Kunde 1 geändert.'.ENDIF.
" Neuen Kunden einfügen (ID 3 existiert nicht)ls_customer = VALUE #( id = 3 name = 'Weber KG' city = 'Hamburg' ).MODIFY TABLE lt_customers FROM ls_customer.
WRITE: / 'Anzahl Kunden:', lines( lt_customers ). " Ausgabe: 34. Mehrere Zeilen mit WHERE ändern
TYPES: BEGIN OF ty_order, order_id TYPE i, status TYPE string, amount TYPE p DECIMALS 2, END OF ty_order.
DATA: lt_orders TYPE STANDARD TABLE OF ty_order WITH EMPTY KEY, ls_update TYPE ty_order.
lt_orders = VALUE #( ( order_id = 1 status = 'NEU' amount = '100.00' ) ( order_id = 2 status = 'NEU' amount = '250.00' ) ( order_id = 3 status = 'OFFEN' amount = '180.00' ) ( order_id = 4 status = 'NEU' amount = '320.00' )).
" Alle Bestellungen mit Status 'NEU' auf 'IN_BEARBEITUNG' setzenls_update-status = 'IN_BEARBEITUNG'.MODIFY lt_orders FROM ls_update TRANSPORTING status WHERE status = 'NEU'.
" Ergebnis: 3 Zeilen geändert (order_id 1, 2, 4)LOOP AT lt_orders INTO DATA(ls_order). WRITE: / ls_order-order_id, ls_order-status.ENDLOOP.5. MODIFY im LOOP mit INTO
DATA: ls_prod TYPE ty_product.
" Alle Preise um 10% erhöhenLOOP AT lt_products INTO ls_prod. ls_prod-price = ls_prod-price * '1.1'. MODIFY lt_products FROM ls_prod.ENDLOOP.6. Bessere Alternative: LOOP mit ASSIGNING
FIELD-SYMBOLS: <fs_prod> TYPE ty_product.
" Alle Preise um 10% erhöhen – ohne MODIFYLOOP AT lt_products ASSIGNING <fs_prod>. <fs_prod>-price = <fs_prod>-price * '1.1'.ENDLOOP.
" Änderungen sind sofort wirksam, kein MODIFY nötig!7. MODIFY TABLE mit TRANSPORTING
" Nur die Stadt eines Kunden ändern (Schlüsselsuche)ls_customer-id = 2. " Schlüssel für die Suchels_customer-city = 'Köln'. " Neuer Wert
MODIFY TABLE lt_customers FROM ls_customer TRANSPORTING city.
IF sy-subrc = 0. WRITE: / 'Stadt von Kunde 2 geändert.'.ENDIF.Verhalten nach Tabellentyp
| Tabellentyp | INDEX | TABLE | WHERE |
|---|---|---|---|
| STANDARD TABLE | Ja | Ja (lineare Suche) | Ja |
| SORTED TABLE | Ja | Ja (binäre Suche) | Ja |
| HASHED TABLE | Nein | Ja (Hash-Lookup) | Ja |
Wichtig bei sortierten Tabellen: Wenn Sie Schlüsselfelder ändern, kann dies die Sortierreihenfolge verletzen und zu einem Laufzeitfehler führen!
" Gefährlich bei SORTED TABLE mit KEY id:ls_customer-id = 999. " Schlüsselfeld ändernMODIFY TABLE lt_sorted_customers FROM ls_customer. " Kann Dump verursachen!Abgrenzung zu anderen Anweisungen
MODIFY vs. ASSIGNING im LOOP
| Aspekt | MODIFY im LOOP | ASSIGNING |
|---|---|---|
| Syntax | Mehr Code | Kompakter |
| Performance | Langsamer (Kopieren) | Schneller (Direktzugriff) |
| Anwendung | Legacy-Code | Empfohlen |
" Mit MODIFY (veraltet)LOOP AT lt_data INTO ls_data. ls_data-field = 'X'. MODIFY lt_data FROM ls_data.ENDLOOP.
" Mit ASSIGNING (empfohlen)LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<fs>). <fs>-field = 'X'.ENDLOOP.MODIFY vs. INSERT und APPEND
MODIFY TABLE: Ändert existierende Zeile ODER fügt neue ein (Upsert).INSERT: Fügt nur ein, schlägt fehl wenn Schlüssel existiert.APPEND: Fügt immer am Ende einer Standardtabelle an.
MODIFY vs. UPDATE (Datenbank)
MODIFY: Für interne Tabellen (im Arbeitsspeicher).UPDATE: Für Datenbanktabellen (persistente Daten).
Für das Suchen einer Zeile vor dem Ändern siehe READ TABLE.
Performance-Tipps
-
ASSIGNING statt MODIFY im LOOP: Vermeiden Sie
LOOP ... INTOmit anschließendemMODIFY. Nutzen Sie stattdessenASSIGNINGfür direkten Schreibzugriff. -
TRANSPORTING bei großen Strukturen: Wenn nur wenige Felder geändert werden, beschränken Sie mit
TRANSPORTINGdie zu kopierenden Daten. -
WHERE für Massenänderungen:
MODIFY ... WHEREist effizienter als ein manueller Loop mit Einzeländerungen. -
Schlüsselfelder nicht ändern: Bei sortierten und Hash-Tabellen sollten Schlüsselfelder nicht geändert werden. Stattdessen: Zeile löschen und neu einfügen (siehe
APPENDoderINSERT).
Wichtige Hinweise / Best Practice
- Prüfen Sie
sy-subrcnachMODIFYmitINDEXoderTABLE, um sicherzustellen, dass die Zeile gefunden wurde. - Bevorzugen Sie
ASSIGNINGimLOOP ATfür direkte Änderungen – das ist performanter und eleganter alsMODIFY. - Verwenden Sie
TRANSPORTING, wenn nur bestimmte Felder geändert werden sollen. MODIFY TABLEist ein “Upsert” – es fügt ein, wenn die Zeile nicht existiert.- Ändern Sie niemals Schlüsselfelder bei sortierten oder Hash-Tabellen direkt.
- Bei
MODIFY ... WHEREistTRANSPORTINGPflicht. - Diese
MODIFY-Anweisung ist für interne Tabellen. Für Datenbanktabellen sieheINSERT, UPDATE, DELETE.