Support formation Rapports Power BI

4 | Valeurs et expressions

En bref

  • Objectifs : distinguer valeurs primitives et valeurs structurées ; écrire et manipuler listes, enregistrements et tables ; accéder à une ligne, une colonne ou une cellule ; gérer les erreurs avec try, otherwise et error.
  • Prérequis : chapitres 1 à 3 de la série.
  • Niveau : avancé.

Pourquoi ?

Le code M manipule en permanence des listes (les valeurs d'une colonne), des enregistrements (une ligne) et des tables. Savoir les écrire et y accéder permet de lire une valeur précise d'une autre requête, de tester une transformation sur une petite table saisie dans le code, ou de remplacer une valeur fixe par une valeur calculée.

Notions clés

Les catégories de valeurs

  1. Valeurs primitives : une donnée élémentaire (nombre, texte, date...).
  2. Valeurs structurées : elles contiennent d'autres valeurs. Il en existe trois : les listes, les enregistrements et les tables.
  3. Fonctions : en M, une fonction est une valeur comme une autre (chapitre « Techniques avancées en M »).
  4. Types : des valeurs qui décrivent le type d'autres valeurs (chapitre 5).
CatégorieTypeExemple de littéral
PrimitiveNullnull
PrimitiveLogiquetrue, false
PrimitiveNombre0, 5, -5, 1.5
PrimitiveHeure#time(20, 15, 30)
PrimitiveDate#date(2024, 3, 1)
PrimitiveDate et heure#datetime(2023, 5, 10, 20, 15, 30)
PrimitiveDate, heure et fuseau#datetimezone(2023, 5, 10, 20, 15, 30, 9, 0)
PrimitiveDurée#duration(5, 2, 15, 0) (5 jours, 2 heures, 15 minutes)
PrimitiveTexte"bonjour"
PrimitiveBinaire#binary("AQID")
StructuréeListe{1, 2, 3}
StructuréeEnregistrement[A = 1, B = 2]
StructuréeTable#table({"X", "Y"}, {{0, 1}, {1, 0}})
FonctionFonction(x) => x + 1
TypeTypetype text, type table [A = any, B = text]

Listes

Une liste s'écrit entre accolades ; elle peut contenir des valeurs de toute nature :

{"a", {4, 5, 6}, [Column1 = 1, Column2 = "v"], #table({"ID", "Produit"}, {{1, "Pomme"}})}
List.Sort(List.Combine({{1, 4}, {2, 5}}))    // renvoie {1, 2, 4, 5}
List.Numbers(1, 5, 1)                         // renvoie {1, 2, 3, 4, 5}
{1..5}                                        // renvoie aussi {1, 2, 3, 4, 5}

L'opérateur .. crée une plage, y compris de caractères, et & concatène deux listes :

let
    Lettres = {"a".."z"},
    Chiffres = {"0".."9"},
    Autorises = Lettres & Chiffres,
    Resultat = Text.Select("inv-1006-!**!-(act)", Autorises)
in
    Resultat

Résultat : « inv1006act ». Le n-ième élément s'obtient par Liste{n}, en commençant à 0 : {"a", "b", "c"}{1} renvoie « b ».

Enregistrements

Un enregistrement est un ensemble de champs nommés, entre crochets ; c'est la forme d'une ligne de table.

let
    Client = [Nom = "Durand", Ville = "Lyon", CA = 12500],
    Ville = Client[Ville],                       // "Lyon"
    Region = Client[Region]?,                    // null au lieu d'une erreur
    Champ = Record.Field(Client, "CA")           // 12500, nom du champ passé en texte
in
    Champ

Record.Field permet de choisir le champ par son nom calculé, à la manière de la fonction INDIRECT d'Excel. Dans une colonne personnalisée, Record.Field(_, [Champ]) lit la colonne dont le nom figure dans la colonne Champ. Source

Tables et accès aux valeurs

SyntaxeRésultat
Table[Colonne]La colonne, sous forme de liste
Table{0}La première ligne, sous forme d'enregistrement
Table{0}[Colonne]La valeur de la première ligne pour cette colonne
Table{[Item = "Ventes", Kind = "Sheet"]}La ligne qui correspond aux valeurs indiquées (utilisé par l'étape Navigation)

Exemple : remplacer dans une colonne la valeur de la première ligne, quelle qu'elle soit, au lieu d'un texte fixe :

= Table.ReplaceValue(#"Type modifié", #"Type modifié"{0}[Colonne 1], "test", Replacer.ReplaceValue, {"Colonne 1"})

Table.Max(Table, "Colonne") renvoie la ligne qui a la valeur maximale ; Table.Max(TypeModifie, "Colonne1")[Colonne1] en extrait la valeur.

Opérateurs

image.png
  • Arithmétiques : +, -, *, / ; comparaison : =, <>, <, <=, >, >= ; logiques : and, or, not.
  • & concatène deux textes, deux listes, deux enregistrements ou deux tables.
  • ?? renvoie la valeur de droite si celle de gauche est null : [Remise] ?? 0.
  • + ne concatène pas du texte : "A" + "B" provoque une erreur, "A" & "B" renvoie « AB ». Source

Gestion des erreurs

try Number.From([Montant]) otherwise 0           // 0 si la conversion échoue
try [Montant]                                    // enregistrement HasError, Value ou Error
error "Code client manquant"                     // déclenche une erreur personnalisée

try renvoie un enregistrement : HasError vaut true en cas d'erreur, et le champ Error décrit l'erreur (Reason, Message, Detail). Source

Exemple

Table de test à coller dans une requête vide : quatre colonnes mêlant nombres, textes et null, puis typées en nombre entier. Les cellules non convertibles deviennent des erreurs de cellule, à traiter avec les techniques de la page « Profiler et nettoyer les données ».

let
    Source = Table.FromColumns({
        {123, 34, 12, "txt", null},
        {123, "txt", 34, 12, null},
        {"txt", 123, 34, 12, null},
        {123, "txt", "34", 12, null}
    }),
    TypeModifie = Table.TransformColumnTypes(Source, {
        {"Column1", Int64.Type}, {"Column2", Int64.Type},
        {"Column3", Int64.Type}, {"Column4", Int64.Type}
    }),
    SansErreurs = Table.ReplaceErrorValues(TypeModifie, {
        {"Column1", null}, {"Column2", null}, {"Column3", null}, {"Column4", null}
    })
in
    SansErreurs

Observez l'étape TypeModifie : chaque « txt » devient Error, alors que le texte « 34 » de Column4 est converti en nombre. L'étape SansErreurs remplace les erreurs par null.

[Capture : aperçu de l'étape TypeModifie, cellules Error dans les quatre colonnes]

Pièges et bonnes pratiques

  • Les positions commencent à 0 : Table{0} est la première ligne.
  • Table{0}[Colonne] dépend de l'ordre des lignes : triez ou filtrez avant de lire une valeur par sa position.
  • Préférez try ... otherwise à la suppression des erreurs quand une valeur de repli a un sens métier.

À retenir

  • Trois valeurs structurées : listes {}, enregistrements [], tables.
  • Table[Colonne] donne une liste, Table{n} une ligne, Table{n}[Colonne] une valeur.
  • & concatène, ?? remplace un null.
  • try ... otherwise fournit une valeur de repli, error déclenche une erreur.

Pour aller plus loin

  • Spécification : valeurs. Source
  • Spécification : opérateurs. Source
  • Spécification : gestion des erreurs. Source
  • Expressions, valeurs et expression let. Source