Les fondamentaux du langage X++
Aujourd’hui, je vous propose un guide fondamental pour plonger dans l’univers de la programmation X++, le langage clé pour travailler avec Dynamics 365 Finance and Operations. Que vous soyez débutant ou développeur chevronné, cet article vous donnera les bases et des astuces avancées pour coder efficacement en X++. On va couvrir les fondamentaux, des types de données aux techniques de gestion des exceptions, en passant par les requêtes SQL et les collections.
Contenu de l'article
- 1. Les types de données primitifs
- 2. Les types de données composites
- 3. Les types de données personnalisés
- 4. Déclarer des variables
- 5. Les opérateurs
- Opérateurs d’assignation
- Opérateurs arithmétiques
- Opérateurs binaires
- Opérateurs relationnels
- Opérateurs logiques
- Opérateurs spéciaux
- 6. Classes et méthodes en X++
- Déclaration de classe
- Instanciation
- Méthodes
- 7. Les collections
- Listes
- Maps
- Sets
- 8. Requêtes SQL
- Sélection
- Jointures
- Insertion
- Mise à jour
- Suppression
- 9. Instructions conditionnelles et itératives
- Conditionnelles
- Itératives
- 10. Constantes
- 11. Gestion des exceptions
- Throw
- Try…Catch
- 12. Messages utilisateur
- 13. Exceptions dans les transactions
- Conclusion
Prêt à booster vos compétences ? C’est parti !
1. Les types de données primitifs
En X++, les types de données primitifs sont la base de tout programme. Voici les plus utilisés :
- Date : Stocke le jour, le mois et l’année. Pour inclure l’heure et le fuseau horaire, utilisez utcDateTime.
- Enums : Liste de valeurs littérales nommées (ex. : NoYes::Yes).
- GUID : Identifiant unique global, parfait pour les réseaux.
- Int & Int64 : Entiers pour stocker des nombres sur 32 ou 64 bits.
- Real : Nombres décimaux.
- Str : Chaînes de texte entourées de guillemets.
- TimeOfDay : Compte les secondes depuis minuit.
- UtcDateTime : Combine date et heure au format yyyy-mm-ddThh:mm:ss.
2. Les types de données composites
Les types composites permettent de structurer des données plus complexes à partir des types primitifs:
- Arrays : Listes d’éléments d’un même type, avec longueur fixe ou dynamique.
- Containers : Collections flexibles pour plusieurs types de données.
- Classes : Définissent des objets avec des méthodes et des variables.
- Delegates : Permettent d’appeler des méthodes abonnées à des événements.
- Tables : Instances de tables avec convention de nommage en camelCase.
3. Les types de données personnalisés
Les Extended Data Types (EDTs) sont des types personnalisés basés sur les types primitifs comme int, real, str ou date. Ils améliorent la lisibilité et la réutilisation du code grâce à des propriétés globales, comme les étiquettes ou les longueurs.
4. Déclarer des variables
Les variables stockent des données en mémoire. Elles peuvent être globales (dans une classe) ou locales (dans une méthode). Exemple :
str customerName = "Patrick Mulenda"; // Déclaration d'une chaîne
Astuce : utilisez le camelCase (ex. : purchaseOrderLine) pour rendre votre code plus lisible !
5. Les opérateurs
Les opérateurs permettent de manipuler, comparer et assigner des valeurs. Voici un aperçu :
Opérateurs d’assignation
- = : Assigne une valeur (ex. : int i = 1;).
- += : Ajoute une valeur à la variable (ex. : i += 1;).
- ++ : Incrémente de 1 (ex. : i++;).
- -= : Soustrait une valeur (ex. : i -= 1;).
- — : Décrémente de 1 (ex. : i–;).
Opérateurs arithmétiques
- + : Addition (ex. : int a = 1 + 4; retourne 5).
- – : Soustraction (ex. : int a = 4 – 1; retourne 3).
- * : Multiplication (ex. : int a = 1 * 2;).
- / : Division (ex. : int a = 1 / 2;).
- div : Division entière (ex. : int a = 20 div 6; retourne 3).
- mod : Reste (ex. : int a = 20 mod 6; retourne 2).
- << : Décalage à gauche (ex. : int a = 1 << 2; retourne 4).
- >> : Décalage à droite (ex. : int a = 4 >> 1; retourne 2).
Opérateurs binaires
- ~ : NOT binaire (ex. : int a = ~1; retourne -2).
- & : AND binaire (ex. : int a = 1 & 3; retourne 1).
- | : OR binaire (ex. : int a = 1 | 3; retourne 3).
- ^ : XOR binaire (ex. : int a = 1 ^ 3; retourne 2).
Opérateurs relationnels
- == : Égalité.
- != : Différence.
- > : Supérieur.
- < : Inférieur.
- >= : Supérieur ou égal.
- <= : Inférieur ou égal.
Opérateurs logiques
- && : ET logique.
- || : OU logique.
- ! : NON logique.
Opérateurs spéciaux
- like : Utilisé dans les requêtes SQL (ex. : select a table where a field like ’12*’;).
- ? : : Opérateur ternaire (ex. : result = (x == 5) ? “Oui” : “Non”;).
6. Classes et méthodes en X++
Les classes sont au cœur de la programmation orientée objet en X++. Elles définissent l’état (via des variables) et le comportement (via des méthodes) des objets.
Déclaration de classe
Une classe inclut un nom, des variables d’instance et des modificateurs d’accès :
- Private : Accès limité à la classe.
- Protected : Accès dans la classe et ses sous-classes.
- Public : Accès depuis n’importe quelle classe.
Exemple :
public class CustomerDetails
{
private str custName;
}
Instanciation
Pour utiliser une classe, il faut l’instancier. Exemple avec une classe Truck :
public class Truck
{
public TruckLoad createNewTruckLoad()
{
TruckLoad myTruckLoad = new TruckLoad();
return myTruckLoad;
}
public void shipTruckLoad(TruckLoad _truckLoad)
{
_truckLoad.ship();
}
public static int calcTotalWeight(int netWeight, int tareWeight)
{
return netWeight + tareWeight;
}
}
Méthodes
- Méthodes d’instance : Nécessitent une instance de la classe.
- Méthodes statiques : Appelables directement sans instanciation.
Exemple de méthode :
public real ReturnCalculation(real _expression1)
{
real expression2 = 2;
return _expression1 * expression2;
}
7. Les collections
Les collections en X++ (comme les arrays, lists, maps, sets et structs) permettent de stocker et gérer des données efficacement.
Listes
Les listes stockent des valeurs d’un même type dans un ordre séquentiel.
Exemple :
internal final class CollectionClassListJob
{
public static void main(Args _args)
{
List list = new List(Types::Integer);
list.addEnd(10);
list.addEnd(20);
list.addStart(30);
ListIterator listI = new ListIterator(list);
while (listI.more())
{
Info(strFmt('%1', listI.value()));
listI.next();
}
}
}
Sortie : 30, 10, 20
Maps
Les maps associent des clés à des valeurs.
Exemple :
internal final class CollectionClassMapJob
{
public static void main(Args _args)
{
Map myMap = new Map(Types::Integer, Types::String);
myMap.insert(10, 'Valeur clé 10');
myMap.insert(20, 'Valeur clé 20');
MapEnumerator mapE = myMap.getEnumerator(); while (mapE.moveNext()) { Info(strFmt('Clé = %1 Valeur = %2', mapE.key(), mapE.value())); } }
}
Sortie : Clé = 10 Valeur = Valeur clé 10 Clé = 20 Valeur = Valeur clé 20
Sets
Les sets stockent des valeurs uniques.
Exemple :
internal final class CollectionClassSetJob
{
public static void main(Args _args)
{
Set mySet = new Set(Types::Int64);
SalesPool salesPool;
while select salesPool
{
if (mySet.in(salesPool.RecId))
{
continue;
}
mySet.add(salesPool.RecId);
}
}
}
8. Requêtes SQL
Les requêtes SQL en X++ permettent de manipuler les données dans la base de données de Dynamics 365.
Sélection
Les instructions select récupèrent des données. Exemple :
Select AccountNum from custtable;
Avec filtrage et tri :
Select forUpdate CustTable order by AccountNum desc
where custTable.accountNum > '1000'
&& custTable.accountNum < '2000';
Jointures
Joignez plusieurs tables avec une clause join :
SalesTable SalesTable;
SalesLine SalesLine;
select SalesLine
join SalesTable
where SalesLine.SalesId == SalesTable.SalesId;
{
info(strFmt("SalesId : %1, ItemId : %2, CustAccount : %3",
SalesLine.SalesId, SalesLine.ItemId, SalesTable.CustAccount));
}
Insertion
Ajoutez des enregistrements avec insert :
FMCustomer fmCustomer;
ttsBegin;
fmCustomer.FirstName = "Jean";
fmCustomer.LastName = "Dupont";
fmCustomer.Email = "jean.dupont@example.com";
fmCustomer.insert();
ttsCommit;
Info("Nouveau client créé.");
Mise à jour
Modifiez des enregistrements avec update :
FMCustomer fmcustomer;
select forUpdate fmcustomer
where fmcustomer.firstname == 'Jean';
ttsBegin;
fmcustomer.firstname = 'Jean-Pierre';
fmcustomer.update();
ttsCommit;
Info("Enregistrement mis à jour.");
Suppression
Supprimez des enregistrements avec delete :
FMCustomer fmcustomer;
select forUpdate fmcustomer
where fmcustomer.firstname == 'Jean-Pierre';
ttsBegin;
fmcustomer.delete();
ttsCommit;
Info("Enregistrement supprimé.");
9. Instructions conditionnelles et itératives
Conditionnelles
If : Exécute un bloc si une condition est vraie.
if (x == 5)
{
info('x vaut cinq');
}
If…else : Ajoute une alternative si la condition est fausse.
if (x == 5)
{
info('x vaut cinq');
}
else
{
info('x ne vaut pas cinq');
}
Switch : Vérifie une valeur contre plusieurs cas.
switch (x)
{
case 5:
info('x vaut 5');
break;
default:
info('Valeur par défaut');
break;
}
Itératives
While : Boucle tant qu’une condition est vraie.
int loopCount = 1;
while (loopCount <= 10)
{
info(strFmt('Tour %1', loopCount));
loopCount++;
}
Do…while : Exécute au moins une fois.
int findPower(real _value)
{
int ex = -1;
real curVal;
do
{
ex += 1;
curVal = power(10, ex);
}
while (_value > curVal);
return ex;
}
For : Boucle pour un nombre défini d’itérations.
for (int i = 1; i <= 100; i++)
{
info(strFmt('Valeur : %1', i));
}
10. Constantes
Les constantes sont des valeurs immuables définies avec le mot-clé const.
const str constantVariable = "ValeurFixe";
11. Gestion des exceptions
La gestion des exceptions permet de gérer les erreurs de manière élégante.
Throw
Déclenche une exception manuellement :
throw error("Une erreur s'est produite.");
Try…Catch
Tente d’exécuter du code et capture les exceptions :
try
{
// Code risqué
}
catch (Exception::Numeric)
{
info('Exception numérique détectée.');
}
catch
{
info('Exception générale capturée.');
}
12. Messages utilisateur
L’API Message permet de gérer les messages de manière flexible :
messageId = Message::Add(MessageSeverity::Informational, "Le client est inactif.");
13. Exceptions dans les transactions
Dans une transaction (ttsBegin/ttsCommit), une exception déclenche un rollback automatique (ttsAbort).
Pour approfondir sur ce sujet, vous pouvez visiter ce lien : Microsoft
Pour préparer votre projet, j’ai écrit un article sur cela ici
Conclusion
Avec ces concepts (types de données, opérateurs, classes, collections, SQL, etc.), vous êtes prêt à écrire du code X++ propre et efficace. Sur mon blog, je partagerai d’autres astuces pour apprendre Dynamics 365.
Qu’en pensez-vous ? Laissez un commentaire pour partager vos propres expériences avec X++ !




Je trouve l’article interressant , mais seulement vous auriez du commencer par le debut c’est-à-dire comment installer X++ dans un environnement. Merci pour l’article concis et precis