ABAP VALUE et NEW : Expressions de constructeur pour données et objets

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

Les expressions de constructeur VALUE et NEW sont des fonctionnalités fondamentales de l’ABAP moderne (à partir de 7.40). Elles permettent la création en ligne de données et d’objets sans déclaration et affectation séparées.

VALUE – Créer des données en ligne

L’opérateur VALUE crée des valeurs pour structures, tables internes et types de données élémentaires.

Syntaxe

VALUE <type>( [Composants/Lignes] )
VALUE #( [Composants/Lignes] ) " Le type est déduit

Exemples pour VALUE

1. Créer une structure

TYPES: BEGIN OF ty_person,
name TYPE string,
age TYPE i,
city TYPE string,
END OF ty_person.
" Classique (ancien)
DATA: ls_person TYPE ty_person.
ls_person-name = 'Max'.
ls_person-age = 30.
ls_person-city = 'Berlin'.
" Moderne avec VALUE
DATA(ls_person2) = VALUE ty_person(
name = 'Max"
age = 30
city = 'Berlin"
).
" Avec déduction de type (#)
DATA: ls_target TYPE ty_person.
ls_target = VALUE #( name = 'Anna' age = 25 city = 'Munich' ).

2. Créer une table interne

TYPES: ty_names TYPE TABLE OF string WITH EMPTY KEY.
" Remplir la table avec des valeurs
DATA(lt_names) = VALUE ty_names(
( `Anna` )
( `Bernd` )
( `Clara` )
).
" Table structurée
DATA(lt_persons) = VALUE ty_persons(
( name = 'Max' age = 30 city = 'Berlin' )
( name = 'Anna' age = 25 city = 'Munich' )
( name = 'Peter' age = 35 city = 'Hambourg' )
).

3. Étendre une table existante (BASE)

DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 1 ) ( 2 ) ( 3 ) ).
" Ajouter d'autres lignes avec BASE
lt_numbers = VALUE #(
BASE lt_numbers
( 4 )
( 5 )
( 6 )
).
" Résultat : 1, 2, 3, 4, 5, 6

4. Structures imbriquées

TYPES: BEGIN OF ty_address,
street TYPE string,
zip TYPE string,
city TYPE string,
END OF ty_address,
BEGIN OF ty_customer,
id TYPE i,
name TYPE string,
address TYPE ty_address,
END OF ty_customer.
DATA(ls_customer) = VALUE ty_customer(
id = 1
name = 'Müller GmbH"
address = VALUE #(
street = 'Hauptstraße 1"
zip = '10115"
city = 'Berlin"
)
).

5. Valeur initiale avec VALUE

DATA: ls_person TYPE ty_person.
" Initialiser la structure (tous les champs à la valeur initiale)
ls_person = VALUE #( ).
" Ne définir que certains champs, le reste initial
ls_person = VALUE #( name = 'Test' ).
" age et city sont 0 ou vides

6. OPTIONAL et DEFAULT

DATA: lt_customers TYPE TABLE OF ty_customer.
" Chercher une ligne - si non trouvée : valeur initiale
DATA(ls_found) = VALUE #( lt_customers[ id = 999 ] OPTIONAL ).
" Si non trouvée : valeur par défaut
DATA(ls_default) = VALUE #(
lt_customers[ id = 999 ]
DEFAULT VALUE #( id = 0 name = 'Inconnu' )
).

7. VALUE avec LET (variables d’aide locales)

DATA(ls_result) = VALUE ty_person(
LET prefix = 'Dr. "
suffix = ' (PDG)"
IN
name = prefix && 'Max Müller' && suffix
age = 45
city = 'Francfort"
).
" name = 'Dr. Max Müller (PDG)"

8. FOR dans VALUE (construction de table)

" Créer une table à partir d'une autre
DATA(lt_names_only) = VALUE ty_names(
FOR ls_p IN lt_persons
( ls_p-name )
).
" Avec condition
DATA(lt_adults) = VALUE ty_persons(
FOR ls_p IN lt_persons
WHERE ( age >= 18 )
( ls_p )
).
" Avec transformation
DATA(lt_upper_names) = VALUE ty_names(
FOR ls_p IN lt_persons
( to_upper( ls_p-name ) )
).

NEW – Créer des objets en ligne

L’opérateur NEW crée des instances de classes ou des objets de données anonymes.

Syntaxe

NEW <nom_classe>( [Paramètres constructeur] )
NEW #( [Paramètres constructeur] ) " Le type est déduit

Exemples pour NEW

1. Créer un objet

CLASS lcl_calculator DEFINITION.
PUBLIC SECTION.
METHODS: add IMPORTING iv_a TYPE i iv_b TYPE i
RETURNING VALUE(rv_result) TYPE i.
ENDCLASS.
CLASS lcl_calculator IMPLEMENTATION.
METHOD add.
rv_result = iv_a + iv_b.
ENDMETHOD.
ENDCLASS.
" Classique (ancien)
DATA: lo_calc TYPE REF TO lcl_calculator.
CREATE OBJECT lo_calc.
" Moderne avec NEW
DATA(lo_calc2) = NEW lcl_calculator( ).
" Utiliser directement
DATA(lv_sum) = NEW lcl_calculator( )->add( iv_a = 5 iv_b = 3 ).

2. Objet avec paramètres de constructeur

CLASS lcl_person DEFINITION.
PUBLIC SECTION.
METHODS: constructor IMPORTING iv_name TYPE string
iv_age TYPE i.
DATA: mv_name TYPE string READ-ONLY,
mv_age TYPE i READ-ONLY.
ENDCLASS.
CLASS lcl_person IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
mv_age = iv_age.
ENDMETHOD.
ENDCLASS.
" Créer un objet avec paramètres
DATA(lo_person) = NEW lcl_person(
iv_name = 'Max Müller"
iv_age = 30
).
WRITE: / lo_person->mv_name, lo_person->mv_age.

3. Objets de données anonymes (références de données)

" Créer une référence entière
DATA(lr_int) = NEW i( 42 ).
WRITE: / lr_int->*. " 42
" Référence chaîne
DATA(lr_string) = NEW string( 'Bonjour le monde' ).
" Référence structure
DATA(lr_person) = NEW ty_person(
name = 'Test"
age = 25
).

4. Tables dans des objets

" Table interne comme référence
DATA(lr_table) = NEW ty_persons(
( name = 'A' age = 20 )
( name = 'B' age = 30 )
).
LOOP AT lr_table->* INTO DATA(ls_p).
WRITE: / ls_p-name.
ENDLOOP.

5. Déduction de type avec

DATA: lo_obj TYPE REF TO lcl_calculator.
" Le type est déduit de lo_obj
lo_obj = NEW #( ).
" Pour les paramètres de méthode
METHODS: process IMPORTING io_calc TYPE REF TO lcl_calculator.
" Appel
process( io_calc = NEW #( ) ).

CONV – Conversion de type

L’opérateur CONV convertit des valeurs en un autre type :

" Chaîne vers entier
DATA(lv_int) = CONV i( '42' ).
" Entier vers chaîne
DATA(lv_str) = CONV string( 42 ).
" Nombre décimal
DATA(lv_dec) = CONV decfloat34( '123.456' ).
" Pour les calculs
DATA(lv_result) = CONV f( 10 / 3 ). " 3.333...

Comparaison : Classique vs. Moderne

" === CLASSIQUE ===
" Structure
DATA: ls_person TYPE ty_person.
ls_person-name = 'Max'.
ls_person-age = 30.
" Table
DATA: lt_persons TYPE ty_persons,
ls_temp TYPE ty_person.
ls_temp-name = 'Max'.
ls_temp-age = 30.
APPEND ls_temp TO lt_persons.
" Objet
DATA: lo_calc TYPE REF TO lcl_calculator.
CREATE OBJECT lo_calc.
" === MODERNE ===
" Structure
DATA(ls_person) = VALUE ty_person( name = 'Max' age = 30 ).
" Table
DATA(lt_persons) = VALUE ty_persons(
( name = 'Max' age = 30 )
).
" Objet
DATA(lo_calc) = NEW lcl_calculator( ).

Remarques importantes / Bonnes pratiques

  • VALUE #() déduit le type du contexte – utilisez-le pour les affectations.
  • VALUE type() spécifie explicitement le type – nécessaire pour les déclarations inline DATA().
  • BASE conserve le contenu existant de la table lors de l’extension.
  • NEW #() pour la création d’objets, VALUE #() pour les données.
  • Combinez avec FOR pour des opérations puissantes sur les tables.
  • OPTIONAL renvoie une valeur initiale, DEFAULT une valeur spécifique.
  • LET permet des variables d’aide locales dans l’expression.
  • Utilisez COND et CORRESPONDING pour d’autres expressions de constructeur.