Support Power Platform - Apps - Automate - SharePoint - Copilot

Les formules nommées (Formulas) dans Power Apps Canvas

Présentation générale

Les formules nommées constituent une fonctionnalité permettant de définir des calculs réutilisables au niveau de l’application. Contrairement aux variables qui stockent une valeur à un instant donné, les formules nommées sont recalculées automatiquement chaque fois que leurs dépendances changent, à l’image des formules dans Excel.

Cette fonctionnalité est accessible via l’objet App.Formulas dans le panneau de propriétés de l’application.

Différence fondamentale avec les variables

CaractéristiqueVariable (Set)Formule nommée
DéfinitionImpérative (action)Déclarative
Mise à jourManuelle via Set()Automatique
Moment du calculÀ l’exécution de Set()À chaque changement de dépendance
EmplacementN’importe où (OnSelect, OnVisible, etc.)App.Formulas uniquement
RéactivitéNon réactiveRéactive

Exemple comparatif

Avec une variable :

// Dans OnVisible ou OnSelect
Set(varTotalTTC, varTotalHT * 1.20)


// Problème : si varTotalHT change ailleurs, varTotalTTC n'est pas recalculé

Avec une formule nommée :

// Dans App.Formulas
frmTotalTTC = frmTotalHT * 1.20;


// Avantage : frmTotalTTC est recalculé automatiquement dès que frmTotalHT change

Syntaxe et déclaration

Les formules nommées se déclarent dans la propriété App.Formulas accessible en sélectionnant l’objet App dans l’arborescence.

Syntaxe de base

NomFormule = Expression;

Règles syntaxiques

  • Chaque formule se termine par un point-virgule
  • Les noms de formules doivent être uniques
  • Les formules peuvent référencer d’autres formules nommées
  • L’ordre de déclaration n’a pas d’importance (résolution automatique des dépendances)

Exemple de déclaration multiple

// Formules de configuration
frmTauxTVA = 0.20;
frmSeuilAlerte = 100;
frmDevise = "€";


// Formules calculées
frmTotalHT = Sum(colPanier, Prix * Quantite);
frmMontantTVA = frmTotalHT * frmTauxTVA;
frmTotalTTC = frmTotalHT + frmMontantTVA;


// Formule conditionnelle
frmMessageAlerte = If(
    frmTotalTTC > frmSeuilAlerte,
    "Montant élevé : validation requise",
    ""
);


// Formule formatée
frmAffichageTotal = Text(frmTotalTTC, "#,##0.00") & " " & frmDevise;

Types de formules nommées

Formules scalaires

Retournent une valeur unique (texte, nombre, booléen, date).

frmUtilisateurActuel = User().FullName;
frmDateAujourdhui = Today();
frmEstWeekend = Weekday(Today()) in [1, 7];
frmNombreClients = CountRows(colClients);

Formules de table

Retournent une table complète, utile pour centraliser des filtres ou transformations.

frmClientsActifs = Filter(colClients, Statut = "Actif");


frmVentesTriees = Sort(
    Filter(colVentes, Annee = Year(Today())),
    Montant,
    SortOrder.Descending
);


frmTopProduits = FirstN(
    Sort(colProduits, NombreVentes, SortOrder.Descending),
    10
);

Formules d’enregistrement

Retournent un enregistrement unique.

frmParametresApp = {
    Theme: "Clair",
    Langue: "fr-FR",
    NombreResultatsParPage: 20,
    ModeDebug: false
};


frmMeilleurVendeur = First(
    Sort(colVendeurs, ChiffreAffaires, SortOrder.Descending)
);

Formules avec tables statiques

Permettent de définir des données de référence.

frmListeStatuts = Table(
    { Code: "BRO", Libelle: "Brouillon", Couleur: RGBA(150,150,150,1) },
    { Code: "ENC", Libelle: "En cours", Couleur: RGBA(0,120,212,1) },
    { Code: "TER", Libelle: "Terminé", Couleur: RGBA(16,124,16,1) },
    { Code: "ANN", Libelle: "Annulé", Couleur: RGBA(168,0,0,1) }
);


frmJoursSemaine = Table(
    { Numero: 1, Nom: "Dimanche", Abrege: "Dim", EstOuvre: false },
    { Numero: 2, Nom: "Lundi", Abrege: "Lun", EstOuvre: true },
    { Numero: 3, Nom: "Mardi", Abrege: "Mar", EstOuvre: true },
    { Numero: 4, Nom: "Mercredi", Abrege: "Mer", EstOuvre: true },
    { Numero: 5, Nom: "Jeudi", Abrege: "Jeu", EstOuvre: true },
    { Numero: 6, Nom: "Vendredi", Abrege: "Ven", EstOuvre: true },
    { Numero: 7, Nom: "Samedi", Abrege: "Sam", EstOuvre: false }
);

Cas d’usage recommandés

Centralisation des calculs métier

// Règles de calcul centralisées
frmTauxRemiseStandard = 0.05;
frmTauxRemisePremium = 0.15;
frmSeuilPremium = 1000;


frmTauxRemiseApplicable = If(
    frmTotalHT >= frmSeuilPremium,
    frmTauxRemisePremium,
    frmTauxRemiseStandard
);


frmMontantRemise = frmTotalHT * frmTauxRemiseApplicable;
frmTotalApresRemise = frmTotalHT - frmMontantRemise;

Filtres réutilisables

// Filtres centralisés utilisables dans plusieurs galeries ou contrôles
frmCommandesEnAttente = Filter(
    colCommandes,
    Statut = "En attente" And DateCommande >= DateAdd(Today(), -30, TimeUnit.Days)
);


frmProduitsEnRupture = Filter(
    colProduits,
    Stock <= SeuilAlerte
);


frmTachesUrgentes = Filter(
    colTaches,
    Priorite = "Haute" And DateEcheance <= DateAdd(Today(), 7, TimeUnit.Days)
);

Données de configuration

frmConfigApp = {
    NomApplication: "Gestion des ventes",
    Version: "2.1.0",
    Environnement: "Production",
    UrlApi: "https://api.monentreprise.fr/v2",
    DelaiTimeout: 30,
    NombreMaxResultats: 500
};


// Utilisation
frmConfigApp.NomApplication
frmConfigApp.UrlApi

Traductions et libellés

frmLangue = "FR";


frmLibelles = If(
    frmLangue = "FR",
    {
        BtnValider: "Valider",
        BtnAnnuler: "Annuler",
        MsgErreur: "Une erreur est survenue",
        MsgSucces: "Opération réussie"
    },
    {
        BtnValider: "Submit",
        BtnAnnuler: "Cancel",
        MsgErreur: "An error occurred",
        MsgSucces: "Operation successful"
    }
);


// Utilisation dans un bouton
Text: frmLibelles.BtnValider

Dépendances et ordre d’évaluation

Les formules nommées gèrent automatiquement leurs dépendances. L’ordre de déclaration n’a aucune importance.

Exemple de chaîne de dépendances

// Ces formules peuvent être déclarées dans n'importe quel ordre
frmTotalTTC = frmTotalHT + frmMontantTVA;
frmMontantTVA = frmTotalHT * frmTauxTVA;
frmTotalHT = Sum(colPanier, PrixUnitaire * Quantite);
frmTauxTVA = 0.20;


// Power Apps résout automatiquement :
// 1. frmTauxTVA (aucune dépendance)
// 2. frmTotalHT (dépend de colPanier)
// 3. frmMontantTVA (dépend de frmTotalHT et frmTauxTVA)
// 4. frmTotalTTC (dépend de frmTotalHT et frmMontantTVA)

Détection des références circulaires

Power Apps détecte et signale les références circulaires.

// Erreur : référence circulaire
frmA = frmB + 1;
frmB = frmA + 1;

Limitations et contraintes

Ce que les formules nommées ne peuvent pas faire

LimitationAlternative
Appeler des fonctions comportementales (Collect, Navigate, Set, etc.)Utiliser OnSelect, OnChange, etc.
Modifier des donnéesUtiliser des actions dans les contrôles
Être modifiées pendant l’exécutionUtiliser des variables pour les valeurs dynamiques
Accéder au contexte d’un écran spécifiqueUtiliser des variables contextuelles

Fonctions non disponibles dans App.Formulas

// Ces fonctions ne peuvent PAS être utilisées dans App.Formulas
Collect()
ClearCollect()
Remove()
Patch()
Set()
UpdateContext()
Navigate()
Back()
Notify()
Launch()

Contournement pour les données modifiables

Combinez formules nommées et collections :

// Dans App.OnStart
ClearCollect(colPanier, Blank())


// Dans App.Formulas (calcul réactif sur la collection)
frmTotalPanier = Sum(colPanier, Prix * Quantite);
frmNombreArticles = CountRows(colPanier);
frmPanierVide = IsEmpty(colPanier);

Bonnes pratiques

Convention de nommage

// Préfixer les formules nommées pour les distinguer des variables
frmNomFormule     // Formule nommée
varNomVariable    // Variable globale
locNomVariable    // Variable contextuelle
colNomCollection  // Collection

Organisation par catégorie

// ═══════════════════════════════════════════════════════
// CONFIGURATION
// ═══════════════════════════════════════════════════════
frmTauxTVA = 0.20;
frmDevise = "EUR";
frmPaysDefaut = "France";


// ═══════════════════════════════════════════════════════
// UTILISATEUR
// ═══════════════════════════════════════════════════════
frmUtilisateurEmail = User().Email;
frmUtilisateurNom = User().FullName;
frmEstAdmin = frmUtilisateurEmail in ["admin@societe.fr", "superuser@societe.fr"];


// ═══════════════════════════════════════════════════════
// CALCULS MÉTIER
// ═══════════════════════════════════════════════════════
frmTotalHT = Sum(colPanier, Montant);
frmTotalTTC = frmTotalHT * (1 + frmTauxTVA);


// ═══════════════════════════════════════════════════════
// DONNÉES FILTRÉES
// ═══════════════════════════════════════════════════════
frmCommandesOuvertes = Filter(colCommandes, Statut <> "Fermé");
frmAlertes = Filter(colNotifications, NonLue = true);

Éviter les formules trop complexes

// À éviter : formule monolithique difficile à maintenir
frmResultatComplexe = If(
    And(
        CountRows(Filter(colA, X > 10)) > 5,
        Sum(Filter(colB, Y = "Active"), Z) > 1000
    ),
    First(Sort(Filter(colC, ...), ...)).Valeur * 1.2,
    Last(Sort(Filter(colD, ...), ...)).Valeur * 0.8
);


// Préférer : décomposition en formules intermédiaires
frmNombreElementsA = CountRows(Filter(colA, X > 10));
frmSommeElementsB = Sum(Filter(colB, Y = "Active"), Z);
frmConditionRemplie = frmNombreElementsA > 5 And frmSommeElementsB > 1000;
frmValeurCasVrai = First(Sort(Filter(colC, ...), ...)).Valeur * 1.2;
frmValeurCasFaux = Last(Sort(Filter(colD, ...), ...)).Valeur * 0.8;
frmResultatFinal = If(frmConditionRemplie, frmValeurCasVrai, frmValeurCasFaux);

Exemple complet d’application

Contexte

Application de gestion de commandes avec calculs automatiques.

App.OnStart

ClearCollect(
    colCommandes,
    { ID: 1, Client: "Dupont", Produit: "Laptop", Quantite: 2, PrixUnitaire: 899, Statut: "En cours" },
    { ID: 2, Client: "Martin", Produit: "Écran", Quantite: 3, PrixUnitaire: 349, Statut: "Livré" },
    { ID: 3, Client: "Bernard", Produit: "Clavier", Quantite: 5, PrixUnitaire: 79, Statut: "En cours" },
    { ID: 4, Client: "Petit", Produit: "Souris", Quantite: 10, PrixUnitaire: 29, Statut: "Annulé" }
)

App.Formulas

// Configuration
frmTauxTVA = 0.20;
frmSeuilCommandeImportante = 1000;


// Statuts disponibles
frmStatuts = Table(
    { Code: "En cours", Couleur: RGBA(0,120,212,1), Icone: Icon.Clock },
    { Code: "Livré", Couleur: RGBA(16,124,16,1), Icone: Icon.CheckBadge },
    { Code: "Annulé", Couleur: RGBA(168,0,0,1), Icone: Icon.Cancel }
);


// Commandes enrichies avec calculs
frmCommandesAvecTotaux = AddColumns(
    colCommandes,
    "TotalHT", Quantite * PrixUnitaire,
    "TotalTTC", Quantite * PrixUnitaire * (1 + frmTauxTVA),
    "EstImportante", Quantite * PrixUnitaire >= frmSeuilCommandeImportante
);


// Filtres par statut
frmCommandesEnCours = Filter(frmCommandesAvecTotaux, Statut = "En cours");
frmCommandesLivrees = Filter(frmCommandesAvecTotaux, Statut = "Livré");
frmCommandesAnnulees = Filter(frmCommandesAvecTotaux, Statut = "Annulé");


// Statistiques globales
frmStatsGlobales = {
    NombreTotal: CountRows(colCommandes),
    NombreEnCours: CountRows(frmCommandesEnCours),
    NombreLivrees: CountRows(frmCommandesLivrees),
    NombreAnnulees: CountRows(frmCommandesAnnulees),
    CATotal: Sum(frmCommandesAvecTotaux, TotalTTC),
    CAEnCours: Sum(frmCommandesEnCours, TotalTTC),
    CALivre: Sum(frmCommandesLivrees, TotalTTC),
    PanierMoyen: Average(frmCommandesAvecTotaux, TotalTTC)
};


// Alertes
frmCommandesImportantesEnAttente = Filter(
    frmCommandesEnCours,
    EstImportante = true
);


frmNombreAlertes = CountRows(frmCommandesImportantesEnAttente);
frmAfficherBadgeAlerte = frmNombreAlertes > 0;

Utilisation dans les contrôles

Galerie des commandes :

Items: frmCommandesAvecTotaux

Libellé du total :

Text: "CA total : " & Text(frmStatsGlobales.CATotal, "#,##0.00 €")

Badge d’alerte :

Visible: frmAfficherBadgeAlerte
Text: Text(frmNombreAlertes)

Indicateur panier moyen :

Text: "Panier moyen : " & Text(frmStatsGlobales.PanierMoyen, "#,##0.00 €")

Tableau récapitulatif

AspectDétail
EmplacementApp.Formulas uniquement
SyntaxeNomFormule = Expression;
Types retournésScalaire, table, enregistrement
RéactivitéAutomatique (recalcule sur changement de dépendance)
Fonctions interditesCollect, Set, Navigate, Patch, Remove, etc.
Références circulairesDétectées et signalées comme erreur
Ordre de déclarationSans importance
PortéeGlobale (toute l’application)