Query et QueryBuildDataSource en X++ : exemples de requêtes dynamiques
Construire une requête dynamique en X++ : Query, QueryBuildDataSource, QueryBuildRange, liens et QueryRun. Exemples Microsoft Learn et erreurs fréquentes.
La réponse courte
Une requête dynamique X++ se construit avec le modèle objet Query : un objet Query, des sources de données QueryBuildDataSource (une source enfant d'une autre crée une jointure), des plages QueryBuildRange (traduites en clause WHERE), des liens QueryBuildLink entre sources, puis QueryRun pour exécuter la requête et parcourir les résultats.
On l'utilise quand la requête doit être modifiable par l'utilisateur (boîte de dialogue d'un batch ou d'un état), réutilisée par un framework (suivi des modifications, data provider) ou construite selon des paramètres. Pour une simple lecture codée en dur, un select X++ reste plus lisible. Microsoft propose aussi l'API SysDa pour des requêtes extensibles sans le surcoût de QueryRun.
Les classes du modèle Query
- Query : le haut de la définition, avec une ou plusieurs sources de données.
- QueryBuildDataSource : l'accès à une source. Deux sources au même niveau produisent des requêtes SQL séparées ; une source enfant crée une jointure.
- QueryBuildFieldList : les champs retournés (tous par défaut), avec agrégats possibles (SUM, COUNT, AVG).
- QueryBuildRange : une restriction sur un champ, traduite en WHERE.
- QueryBuildLink : la relation entre deux sources jointes (sur la source enfant).
- QueryBuildDynalink : un lien vers un enregistrement externe, utilisé notamment par les formulaires synchronisés.
- QueryRun : exécute la requête et récupère les données.
Exemple : jointures, plage et liens
Exemple de Microsoft Learn (requête de suivi des modifications) : clients, parties, adresse principale.
public static Query defaultCTQuery()
{
Query q = new Query();
QueryBuildDataSource custDs = q.addDataSource(tableNum(CustTable));
QueryBuildDataSource partyDs = custDs.addDataSource(tableNum(DirPartyTable));
partyDs.relations(true);
QueryBuildDataSource locationDs = partyDs.addDataSource(tableNum(DirPartyLocation));
locationDs.addRange(fieldNum(DirPartyLocation, IsPrimary)).value(queryValue(NoYes::Yes));
locationDs.addLink(fieldNum(DirPartyTable, RecId), fieldNum(DirPartyLocation, Party));
return q;
}relations(true) utilise les relations définies sur les tables ; addLink précise explicitement les champs de jointure ; queryValue convertit une valeur en chaîne de plage. Pour parcourir les résultats :
QueryRun queryRun = new QueryRun(query);
while (queryRun.next())
{
CustTable custTable = queryRun.get(tableNum(CustTable));
// ...
}Erreurs fréquentes
- Ajouter deux sources au même niveau en pensant faire une jointure : ce sont deux requêtes séparées.
- Construire une plage par concaténation de texte sans queryValue : risque d'erreur sur les caractères spéciaux.
- Dans un formulaire, ajouter une plage après super() dans executeQuery : règle BP BPCheckinvalidExecuteQuery.
- Utiliser QueryRun pour une lecture simple et fixe : un select est plus clair, ou SysDa si l'extensibilité compte.
- Oublier relations(true) ou addLink : jointure produit cartésien.
Faire générer ce développement
Requêtes dynamiques de batch, d'état ou de data provider : un code répétitif, que l'IA génère bien quand le contexte est fourni. Skalp AI rédige la spécification, génère le code X++ et les tests unitaires, compile en contrôlant les bonnes pratiques, puis livre par pull request dans votre Azure DevOps : rien n'est fusionné sans la validation de votre architecte technique. Voir développement X++ par IA, le cadre général dans développer en X++ sans consultant en 2026, et les offres Basic, Pro et Max (1 crédit, ≈ 400 € en Basic, 200 € en Pro, consommé seulement à la génération du code).
À lire aussi : champ calculé dans une data entity.
Sources
- Microsoft Learn, « X++ class library », mise à jour du 31/03/2026, consultée le 18/10/2026.
- Microsoft Learn, « Enable SQL change tracking for data entities », mise à jour du 26/09/2026, consultée le 18/10/2026.
- Microsoft Learn, « Access data by using the SysDa classes », mise à jour du 31/03/2026, consultée le 18/10/2026.
Questions fréquentes
Comment faire une jointure avec QueryBuildDataSource ?
Ajoutez la seconde source comme enfant de la première (parentDs.addDataSource(...)), puis relations(true) ou addLink pour préciser les champs.
Query ou select en X++ ?
Select pour une lecture fixe et lisible ; Query quand la requête doit être modifiable par l'utilisateur ou construite dynamiquement. SysDa pour des requêtes extensibles sans surcoût.
À quoi sert queryValue ?
À convertir une valeur (énumération, date, texte) en chaîne correctement formatée pour une plage de requête.
Prêt à transformer votre D365 ?
Rejoignez les DSI qui développent leurs tickets D365 en 2 à 4 h pour 1 crédit (≈ 400 € en Basic, 200 € en Pro).