Les déclarations de données
La déclaration des données est une étape fondamentale dans tout programme ABAP. Elle permet de définir les variables, les constantes, les structures et les tables internes étant utilisées pour entreposer et manipuler les informations pendant l'exécution du programme.
En ABAP, toutes les déclarations doivent apparaître avant les instructions exécutables. Cette contrainte assure une séparation claire entre la définition des ressources et leur utilisation, ce qui facilite la compréhension et la maintenance du code.
Le système de déclaration ABAP offre plusieurs mécanismes complémentaires :
- Déclaration explicite avec TYPE : spécifier directement le type de données souhaite pour une variable.
- Déclaration par référence avec LIKE : reprendre le type d'une autre variable ou d'un champ du dictionnaire de données.
- Déclaration de types personnalises avec TYPES : créer des types réutilisables dans tout le programme.
- Déclaration de constantes avec CONSTANTS : définir des valeurs immuables accessibles globalement.
Le choix entre ces mécanismes dépend du contexte et des besoins de reutilisabilité. Une bonne pratique consiste a définir des types personnalisés pour les structures fréquemment utilisées, et a utiliser LIKE pour référencer les éléments du dictionnaire de données SAP.
Instruction DATA - Déclaration de variables
L'instruction DATA est le mécanisme principal pour déclarer des variables en ABAP. Elle alloue de la mémoire pour stocker une valeur et associe un nom symbolique a cette zone de mémoire.
Syntaxe complète :
|
DATA nom TYPE type [LENGTH longueur] [DECIMALS decimales] [VALUE valeur_initiale] [READ-ONLY]. |
Éléments de la syntaxe :
| Paramètre | Description |
|---|---|
| nom | Identifiant unique de la variable (max 30 caractères) |
| TYPE type | Spécification du type de données |
| LENGTH longueur | Taille pour les types C, N, X (optionnel) |
| DECIMALS décimales | Nombre de décimales pour le type P (optionnel) |
| VALUE valeur | Valeur initiale (optionnel) |
| READ-ONLY | Empêche la modification directe (optionnel, classes) |
Règles de nommage recommandées (conventions SAP) :
- gv_ : variable globale (Global Variable)
- lv_ : variable locale (Local Variable)
- pv_ : paramètre de fonction (Parameter Variable)
- cv_ : variable de retour (Changing Variable)
Exemples de déclarations simples :
- " Entier avec valeur initiale
- DATA gv_compteur TYPE I VALUE 0.
-
- " Chaine de caracteres avec longueur explicite
- DATA gv_nom TYPE C LENGTH 30.
-
- " Nombre decimal avec precision
- DATA gv_prix TYPE P LENGTH 8 DECIMALS 2.
-
- " Chaine de longueur variable
- DATA gv_texte TYPE STRING.
-
- " Date et heure
- DATA gv_date TYPE D VALUE sy-datum.
- DATA gv_heure TYPE T.
-
- " Reference au dictionnaire de donnees
- DATA gv_client TYPE kunnr. " Numero client SAP
- DATA gv_montant TYPE wrbtr. " Montant en devise
Initialisation automatique : toute variable déclarée sans clause VALUE reçoit automatiquement la valeur initiale de son type (0 pour les nombres, espaces pour les chaînes, '00000000' pour les dates,...).
Portée des variables : une variable déclarée avec DATA au niveau du programme (hors des procédures) est globale et accessible depuis tout le programme. Une variable déclarée dans une procédure (FORM, METHOD, FUNCTION) est locale a cette procédure.
Déclaration chaînée - Syntaxe avec deux-points
La déclaration chaînée permet de déclarer plusieurs variables en une seule instruction DATA, en utilisant le caractère deux-points (:) après le mot-clef et des virgules pour séparer les déclarations.
Syntaxe :
|
DATA: nom1 TYPE type1 [options1], nom2 TYPE type2 [options2], ... nomN TYPE typeN [optionsN]. |
Cette syntaxe est particulièrement utile pour :
- Regrouper les déclarations par thème ou fonction
- Réduire la répétition du mot-clef DATA
- Améliorer la lisibilité du code
Exemple détaillé :
- " Declarations groupees par fonction
- DATA: " Variables de travail
- lv_index TYPE I,
- lv_longueur TYPE I,
- lv_position TYPE I,
-
- " Variables de resultat
- lv_total TYPE P DECIMALS 2,
- lv_moyenne TYPE F,
-
- " Indicateurs
- lv_trouve TYPE ABAP_BOOL,
- lv_erreur TYPE ABAP_BOOL VALUE abap_false.
Bonnes pratiques pour les déclarations chaînées :
- Aligner les noms de variables pour une meilleure lisibilité
- Grouper les variables par fonction ou par type
- Ajouter des commentaires pour documenter les groupes
- Limiter le nombre de variables par chaîne (max 10-15)
Déclaration avec BEGIN OF - END OF intégrée :
La syntaxe chaînée permet aussi de déclarer directement des structures :
- DATA: BEGIN OF ls_donnees,
- id TYPE I,
- nom TYPE C LENGTH 30,
- actif TYPE ABAP_BOOL,
- END OF ls_donnees.
Cette forme est équivalente à définir un type puis déclarer une variable de ce type, mais sans créer de type reutilisable.
Instruction CONSTANTS - Déclaration de constantes
L'instruction CONSTANTS permet de déclarer des valeurs immuables qui ne peuvent pas être modifiées pendant l'exécution du programme. L'utilisation de constantes amélioré la lisibilité et la maintenabilité du code.
Syntaxe :
| CONSTANTS nom TYPE type VALUE valeur. |
Règles de nommage recommandées :
- gc_ : constante globale (Global Constant)
- lc_ : constante locale (Local Constant)
- c_ : forme abrégée acceptable
Avantages des constantes :
- Centralisation des valeurs fixes
- Modification facile (un seul endroit)
- Documentation du code (noms significatifs)
- Détection des erreurs a la compilation
Exemples de déclarations de constantes :
- " Constantes mathematiques
- CONSTANTS gc_pi TYPE F VALUE '3.14159265358979'.
- CONSTANTS gc_e TYPE F VALUE '2.71828182845904'.
-
- " Limites et seuils
- CONSTANTS gc_max_lignes TYPE I VALUE 1000.
- CONSTANTS gc_taux_tva TYPE P DECIMALS 2 VALUE '20.00'.
-
- " Codes et statuts
- CONSTANTS gc_statut_actif TYPE C LENGTH 1 VALUE 'A'.
- CONSTANTS gc_statut_inactif TYPE C LENGTH 1 VALUE 'I'.
- CONSTANTS gc_statut_bloque TYPE C LENGTH 1 VALUE 'B'.
-
- " Messages
- CONSTANTS gc_msg_erreur TYPE STRING VALUE 'Une erreur est survenue'.
Déclaration chaînée de constantes :
- CONSTANTS: gc_lundi TYPE I VALUE 1,
- gc_mardi TYPE I VALUE 2,
- gc_mercredi TYPE I VALUE 3,
- gc_jeudi TYPE I VALUE 4,
- gc_vendredi TYPE I VALUE 5,
- gc_samedi TYPE I VALUE 6,
- gc_dimanche TYPE I VALUE 7.
Constantes de structure :
Les constantes peuvent aussi être des structures avec des valeurs prédéfinies pour chaque champ :
- CONSTANTS: BEGIN OF gc_defaut,
- taille TYPE I VALUE 100,
- format TYPE C LENGTH 3 VALUE 'PDF',
- actif TYPE ABAP_BOOL VALUE abap_true,
- END OF gc_defaut.
Déclaration par référence - LIKE et TYPE REF TO
La clause LIKE permet de déclarer une variable en reprenant le type d'une autre variable existante ou d'un élément du dictionnaire de données SAP (tables, structures, éléments de données).
Syntaxe avec LIKE :
| DATA nom LIKE reference. |
Cas d'utilisation de LIKE :
- Copier le type d'une variable locale
- Référencer un champ d'une table du dictionnaire
- Assurer la cohérence avec les structures existantes
Exemples :
- " Reference a une variable locale
- DATA gv_original TYPE I.
- DATA gv_copie LIKE gv_original.
-
- " Reference a un champ de table du dictionnaire
- DATA gv_numero_client LIKE kna1-kunnr.
- DATA gv_nom_client LIKE kna1-name1.
- DATA gv_montant LIKE bseg-wrbtr.
-
- " Reference a la ligne d'une table
- DATA gt_clients LIKE TABLE OF kna1.
- DATA gs_client LIKE LINE OF gt_clients.
TYPE vs LIKE - Différences et recommandations :
- TYPE : référence a un type de données abstrait (type élémentaire, type défini avec TYPES, élément de données du dictionnaire).
- LIKE : référence a un objet de données concret (variable, champ de table, structure).
Recommandation moderne : depuis ABAP 7.40, il est préférable d'utiliser TYPE plutôt que LIKE pour la plupart des cas. LIKE reste utile pour référencer des champs de tables du dictionnaire ou pour copier le type d'une variable dynamiquement déterminée.
Types référence - TYPE REF TO :
Pour travailler avec des références (pointeurs), ABAP utilise la syntaxe TYPE REF TO :
- " Reference a un objet
- DATA lo_client TYPE REF TO zcl_client.
-
- " Reference a des donnees
- DATA lr_donnees TYPE REF TO ty_donnees.
- DATA lr_table TYPE REF TO DATA. " Reference generique
Instruction TYPES - Définition de types personnalises
L'instruction TYPES permet de créer des définitions de types réutilisables dans tout le programme. Ces types peuvent être des types élémentaires, des structures ou des types de tables.
Syntaxe pour types élémentaires :
| TYPES nom TYPE type_de_base [LENGTH longueur] [DECIMALS decimales]. |
Exemples :
- " Types elementaires personnalises
- TYPES ty_montant TYPE P LENGTH 15 DECIMALS 2.
- TYPES ty_code TYPE C LENGTH 10.
- TYPES ty_description TYPE STRING.
Syntaxe pour types structures :
- TYPES: BEGIN OF nom_structure,
- champ1 TYPE type1,
- champ2 TYPE type2,
- ...
- END OF nom_structure.
Exemple complet de structure :
- " Definition d'un type structure
- TYPES: BEGIN OF ty_employe,
- matricule TYPE N LENGTH 8,
- nom TYPE C LENGTH 40,
- prenom TYPE C LENGTH 30,
- service TYPE C LENGTH 4,
- salaire TYPE P LENGTH 8 DECIMALS 2,
- date_embauche TYPE D,
- actif TYPE ABAP_BOOL,
- END OF ty_employe.
-
- " Declaration de variables utilisant ce type
- DATA gs_employe TYPE ty_employe.
- DATA gt_employes TYPE TABLE OF ty_employe.
- DATA gs_backup TYPE ty_employe.
Structures imbriquées :
Les structures peuvent contenir d'autres structures pour modéliser des données complexes :
- TYPES: BEGIN OF ty_adresse,
- rue TYPE C LENGTH 60,
- code_postal TYPE N LENGTH 5,
- ville TYPE C LENGTH 40,
- pays TYPE C LENGTH 3,
- END OF ty_adresse.
-
- TYPES: BEGIN OF ty_client_complet,
- numero TYPE N LENGTH 10,
- nom TYPE C LENGTH 60,
- adresse_facturation TYPE ty_adresse,
- adresse_livraison TYPE ty_adresse,
- telephone TYPE C LENGTH 15,
- email TYPE C LENGTH 60,
- END OF ty_client_complet.
Inclusion de structures avec INCLUDE :
Pour éviter la duplication, on peut inclure une structure dans une autre avec la clause INCLUDE :
- TYPES: BEGIN OF ty_personne,
- nom TYPE C LENGTH 40,
- prenom TYPE C LENGTH 30,
- END OF ty_personne.
-
- TYPES: BEGIN OF ty_employe_v2.
- INCLUDE TYPE ty_personne.
- TYPES: matricule TYPE N LENGTH 8,
- service TYPE C LENGTH 4,
- END OF ty_employe_v2.
Structures - Définition et utilisation détaillée
Les structures sont des types de données composes regroupant plusieurs champs de types différents sous un même identificateur.
Elles sont essentielles pour modéliser des entités métier complexes.
Déclaration directe avec DATA BEGIN OF :
- DATA: BEGIN OF gs_commande,
- numero TYPE N LENGTH 10,
- date TYPE D,
- client TYPE N LENGTH 10,
- montant_ht TYPE P DECIMALS 2,
- tva TYPE P DECIMALS 2,
- montant_ttc TYPE P DECIMALS 2,
- statut TYPE C LENGTH 2,
- END OF gs_commande.
Accès aux champs d'une structure :
L'accès aux champs individuels se fait avec le tiret (-) :
- gs_commande-numero = '0000000001'.
- gs_commande-date = sy-datum.
- gs_commande-client = '0000123456'.
- gs_commande-montant_ht = '1000.00'.
- gs_commande-tva = gs_commande-montant_ht * '0.20'.
- gs_commande-montant_ttc = gs_commande-montant_ht + gs_commande-tva.
Affectation complète de structure :
On peut affecter une structure entière a une autre du même type :
- DATA gs_copie LIKE gs_commande.
- gs_copie = gs_commande. " Copie complete
Ou utiliser MOVE-CORRESPONDING pour copier les champs de même nom :
- DATA: BEGIN OF gs_resume,
- numero TYPE N LENGTH 10,
- montant_ttc TYPE P DECIMALS 2,
- END OF gs_resume.
-
- MOVE-CORRESPONDING gs_commande TO gs_resume.
Initialisation des structures :
- " Reinitialiser tous les champs a leur valeur initiale
- CLEAR gs_commande.
-
- " Reinitialiser un champ specifique
- CLEAR gs_commande-statut.
-
- " Verifier si une structure est initiale
- IF gs_commande IS INITIAL.
- WRITE: / 'La structure est vide'.
- ENDIF.
Tables internes - Déclaration et types de tables
Les tables internes sont des structures de données dynamiques permettant d'entreposer plusieurs lignes du même type. Elles sont fondamentales pour le traitement de collections de données en ABAP.
Types de tables internes :
ABAP supporte trois types principaux de tables internes, chacun optimise pour des usages spécifiques :
- TABLE STANDARD (par défaut) :
- Accès séquentiel ou par index
- Insertion rapide (a la fin)
- Recherche linéaire O(n)
- Adaptée aux petites collections
- SORTED TABLE :
- Toujours triée selon une clef
- Recherche binaire O(log n)
- Insertion triée automatique
- Adaptée aux recherches fréquentes
- HASHED TABLE :
- Accès par clef unique (hash)
- Recherche O(1) par clef
- Pas d'accès par index
- Adaptée aux grandes collections avec clef unique
Syntaxe de déclaration :
- " Table standard (defaut)
- DATA gt_donnees TYPE TABLE OF ty_ligne.
- DATA gt_clients TYPE STANDARD TABLE OF ty_client.
-
- " Table triee avec cle
- DATA gt_employes TYPE SORTED TABLE OF ty_employe
- WITH UNIQUE KEY matricule.
-
- " Table avec cle non unique
- DATA gt_commandes TYPE SORTED TABLE OF ty_commande
- WITH NON-UNIQUE KEY client.
-
- " Table hashee avec cle unique
- DATA gt_index TYPE HASHED TABLE OF ty_index
- WITH UNIQUE KEY code.
Déclaration complète avec toutes les options :
- TYPES: BEGIN OF ty_article,
- numero TYPE N LENGTH 10,
- designation TYPE C LENGTH 40,
- prix TYPE P DECIMALS 2,
- stock TYPE I,
- END OF ty_article.
-
- DATA gt_articles TYPE TABLE OF ty_article
- WITH HEADER LINE " (obsolete mais supporte)
- WITH KEY numero.
Syntaxe moderne (ABAP 7.40+) :
|
DATA gt_articles TYPE SORTED TABLE OF ty_article WITH UNIQUE KEY numero WITH NON-UNIQUE SORTED KEY k_prix COMPONENTS prix. |
Déclaration avec LIKE TABLE OF :
|
DATA gt_clients_vip LIKE TABLE OF gs_client. DATA gt_copie LIKE gt_clients. |
Field-symbols et références de données
Les field-symbols sont des pointeurs symboliques vers des zones de mémoire. Ils permettent d'accéder a des données de manière dynamique sans copier les valeurs.
Déclaration de field-symbols :
| FIELD-SYMBOLS fs_ligne TYPE ty_ligne. |
| FIELD-SYMBOLS fs_champ TYPE ANY. |
| FIELD-SYMBOLS fs_table TYPE ANY TABLE. |
Affectation avec ASSIGN :
|
DATA gv_valeur TYPE I VALUE 42. FIELD-SYMBOLS fs_val TYPE I. ASSIGN gv_valeur TO fs_val. fs_val = 100. " Modifie gv_valeur directement WRITE: / gv_valeur. " Affiche 100 |
Utilisation avec les tables internes :
|
LOOP AT gt_clients ASSIGNING FIELD-SYMBOL(<fs_client>). <fs_client>-statut = 'A'. " Modification directe ENDLOOP. |
Vérification d'affectation :
|
IF <fs_val> IS ASSIGNED. <" Le field-symbol pointe vers une donnee valide ENDIF. UNASSIGN <fs_val>. " Libere l'affectation |
Références de données avec GET REFERENCE :
- DATA lr_ref TYPE REF TO ty_client.
- DATA ls_client TYPE ty_client.
-
- GET REFERENCE OF ls_client INTO lr_ref.
-
- " Acces via la reference
- lr_ref->nom = 'Dupont'.
Écran de sélection - PARAMETERS et SELECT-OPTIONS
L'écran de sélection permet de définir des paramètres d'entrée que l'utilisateur peut renseigner avant l'exécution d'un report. C'est une fonctionnalité essentielle des programmes de type REPORT.
Instruction PARAMETERS :
| PARAMETERS nom TYPE type [DEFAULT valeur] [options]. |
Options principales de PARAMETERS :
- DEFAULT valeur : valeur par défaut
- OBLIGATORY : saisie obligatoire
- LOWER CASE : accepte les minuscules
- AS CHECKBOX : affiche comme case a cocher
- RADIOBUTTON GROUP grp : bouton radio dans un groupe
- MODIF ID id : identifiant pour modification dynamique
- NO-DISPLAY : paramètre cache
Exemples de PARAMETERS :
- " Parametre simple avec valeur par defaut
- PARAMETERS p_societe TYPE bukrs DEFAULT '1000'.
-
- " Parametre obligatoire
- PARAMETERS p_date TYPE sy-datum OBLIGATORY.
-
- " Case a cocher
- PARAMETERS p_actif AS CHECKBOX DEFAULT 'X'.
-
- " Boutons radio
- PARAMETERS: p_opt1 RADIOBUTTON GROUP grp1 DEFAULT 'X',
- p_opt2 RADIOBUTTON GROUP grp1,
- p_opt3 RADIOBUTTON GROUP grp1.
-
- " Parametre avec liste de valeurs (recherche F4)
- PARAMETERS p_client TYPE kunnr MATCHCODE OBJECT zsh_client.
Instruction SELECT-OPTIONS :
| SELECT-OPTIONS nom FOR variable [options]. |
Les SELECT-OPTIONS permettent de définir des intervalles de valeurs (intervals) pour les sélections. Le système crée automatiquement une table interne avec les champs SIGN, OPTION, LOW et HIGH.
Structure d'une ligne SELECT-OPTIONS :
- SIGN : 'I' (Include) ou 'E' (Exclude)
- OPTION : 'EQ', 'NE', 'GT', 'LT', 'GE', 'LE', 'BT' (Between),...
- LOW : valeur basse de l'intervalle
- HIGH : valeur haute de l'intervalle (pour BT)
Exemples de SELECT-OPTIONS :
- " Variable de reference pour SELECT-OPTIONS
- TABLES: kna1. " Ou: DATA gv_kunnr TYPE kna1-kunnr.
-
- " Selection de numeros de clients
- SELECT-OPTIONS s_kunnr FOR kna1-kunnr.
-
- " Selection de dates
- SELECT-OPTIONS s_date FOR sy-datum DEFAULT sy-datum.
-
- " Selection avec options
- SELECT-OPTIONS s_bukrs FOR t001-bukrs NO-EXTENSION
- NO INTERVALS.
Utilisation dans les requêtes SELECT :
- SELECT * FROM kna1
- WHERE kunnr IN s_kunnr
- AND land1 = p_pays
- INTO TABLE gt_clients.
Variables système - Structure SY
ABAP fournit une structure système SY (alias SYST) contenant des informations sur le contexte d'exécution. Ces champs sont en lecture seule et mis a jour automatiquement par le système.
Champs SY fréquemment utilises :
| Champ | Type | Description |
|---|---|---|
| sy-subrc | I | Code retour de la dernière opération |
| sy-datum | D | Date système (AAAAMMJJ) |
| sy-uzeit | T | Heure système (HHMMSS) |
| sy-uname | C(12) | Nom de l'utilisateur connecte |
| sy-langu | C(1) | Langue de connexion |
| sy-mandt | C(3) | Mandant de connexion |
| sy-sysid | C(8) | Identifiant du système SAP |
| sy-host | C(32) | Nom du serveur d'application |
| sy-index | I | Index de boucle (DO, WHILE) |
| sy-tabix | I | Index de ligne dans une table interne |
| sy-dbcnt | I | Nombre de lignes traitées par SELECT |
| sy-msgid | C(20) | Classe du dernier message |
| sy-msgno | N(3) | Numéro du dernier message |
| sy-msgty | C(1) | Type du dernier message (E/W/I/S) |
| sy-msgv1-v4 | C(50) | Variables du dernier message |
| sy-repid | C(40) | Nom du programme en cours |
| sy-tcode | C(20) | Code transaction en cours |
| sy-dynnr | N(4) | Numéro d'écran courant |
| sy-batch | C(1) | 'X' si exécution en traitement par lots |
Exemples d'utilisation :
- " Verification du code retour
- READ TABLE gt_clients WITH KEY numero = lv_num INTO gs_client.
- IF sy-subrc = 0.
- WRITE: / 'Client trouve:', gs_client-nom.
- ELSE.
- WRITE: / 'Client non trouve'.
- ENDIF.
-
- " Utilisation de la date et heure systeme
- gs_log-date_creation = sy-datum.
- gs_log-heure_creation = sy-uzeit.
- gs_log-utilisateur = sy-uname.
-
- " Index de boucle
- DO 10 TIMES.
- WRITE: / 'Iteration:', sy-index.
- ENDDO.
-
- " Index de table
- LOOP AT gt_articles INTO gs_article.
- gs_article-ligne = sy-tabix.
- ENDLOOP.
Bonnes pratiques pour les déclarations
Conventions de nommage recommandées :
| Préfixe | Signification | Exemple |
|---|---|---|
| gv_ | Variable globale | gv_compteur |
| lv_ | Variable locale | lv_index |
| gs_ | Structure globale | gs_client |
| ls_ | Structure locale | ls_donnees |
| gt_ | Table globale | gt_resultats |
| lt_ | Table locale | lt_temp |
| gf_ | Flag/booleen global | gf_traite |
| lf_ | Flag/booleen local | lf_erreur |
| gc_ | Constante globale | gc_max |
| lc_ | Constante locale | lc_taille |
| lo_ | Objet local | lo_document |
| go_ | Objet global | go_application |
| lr_ | Référence locale | lr_donnees |
| gr_ | Référence globale | gr_contexte |
Types personnalises :
| Préfixe | Signification | Exemple |
|---|---|---|
| ty_ | Type structure | ty_client |
| tt_ | Type table | tt_clients |
| tr_ | Type range | tr_numeros |
Organisation des déclarations :
Pour une meilleure lisibilité, organiser les déclarations dans l'ordre suivant :
- 1. TYPES (définitions de types personnalises)
- 2. CONSTANTS (constantes)
- 3. DATA (variables et structures simples)
- 4. DATA (tables internes)
- 5. FIELD-SYMBOLS (symboles de champ)
- 6. PARAMETERS et SELECT-OPTIONS (écran de sélection)
Exemple d'organisation :
- "======================================
- " Types personnalises
- "======================================
- TYPES: BEGIN OF ty_resultat,
- code TYPE N LENGTH 10,
- valeur TYPE P DECIMALS 2,
- END OF ty_resultat.
- TYPES tt_resultats TYPE TABLE OF ty_resultat.
-
- "======================================
- " Constantes
- "======================================
- CONSTANTS: gc_max_lignes TYPE I VALUE 1000,
- gc_version TYPE C LENGTH 5 VALUE '1.0.0'.
-
- "======================================
- " Variables globales
- "======================================
- DATA: gv_compteur TYPE I,
- gv_total TYPE P DECIMALS 2,
- gs_resultat TYPE ty_resultat.
-
- "======================================
- " Tables internes
- "======================================
- DATA: gt_resultats TYPE tt_resultats,
- gt_erreurs TYPE TABLE OF bapiret2.
-
- "======================================
- " Ecran de selection
- "======================================
- PARAMETERS p_annee TYPE gjahr OBLIGATORY.
- SELECT-OPTIONS s_bukrs FOR t001-bukrs.