Instruction ABAP SORT : Trier les tables internes

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

L’instruction SORT est utilisée en ABAP pour ordonner les lignes d’une table interne selon certains critères. Le tri s’effectue en mémoire et modifie l’ordre physique des lignes dans la table.

Syntaxe

La syntaxe de base offre différentes options :

1. Tri par clé par défaut

SORT <table_interne>.

2. Tri par champs spécifiques

SORT <table_interne> BY <champ1> [ASCENDING|DESCENDING]
[<champ2> [ASCENDING|DESCENDING]]
[...].

3. Tri avec options supplémentaires

SORT <table_interne> [BY <champs>]
[ASCENDING|DESCENDING]
[AS TEXT]
[STABLE].

Composants

  • <table_interne> : La table à trier. Doit être une table standard (les tables triées et hachées ne peuvent pas être triées avec SORT).
  • BY <champ1> <champ2> ... : Les champs selon lesquels trier. L’ordre détermine la priorité.
  • ASCENDING : Tri croissant (A-Z, 0-9). Par défaut si rien n’est spécifié.
  • DESCENDING : Tri décroissant (Z-A, 9-0).
  • AS TEXT : Trie les champs de caractères selon les règles dépendantes de la langue (tri local).
  • STABLE : Conserve l’ordre relatif des lignes avec des valeurs de clé de tri égales.

Fonctionnement

  1. Sans clause BY, le tri s’effectue selon la clé primaire de la table. Si la table n’a pas de clé explicite ou EMPTY KEY, tous les champs non numériques sont utilisés comme clé.
  2. Avec clause BY, le tri s’effectue uniquement selon les champs indiqués.
  3. Le tri s’effectue in-place - la table originale est modifiée.
  4. Avec plusieurs champs de tri, le tri s’effectue d’abord selon le premier champ, puis en cas d’égalité selon le second, etc.

Champs système

L’instruction SORT ne définit pas de champs système pertinents. Il n’y a pas de cas d’erreur - une table vide reste simplement vide.

Exemples

1. Tri simple (clé par défaut)

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 = 'Munich' )
( name = 'Weber' age = 42 city = 'Hambourg' )
( name = 'Fischer' age = 28 city = 'Berlin' )
).
" Tri selon tous les champs non numériques (name, city)
SORT lt_persons.

2. Tri par un champ

" Trier par âge (croissant)
SORT lt_persons BY age.
" Résultat : Schmidt (28), Fischer (28), Müller (35), Weber (42)
" Voir aussi : /loop-at-statement/
LOOP AT lt_persons INTO DATA(ls_person).
WRITE: / ls_person-name, ls_person-age.
ENDLOOP.

3. Tri par plusieurs champs

" D'abord par âge, puis par nom
SORT lt_persons BY age name.
" Résultat pour le même âge (28) : Fischer avant Schmidt
LOOP AT lt_persons INTO ls_person.
WRITE: / ls_person-age, ls_person-name.
ENDLOOP.

4. Tri décroissant

" Par âge décroissant
SORT lt_persons BY age DESCENDING.
" Résultat : Weber (42), Müller (35), Schmidt (28), Fischer (28)

5. Directions de tri mixtes

" Par ville croissant, puis par âge décroissant
SORT lt_persons BY city ASCENDING
age DESCENDING.
" Berlin : Müller (35), Fischer (28)
" Hambourg : Weber (42)
" Munich : Schmidt (28)

6. Tri stable

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' )
).
" Sans STABLE : ordre des lignes avec même customer indéfini
SORT lt_orders BY customer.
" Avec STABLE : ordre original en cas d'égalité préservé
SORT lt_orders BY customer STABLE.
" Résultat avec STABLE pour customer = 'A' : order_id 1, 3, 4 (ordre original)

7. Tri basé sur le texte (AS TEXT)

DATA: lt_names TYPE STANDARD TABLE OF string WITH EMPTY KEY.
lt_names = VALUE #( ( `Äpfel` ) ( `Apfel` ) ( `Banane` ) ( `Öl` ) ( `Orange` ) ).
" Sans AS TEXT : tri selon code caractère interne
SORT lt_names.
" Résultat : Apfel, Banane, Orange, Äpfel, Öl (trémas à la fin)
" Avec AS TEXT : tri dépendant de la langue
SORT lt_names AS TEXT.
" Résultat : Äpfel, Apfel, Banane, Öl, Orange (trémas correctement placés)
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.
" Remplir la table (non triée)
lt_materials = VALUE #(
( matnr = 'MAT003' maktx = 'Rondelle' )
( matnr = 'MAT001' maktx = 'Vis' )
( matnr = 'MAT002' maktx = 'Écrou' )
).
" Doit être trié avant BINARY SEARCH !
SORT lt_materials BY matnr.
" Maintenant BINARY SEARCH peut être utilisé
READ TABLE lt_materials INTO ls_material
WITH KEY matnr = 'MAT002"
BINARY SEARCH.
IF sy-subrc = 0.
WRITE: / 'Trouvé :', ls_material-maktx.
ENDIF.

9. Tri de champs numériques

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 )
).
" Liste des meilleurs scores : score le plus élevé en premier
SORT lt_scores BY points DESCENDING.
DATA(lv_rank) = 0.
" Itération avec 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. Tri de champs date et heure

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 = 'Réunion' date = '20250315' time = '140000' )
( name = 'Atelier' date = '20250315' time = '090000' )
( name = 'Conférence' date = '20250310' time = '100000' )
).
" Trier par date et heure (chronologique)
SORT lt_events BY date ASCENDING
time ASCENDING.
" Résultat : Conférence (10.03.), Atelier (15.03. 09:00), Réunion (15.03. 14:00)

Limitations

Uniquement pour les tables standard

SORT ne peut être appliqué qu’aux tables standard :

" Autorisé
DATA: lt_standard TYPE STANDARD TABLE OF ty_data.
SORT lt_standard BY field.
" Non autorisé - Erreur de syntaxe !
DATA: lt_sorted TYPE SORTED TABLE OF ty_data WITH UNIQUE KEY field.
" SORT lt_sorted BY field. " Erreur : tables triées déjà triées
DATA: lt_hashed TYPE HASHED TABLE OF ty_data WITH UNIQUE KEY field.
" SORT lt_hashed BY field. " Erreur : tables hachées n'ont pas d'ordre défini

Le tri n’est pas persistant

Le tri ne s’applique qu’à l’exécution actuelle du programme. Après l’insertion de nouvelles lignes (par ex. avec APPEND), la table peut ne plus être triée.

SORT lt_data BY field.
" lt_data est maintenant trié
APPEND VALUE #( field = 'ZZZ' ) TO lt_data.
" lt_data n'est plus garanti trié !

SORT vs. SORTED TABLE

AspectSORTSORTED TABLE
TypeInstructionType de table
ApplicationTables standardÀ la déclaration
TriPonctuel, manuelAutomatique, permanent
PerformanceO(n log n) à chaque appelO(log n) à l’insertion
FlexibilitéCritères de tri quelconquesCritère de tri fixe

Recommandation : Si les données sont fréquemment récupérées triées, utilisez une SORTED TABLE. Pour des tris ponctuels ou des critères changeants, SORT est plus flexible.

" SORTED TABLE : toujours triée par matnr
DATA: lt_sorted_mat TYPE SORTED TABLE OF ty_material
WITH UNIQUE KEY matnr.
" STANDARD TABLE avec SORT : tri flexible
DATA: lt_standard_mat TYPE STANDARD TABLE OF ty_material WITH EMPTY KEY.
SORT lt_standard_mat BY matnr. " Par numéro
SORT lt_standard_mat BY maktx. " Plus tard par texte

Conseils de performance

  1. Évitez les tris répétés : Triez la table une fois et n’ajoutez plus de données non triées ensuite.

  2. SORTED TABLE pour accès triés fréquents : Si vous effectuez régulièrement des recherches binaires avec READ TABLE, une SORTED TABLE est plus efficace.

  3. Minimiser les champs de tri : Moins il y a de champs dans BY, plus le tri est rapide.

  4. STABLE uniquement si nécessaire : STABLE peut légèrement réduire la performance. Utilisez-le uniquement si l’ordre en cas d’égalité est important.

  5. Tables volumineuses : Pour les très grandes tables (>100 000 lignes), le tri peut prendre un temps notable. Envisagez des structures de données alternatives.

  6. Tri avant BINARY SEARCH : Si vous utilisez READ TABLE ... BINARY SEARCH, la table doit être triée par le champ de recherche.

" Faux : BINARY SEARCH sans tri préalable
READ TABLE lt_data INTO ls_data WITH KEY field = 'X' BINARY SEARCH. " Non fiable !
" Correct : d'abord trier, puis chercher
SORT lt_data BY field.
READ TABLE lt_data INTO ls_data WITH KEY field = 'X' BINARY SEARCH. " Correct

Remarques importantes / Bonnes pratiques

  • SORT fonctionne uniquement avec les tables standard - les tables triées et hachées ne peuvent pas être triées avec SORT.
  • Sans clause BY, le tri s’effectue selon la clé primaire.
  • Utilisez STABLE si l’ordre relatif des lignes avec clés égales doit être conservé.
  • AS TEXT est important pour un tri alphabétique correct avec trémas et caractères spéciaux.
  • Après le tri, vous pouvez utiliser READ TABLE ... BINARY SEARCH pour des recherches rapides.
  • Pour des données en permanence triées, les SORTED TABLE sont un meilleur choix que le tri répété d’une table standard.
  • Le tri n’est pas persistant - les nouvelles lignes (par ex. via APPEND) sont ajoutées à la fin et peuvent rompre le tri.