Champ calculé Dynamics 365 F&O : computed column ou champ virtuel
Dans une data entity D365 F&O, un champ calculé est une colonne SQL générée par une méthode X++ statique. Quand le préférer au champ virtuel, code, pièges.
La réponse courte
Dans Dynamics 365 Finance & Operations, un « champ calculé » d'une data entity est un champ non mappé dont la valeur est calculée par SQL Server. On le crée avec un champ « Unmapped » dont la propriété IsComputedField vaut Yes, et une méthode X++ statique qui renvoie l'expression SQL. Cette méthode n'est appelée qu'à la synchronisation de la base : à l'exécution, SQL calcule la valeur directement dans la vue de l'entité.
L'autre option est le champ virtuel (IsComputedField = No) : sa valeur est calculée en X++, ligne par ligne, par exemple dans postLoad. Microsoft recommande les champs calculés quand c'est possible, parce qu'ils sont calculés au niveau de SQL Server. Les champs virtuels ne permettent ni la recherche ni le filtrage.
Note : si vous cherchez un « champ calculé » au sens d'une formule sur un formulaire, c'est souvent une méthode display ; cet article traite des data entities, utilisées pour l'import/export, OData et les intégrations.
Champ calculé ou champ virtuel : comment choisir ?
- Champ calculé : valeur produite par une colonne calculée de la vue SQL ; lu directement depuis la vue ; idéal pour la lecture et l'export ; filtrable.
- Champ virtuel : non persisté, lu et écrit par du code X++ ; à réserver aux valeurs impossibles à exprimer en SQL ; ni recherche ni filtre.
- En écriture, les deux passent par du X++ (par exemple mapEntityToDataSource) qui répartit la valeur reçue dans les vrais champs des data sources.
Conséquence sur les performances d'export : Microsoft déconseille postLoad, qui force l'export à passer par la table de staging pour appeler la méthode à chaque ligne. Préférez une colonne calculée quand la valeur peut être produite par SQL.
Créer un champ calculé pas à pas
L'exemple de Microsoft Learn ajoute à l'entité FMCustomerEntity un champ NameAndAddress qui concatène nom et adresse :
- Dans le designer de l'entité, clic droit sur Fields > New > String Unmapped Field ; nommez-le NameAndAddress.
- Laissez IsComputedField à Yes et renseignez la propriété de méthode (DataEntityView Method / ComputedFieldMethod) avec le nom de la méthode statique.
- Créez cette méthode statique ; elle construit l'expression SQL avec la classe SysComputedColumn (returnField, returnLiteral, addList, cast…).
- Recompilez, puis synchronisez la base : la colonne est créée dans la vue SQL de l'entité.
Version simplifiée de la méthode :
private static str formatNameAndAddress()
{
DataEntityName dataEntityName = tablestr(FMCustomerEntity);
List fieldList = new List(types::String);
fieldList.addEnd(SysComputedColumn::returnField(dataEntityName,
identifierstr(FMCustomer), fieldstr(FMCustomer, FirstName)));
fieldList.addEnd(SysComputedColumn::returnLiteral(" "));
fieldList.addEnd(SysComputedColumn::returnField(dataEntityName,
identifierstr(FMCustomer), fieldstr(FMCustomer, LastName)));
fieldList.addEnd(SysComputedColumn::returnLiteral("; "));
fieldList.addEnd(SysComputedColumn::returnField(dataEntityName,
identifierstr(FMAddressTable), fieldstr(FMAddressTable, City)));
return SysComputedColumn::addList(fieldList);
}Astuce donnée par Microsoft : en cas d'erreur de synchronisation, mettez d'abord au point l'expression SQL dans SQL Server Management Studio, puis traduisez-la en X++.
Et le champ virtuel ?
Créez un champ Unmapped avec IsComputedField = No, puis surchargez postLoad pour calculer la valeur à la lecture :
public void postLoad()
{
super();
// Champ virtuel : « Nom, Prénom »
this.FullName = this.LastName + ", " + this.FirstName;
}Pour accepter cette valeur en écriture (par exemple un système externe qui envoie « Nom, Prénom »), surchargez mapEntityToDataSource et répartissez la valeur dans les champs du data source concerné.
Erreurs fréquentes
- Oublier la synchronisation de la base après la compilation : la colonne n'existe pas dans la vue.
- Écrire une jointure dans l'expression SQL : Microsoft recommande d'ajouter plutôt la table nécessaire comme data source de l'entité, sinon SQL calcule ligne par ligne.
- Laisser la méthode lever une exception : la synchronisation l'intercepte, met la colonne à NULL et écrit seulement un avertissement. Vérifiez les clés de configuration dans la méthode.
- Utiliser postLoad (champ virtuel) pour un simple formatage : l'export passe par la table de staging et ralentit.
- Mélanger les types sans cast : utilisez SysComputedColumn::cast pour les champs numériques ou dates concaténés.
Aller plus loin
Pour créer l'entité elle-même et l'exporter, lisez créer une data entity et l'exporter avec DMF. Skalp AI génère ce type de développement (entité, champs calculés, tests unitaires), livré sur votre Azure DevOps et validé par votre DSI : voir data entities et packages DMF, le cadre général dans développer en X++ sans consultant en 2026 et les offres Basic, Pro et Max.
Sources
- Microsoft Learn, « Computed columns and virtual fields in data entities », mise à jour du 14/01/2026, consultée le 11/10/2026.
- Microsoft Learn, « Data entity export performance tips », mise à jour du 26/09/2026, consultée le 11/10/2026.
Questions fréquentes
Un champ calculé est-il stocké en base ?
Non. C'est une colonne calculée de la vue SQL de l'entité. En écriture, du code X++ répartit la valeur dans les champs réels des data sources, qui eux sont stockés.
Peut-on filtrer sur un champ virtuel ?
Non, la recherche et le filtrage ne sont pas pris en charge sur les champs virtuels. Utilisez un champ calculé si vous devez filtrer.
Pourquoi mon champ calculé renvoie-t-il NULL ?
La méthode qui génère l'expression SQL a probablement levé une exception pendant la synchronisation : la colonne est alors mise à NULL avec un simple avertissement. Vérifiez le journal de synchronisation et les clés de configuration.
Prêt à transformer votre D365 ?
Rejoignez les DSI qui développent leurs tickets D365 en 1h pour 1 crédit (≈ 400 € en Basic, 200 € en Pro).