ABAP SORT Anweisung: Interne Tabellen sortieren

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Die SORT-Anweisung wird in ABAP verwendet, um die Zeilen einer internen Tabelle nach bestimmten Kriterien zu ordnen. Die Sortierung erfolgt im Arbeitsspeicher und verändert die physische Reihenfolge der Zeilen in der Tabelle.

Syntax

Die grundlegende Syntax bietet verschiedene Optionen:

1. Sortierung nach Standardschlüssel

SORT <interne_tabelle>.

2. Sortierung nach bestimmten Feldern

SORT <interne_tabelle> BY <feld1> [ASCENDING|DESCENDING]
[<feld2> [ASCENDING|DESCENDING]]
[...].

3. Sortierung mit zusätzlichen Optionen

SORT <interne_tabelle> [BY <felder>]
[ASCENDING|DESCENDING]
[AS TEXT]
[STABLE].

Bestandteile

  • <interne_tabelle>: Die zu sortierende Tabelle. Muss eine Standardtabelle sein (sortierte und Hash-Tabellen können nicht mit SORT sortiert werden).
  • BY <feld1> <feld2> ...: Die Felder, nach denen sortiert werden soll. Die Reihenfolge bestimmt die Priorität.
  • ASCENDING: Aufsteigende Sortierung (A-Z, 0-9). Standard, wenn nichts angegeben.
  • DESCENDING: Absteigende Sortierung (Z-A, 9-0).
  • AS TEXT: Sortiert Zeichenfelder nach sprachabhängigen Regeln (Locale-Sortierung).
  • STABLE: Erhält die relative Reihenfolge von Zeilen mit gleichen Sortierschlüsselwerten.

Funktionsweise

  1. Ohne BY-Klausel wird nach dem Primärschlüssel der Tabelle sortiert. Hat die Tabelle keinen expliziten Schlüssel oder EMPTY KEY, werden alle Nicht-Numerischen Felder als Schlüssel verwendet.
  2. Mit BY-Klausel wird nur nach den angegebenen Feldern sortiert.
  3. Die Sortierung erfolgt in-place – die ursprüngliche Tabelle wird verändert.
  4. Bei mehreren Sortierfeldern wird zuerst nach dem ersten Feld sortiert, bei Gleichheit nach dem zweiten usw.

Systemfelder

Die SORT-Anweisung setzt keine relevanten Systemfelder. Es gibt keinen Fehlerfall – eine leere Tabelle bleibt einfach leer.

Beispiele

1. Einfache Sortierung (Standardschlüssel)

TYPES: BEGIN OF ty_person,
name TYPE string,
age TYPE i,
city TYPE string,
END OF ty_person.
DATA: lt_persons TYPE STANDARD TABLE OF ty_person WITH EMPTY KEY.
lt_persons = VALUE #(
( name = 'Müller' age = 35 city = 'Berlin' )
( name = 'Schmidt' age = 28 city = 'München' )
( name = 'Weber' age = 42 city = 'Hamburg' )
( name = 'Fischer' age = 28 city = 'Berlin' )
).
" Sortierung nach allen Nicht-Numerischen Feldern (name, city)
SORT lt_persons.

2. Sortierung nach einem Feld

" Nach Alter sortieren (aufsteigend)
SORT lt_persons BY age.
" Ergebnis: Schmidt (28), Fischer (28), Müller (35), Weber (42)
" Siehe auch: /loop-at-statement/
LOOP AT lt_persons INTO DATA(ls_person).
WRITE: / ls_person-name, ls_person-age.
ENDLOOP.

3. Sortierung nach mehreren Feldern

" Erst nach Alter, dann nach Name
SORT lt_persons BY age name.
" Ergebnis bei gleichem Alter (28): Fischer vor Schmidt
LOOP AT lt_persons INTO ls_person.
WRITE: / ls_person-age, ls_person-name.
ENDLOOP.

4. Absteigende Sortierung

" Nach Alter absteigend
SORT lt_persons BY age DESCENDING.
" Ergebnis: Weber (42), Müller (35), Schmidt (28), Fischer (28)

5. Gemischte Sortierrichtungen

" Nach Stadt aufsteigend, dann nach Alter absteigend
SORT lt_persons BY city ASCENDING
age DESCENDING.
" Berlin: Müller (35), Fischer (28)
" Hamburg: Weber (42)
" München: Schmidt (28)

6. Stabile Sortierung

DATA: lt_orders TYPE STANDARD TABLE OF ty_order WITH EMPTY KEY.
lt_orders = VALUE #(
( order_id = 1 customer = 'A' date = '20250101' )
( order_id = 2 customer = 'B' date = '20250101' )
( order_id = 3 customer = 'A' date = '20250102' )
( order_id = 4 customer = 'A' date = '20250101' )
).
" Ohne STABLE: Reihenfolge von Zeilen mit gleichem customer ist undefiniert
SORT lt_orders BY customer.
" Mit STABLE: Ursprüngliche Reihenfolge bei Gleichheit bleibt erhalten
SORT lt_orders BY customer STABLE.
" Ergebnis mit STABLE für customer = 'A': order_id 1, 3, 4 (ursprüngliche Reihenfolge)

7. Textbasierte Sortierung (AS TEXT)

DATA: lt_names TYPE STANDARD TABLE OF string WITH EMPTY KEY.
lt_names = VALUE #( ( `Äpfel` ) ( `Apfel` ) ( `Banane` ) ( `Öl` ) ( `Orange` ) ).
" Ohne AS TEXT: Sortierung nach internem Zeichencode
SORT lt_names.
" Ergebnis: Apfel, Banane, Orange, Äpfel, Öl (Umlaute am Ende)
" Mit AS TEXT: Sprachabhängige Sortierung
SORT lt_names AS TEXT.
" Ergebnis: Äpfel, Apfel, Banane, Öl, Orange (Umlaute korrekt eingeordnet)

8. Sortierung für BINARY SEARCH vorbereiten

TYPES: BEGIN OF ty_material,
matnr TYPE matnr,
maktx TYPE maktx,
END OF ty_material.
DATA: lt_materials TYPE STANDARD TABLE OF ty_material WITH EMPTY KEY,
ls_material TYPE ty_material.
" Tabelle füllen (unsortiert)
lt_materials = VALUE #(
( matnr = 'MAT003' maktx = 'Scheibe' )
( matnr = 'MAT001' maktx = 'Schraube' )
( matnr = 'MAT002' maktx = 'Mutter' )
).
" Vor BINARY SEARCH muss sortiert werden!
SORT lt_materials BY matnr.
" Jetzt kann BINARY SEARCH verwendet werden
READ TABLE lt_materials INTO ls_material
WITH KEY matnr = 'MAT002'
BINARY SEARCH.
IF sy-subrc = 0.
WRITE: / 'Gefunden:', ls_material-maktx.
ENDIF.

9. Sortierung numerischer Felder

TYPES: BEGIN OF ty_score,
player TYPE string,
points TYPE i,
END OF ty_score.
DATA: lt_scores TYPE STANDARD TABLE OF ty_score WITH EMPTY KEY.
lt_scores = VALUE #(
( player = 'Anna' points = 150 )
( player = 'Bob' points = 280 )
( player = 'Clara' points = 95 )
( player = 'David' points = 280 )
).
" Highscore-Liste: Höchste Punktzahl zuerst
SORT lt_scores BY points DESCENDING.
DATA(lv_rank) = 0.
" Iteration mit LOOP AT: /loop-at-statement/
LOOP AT lt_scores INTO DATA(ls_score).
lv_rank = lv_rank + 1.
WRITE: / lv_rank, ls_score-player, ls_score-points.
ENDLOOP.

10. Sortierung von Datums- und Zeitfeldern

TYPES: BEGIN OF ty_event,
name TYPE string,
date TYPE d,
time TYPE t,
END OF ty_event.
DATA: lt_events TYPE STANDARD TABLE OF ty_event WITH EMPTY KEY.
lt_events = VALUE #(
( name = 'Meeting' date = '20250315' time = '140000' )
( name = 'Workshop' date = '20250315' time = '090000' )
( name = 'Konferenz' date = '20250310' time = '100000' )
).
" Nach Datum und Uhrzeit sortieren (chronologisch)
SORT lt_events BY date ASCENDING
time ASCENDING.
" Ergebnis: Konferenz (10.03.), Workshop (15.03. 09:00), Meeting (15.03. 14:00)

Einschränkungen

Nur für Standardtabellen

SORT kann nur auf Standardtabellen angewendet werden:

" Erlaubt
DATA: lt_standard TYPE STANDARD TABLE OF ty_data.
SORT lt_standard BY field.
" Nicht erlaubt - Syntaxfehler!
DATA: lt_sorted TYPE SORTED TABLE OF ty_data WITH UNIQUE KEY field.
" SORT lt_sorted BY field. " Fehler: Sortierte Tabellen sind bereits sortiert
DATA: lt_hashed TYPE HASHED TABLE OF ty_data WITH UNIQUE KEY field.
" SORT lt_hashed BY field. " Fehler: Hash-Tabellen haben keine definierte Reihenfolge

Sortierung ist nicht persistent

Die Sortierung gilt nur für die aktuelle Programmausführung. Nach dem Einfügen neuer Zeilen (z.B. mit APPEND) ist die Tabelle möglicherweise nicht mehr sortiert.

SORT lt_data BY field.
" lt_data ist jetzt sortiert
APPEND VALUE #( field = 'ZZZ' ) TO lt_data.
" lt_data ist jetzt NICHT mehr garantiert sortiert!

SORT vs. SORTED TABLE

AspektSORTSORTED TABLE
TypAnweisungTabellentyp
AnwendungStandardtabellenBei Deklaration
SortierungEinmalig, manuellAutomatisch, dauerhaft
PerformanceO(n log n) bei jedem AufrufO(log n) beim Einfügen
FlexibilitätBeliebige SortierkriterienFestes Sortierkriterium

Empfehlung: Wenn Daten häufig sortiert abgerufen werden, verwenden Sie eine SORTED TABLE. Für einmalige oder wechselnde Sortierkriterien ist SORT flexibler.

" SORTED TABLE: Immer nach matnr sortiert
DATA: lt_sorted_mat TYPE SORTED TABLE OF ty_material
WITH UNIQUE KEY matnr.
" STANDARD TABLE mit SORT: Flexibel sortierbar
DATA: lt_standard_mat TYPE STANDARD TABLE OF ty_material WITH EMPTY KEY.
SORT lt_standard_mat BY matnr. " Nach Nummer
SORT lt_standard_mat BY maktx. " Später nach Text

Performance-Tipps

  1. Vermeiden Sie wiederholtes Sortieren: Sortieren Sie die Tabelle einmal und fügen Sie danach keine unsortierten Daten mehr hinzu.

  2. SORTED TABLE für häufige sortierte Zugriffe: Wenn Sie regelmäßig binäre Suchen mit READ TABLE durchführen, ist eine SORTED TABLE effizienter.

  3. Sortierfelder minimieren: Je weniger Felder im BY-Zusatz, desto schneller die Sortierung.

  4. STABLE nur wenn nötig: STABLE kann die Performance leicht reduzieren. Verwenden Sie es nur, wenn die Reihenfolge bei Gleichheit wichtig ist.

  5. Große Tabellen: Bei sehr großen Tabellen (>100.000 Zeilen) kann das Sortieren merklich Zeit beanspruchen. Erwägen Sie alternative Datenstrukturen.

  6. Sortierung vor BINARY SEARCH: Wenn Sie READ TABLE ... BINARY SEARCH verwenden, muss die Tabelle nach dem Suchfeld sortiert sein.

" Falsch: BINARY SEARCH ohne vorherige Sortierung
READ TABLE lt_data INTO ls_data WITH KEY field = 'X' BINARY SEARCH. " Unzuverlässig!
" Richtig: Erst sortieren, dann suchen
SORT lt_data BY field.
READ TABLE lt_data INTO ls_data WITH KEY field = 'X' BINARY SEARCH. " Korrekt

Wichtige Hinweise / Best Practice

  • SORT funktioniert nur mit Standardtabellen – sortierte und Hash-Tabellen können nicht mit SORT sortiert werden.
  • Ohne BY-Klausel wird nach dem Primärschlüssel sortiert.
  • Verwenden Sie STABLE, wenn die relative Reihenfolge von Zeilen mit gleichen Schlüsselwerten erhalten bleiben soll.
  • AS TEXT ist wichtig für korrekte alphabetische Sortierung mit Umlauten und Sonderzeichen.
  • Nach dem Sortieren können Sie READ TABLE ... BINARY SEARCH für schnelle Suchen verwenden.
  • Für dauerhaft sortierte Daten sind SORTED TABLEs die bessere Wahl als wiederholtes Sortieren einer Standardtabelle.
  • Die Sortierung ist nicht persistent – neue Zeilen (z.B. via APPEND) werden am Ende angehängt und können die Sortierung brechen.