Partager via


Présentation

Aperçu

Microsoft Power Query offre une expérience puissante « obtenir des données » qui englobe de nombreuses fonctionnalités. Une fonctionnalité principale de Power Query consiste à filtrer et à combiner, autrement dit, des données « mash-up » à partir d’une ou plusieurs d’une collection enrichie de sources de données prises en charge. Tout mashup de données de ce type est exprimé à l’aide du langage de formule Power Query (informellement appelé « M »). Power Query incorpore des documents M dans un large éventail de produits Microsoft, notamment Excel, Power BI, Analysis Services et Dataverse, pour permettre une mashup reproductible de données.

Ce document fournit la spécification de M. Après une brève introduction qui vise à créer une première intuition et une connaissance de la langue, le document couvre précisément la langue en plusieurs étapes progressives :

  1. La structure lexicale définit l’ensemble de textes qui sont lexicalement valides.

  2. Les valeurs, les expressions, les environnements et les variables, les identificateurs et le modèle d’évaluation forment les concepts de base du langage.

  3. La spécification détaillée des valeurs, primitives et structurées, définit le domaine cible du langage.

  4. Les valeurs ont des types, eux-mêmes un type spécial de valeur, qui caractérisent les types fondamentaux de valeurs et portent des métadonnées supplémentaires spécifiques aux formes de valeurs structurées.

  5. L’ensemble d’opérateurs dans M définit les types d’expressions qui peuvent être formés.

  6. Functions, un autre type de valeurs spéciales, fournit la base d’une bibliothèque standard riche pour M et permet l’ajout de nouvelles abstractions.

  7. Des erreurs peuvent se produire lors de l’application d’opérateurs ou de fonctions pendant l’évaluation des expressions. Bien que les erreurs ne soient pas des valeurs, il existe des façons de gérer les erreurs qui mappent les erreurs aux valeurs.

  8. Laissez les expressions autoriser l’introduction de définitions auxiliaires utilisées pour créer des expressions complexes en plus petites étapes.

  9. Si les expressions prennent en charge l’évaluation conditionnelle.

  10. Les sections fournissent un mécanisme de modularité simple. (Les sections ne sont pas encore exploitées par Power Query.)

  11. Enfin, une grammaire consolidée collecte les fragments de grammaire de toutes les autres sections de ce document en une seule définition complète.

Pour les théoriciens du langage informatique : le langage de formule spécifié dans ce document est un langage fonctionnel partiellement paresseux, à ordre plus pur, de type plus élevé, partiellement différé.

Expressions et valeurs

La construction centrale dans M est l’expression. Une expression peut être évaluée (calculée), ce qui génère une valeur unique.

Bien que de nombreuses valeurs puissent être écrites littéralement en tant qu’expression, une valeur n’est pas une expression. Par exemple, l’expression 1 prend la valeur 1 ; les expressions 1+1 sont évaluées à la valeur 2. Cette distinction est subtile, mais importante. Les expressions sont des recettes pour l’évaluation ; les valeurs sont les résultats de l’évaluation.

Les exemples suivants illustrent les différents types de valeurs disponibles dans M. En tant que convention, une valeur est écrite à l’aide de la forme littérale dans laquelle elles apparaissent dans une expression qui prend la valeur. (Notez que le // début d’un commentaire qui continue à la fin de la ligne.)

  • Une valeur primitive est une valeur en une seule partie, telle qu’un nombre, un texte logique ou null. Une valeur Null peut être utilisée pour indiquer l’absence de données.

    123                  // A number
    true                 // A logical
    "abc"                // A text
    null                 // null value
    
  • Une valeur de liste est une séquence ordonnée de valeurs. M prend en charge les listes infinies, mais s’il est écrit en tant que littéral, les listes ont une longueur fixe. Les accolades et {} indiquent le début et la fin d’une liste.

    {123, true, "A"}     // list containing a number, a logical, and 
                          //     a text 
    {1, 2, 3}            // list of three numbers 
    
  • Un enregistrement est un ensemble de champs. Un champ est une paire nom/valeur où le nom est une valeur de texte unique dans l’enregistrement du champ. La syntaxe littérale des valeurs d’enregistrement permet aux noms d’être écrits sans guillemets, un formulaire également appelé identificateurs. L’enregistrement suivant montre un enregistrement contenant trois champs nommés «A », «B » et «C », qui ont des valeurs 1, 2et 3.

    [ 
          A = 1,  
          B = 2,  
          C = 3 
    ]
    
  • Une table est un ensemble de valeurs organisées en colonnes (identifiées par nom) et des lignes. Il n’existe aucune syntaxe littérale pour créer une table, mais il existe plusieurs fonctions standard qui peuvent être utilisées pour créer des tables à partir de listes ou d’enregistrements.

    Par exemple:

    #table( {"A", "B"}, { {1, 2}, {3, 4} } ) 
    

    Cela crée une table de la forme suivante :

    Image d’un exemple de tableau dans le langage de formule M.

  • Une fonction est une valeur qui, lorsqu’elle est appelée avec des arguments, produit une nouvelle valeur. Une fonction est écrite en répertoriant les paramètres de la fonction entre parenthèses, suivie du symbole =>de passe, suivie de l’expression définissant la fonction. Cette expression fait généralement référence aux paramètres (par nom).

    (x, y) => (x + y) / 2`
    

Evaluation

Le modèle d’évaluation du langage M est modélisé après le modèle d’évaluation couramment trouvé dans les feuilles de calcul, où l’ordre de calcul peut être déterminé en fonction des dépendances entre les formules des cellules.

Si vous avez écrit des formules dans une feuille de calcul telle qu’Excel, vous pouvez reconnaître les formules situées à gauche et générer les valeurs à droite lorsqu’elles sont calculées :

Captures d’écran des formules situées à droite, ce qui entraîne les valeurs à gauche.

Dans M, les parties d’une expression peuvent référencer d’autres parties de l’expression par nom, et le processus d’évaluation détermine automatiquement l’ordre dans lequel les expressions référencées sont calculées.

Vous pouvez utiliser un enregistrement pour produire une expression équivalente à l’exemple de feuille de calcul précédent. Lors de l’initialisation de la valeur d’un champ, vous pouvez faire référence à d’autres champs dans l’enregistrement à l’aide du nom du champ, comme illustré dans l’exemple suivant :

[  
    A1 = A2 * 2,  
    A2 = A3 + 1,  
    A3 = 1  
]

L’expression précédente équivaut à l’exemple suivant (dans lequel les deux sont évaluées à des valeurs égales) :

[  
    A1 = 4,  
    A2 = 2,  
    A3 = 1  
]

Les enregistrements peuvent être contenus dans, ou imbriquer, dans d’autres enregistrements. Vous pouvez utiliser l’opérateur de recherche ([]) pour accéder aux champs d’un enregistrement par nom. Par exemple, l’enregistrement suivant a un champ nommé Sales contenant un enregistrement et un champ nommé Total qui accède aux champs et FirstHalf aux SecondHalf champs de l’enregistrement Sales :

[  
    Sales = [ FirstHalf = 1000, SecondHalf = 1100 ], 
    Total = Sales[FirstHalf] + Sales[SecondHalf] 
]

L’expression précédente équivaut à l’exemple suivant lorsqu’elle est évaluée :

[  
    Sales = [ FirstHalf = 1000, SecondHalf = 1100 ], 
    Total = 2100 
]

Les enregistrements peuvent également être contenus dans des listes. Vous pouvez utiliser l’opérateur d’index positionnel ({}) pour accéder à un élément d’une liste par son index numérique. Les valeurs d’une liste sont référencées à l’aide d’un index de base zéro à partir du début de la liste. Par exemple, les index 0 et 1 sont utilisés pour référencer les premiers et deuxième éléments de la liste suivante :

[ 
    Sales =  
        {  
            [  
                Year = 2007,  
                FirstHalf = 1000,  
                SecondHalf = 1100, 
                Total = FirstHalf + SecondHalf // 2100 
            ], 
            [  
                Year = 2008,  
                FirstHalf = 1200,  
                SecondHalf = 1300, 
                Total = FirstHalf + SecondHalf // 2500 
            ]  
        }, 
    TotalSales = Sales{0}[Total] + Sales{1}[Total] // 4600 
]

Les expressions membres de liste et d’enregistrement (ainsi que les expressions let) sont évaluées à l’aide d’une évaluation différée, ce qui signifie qu’elles sont évaluées uniquement si nécessaire. Toutes les autres expressions sont évaluées à l’aide d’une évaluation impatiente, ce qui signifie qu’elles sont évaluées immédiatement lorsqu’elles sont rencontrées pendant le processus d’évaluation. Une bonne façon de réfléchir à cela consiste à se rappeler que l’évaluation d’une expression de liste ou d’enregistrement retourne une valeur de liste ou d’enregistrement qui se souvient de la façon dont ses éléments de liste ou ses champs d’enregistrement doivent être calculés, quand ils sont demandés (par des opérateurs de recherche ou d’index).

Functions

Dans M, une fonction est un mappage d’un ensemble de valeurs d’entrée à une valeur de sortie unique. Une fonction est écrite en nommant d’abord l’ensemble requis de valeurs d’entrée (les paramètres de la fonction), puis en fournissant une expression qui calcule le résultat de la fonction à l’aide de ces valeurs d’entrée (le corps de la fonction) en suivant le symbole de passe à (=>). Par exemple:

(x) => x + 1                    // function that adds one to a value 
(x, y) =>  x + y                // function that adds two values

Une fonction est une valeur comme un nombre ou une valeur de texte. L’exemple suivant montre une fonction qui est la valeur d’un champ Add, qui est ensuite appelé ou exécuté, à partir de plusieurs autres champs. Lorsqu’une fonction est appelée, un ensemble de valeurs est spécifié qui sont logiquement substituées au jeu requis de valeurs d’entrée dans l’expression du corps de la fonction.

[ 
    Add = (x, y) => x + y,
    OnePlusOne = Add(1, 1),     // 2 
    OnePlusTwo = Add(1, 2)      // 3
]

Bibliothèque

M inclut un ensemble commun de définitions disponibles pour une utilisation à partir d’une expression appelée bibliothèque standard, ou simplement une bibliothèque pour un court terme. Ces définitions se composent d’un ensemble de valeurs nommées. Les noms des valeurs fournies par une bibliothèque sont disponibles pour une utilisation dans une expression sans avoir été définis explicitement par l’expression. Par exemple:

Number.E                        // Euler's number e (2.7182...) 
Text.PositionOf("Hello", "ll")  // 2

Opérateurs

M inclut un ensemble d’opérateurs qui peuvent être utilisés dans les expressions. Les opérateurs sont appliqués aux opérandes pour former des expressions symboliques . Par exemple, dans l’expression 1 + 2 , les nombres 1 et 2 sont des opérandes et l’opérateur est l’opérateur d’addition (+).

La signification d’un opérateur peut varier en fonction du type de valeurs que sont ses opérandes. Par exemple, l’opérateur plus peut être utilisé avec d’autres types de valeurs en plus des nombres :

1 + 2                   // numeric addition: 3 
#time(12,23,0) + #duration(0,0,2,0) 
                        // time arithmetic: #time(12,25,0)

Un autre exemple d’opérateur avec un opérande dépendant de la signification est l’opérateur combiné () :&

"A" & "BC"              // text concatenation: "ABC" 
{1} & {2, 3}            // list concatenation: {1, 2, 3} 
[ a = 1 ] & [ b = 2 ]   // record merge: [ a = 1, b = 2 ]

Notez que certains opérateurs ne prennent pas en charge toutes les combinaisons de valeurs. Par exemple:

1 + "2"  // error: adding number and text isn't supported

Les expressions qui, lorsqu’elles sont évaluées, rencontrent des conditions d’opérateur non définies sont évaluées à des erreurs.

Métadonnées

Les métadonnées sont des informations sur une valeur associée à une valeur. Les métadonnées sont représentées sous forme de valeur d’enregistrement, appelée enregistrement de métadonnées. Les champs d’un enregistrement de métadonnées peuvent être utilisés pour stocker les métadonnées d’une valeur.

Chaque valeur a un enregistrement de métadonnées. Si la valeur de l’enregistrement de métadonnées n’a pas été spécifiée, l’enregistrement de métadonnées est vide (n’a aucun champ).

Les enregistrements de métadonnées fournissent un moyen d’associer des informations supplémentaires à n’importe quel type de valeur de manière discrète. L’association d’un enregistrement de métadonnées à une valeur ne modifie pas la valeur ou son comportement.

Une valeur y d’enregistrement de métadonnées est associée à une valeur x existante à l’aide de la syntaxe x meta y. Par exemple, le code suivant associe un enregistrement de métadonnées et RatingTags des champs à la valeur "Mozart"de texte :

"Mozart" meta [ Rating = 5, Tags = {"Classical"} ]

Pour les valeurs qui contiennent déjà un enregistrement de métadonnées non vide, le résultat de l’application du méta est celui de l’informatique de la fusion d’enregistrements de l’enregistrement existant et du nouvel enregistrement de métadonnées. Par exemple, les deux expressions suivantes sont équivalentes les unes aux autres et à l’expression précédente :

("Mozart" meta [ Rating = 5 ]) meta [ Tags = {"Classical"} ] 
"Mozart" meta ([ Rating = 5 ] & [ Tags = {"Classical"} ])

Un enregistrement de métadonnées est accessible pour une valeur donnée à l’aide de la Value.Metadata fonction. Dans l’exemple suivant, l’expression du ComposerRating champ accède à l’enregistrement de métadonnées de la valeur du Composer champ, puis accède au Rating champ de l’enregistrement de métadonnées.

[ 
    Composer = "Mozart" meta [ Rating = 5, Tags = {"Classical"} ], 
    ComposerRating = Value.Metadata(Composer)[Rating] // 5
]

Let expression

De nombreux exemples présentés jusqu’à présent ont inclus toutes les valeurs littérales de l’expression dans le résultat de l’expression. L’expression let permet à un ensemble de valeurs d’être calculées, affectées, puis utilisées dans une expression suivante qui précède le in. Par exemple, dans notre exemple de données de vente, vous pouvez effectuer les activités suivantes :

let 
    Sales2007 =  
        [  
            Year = 2007,  
            FirstHalf = 1000,  
            SecondHalf = 1100, 
            Total = FirstHalf + SecondHalf // 2100 
        ], 
    Sales2008 =  
        [  
            Year = 2008,  
            FirstHalf = 1200,  
            SecondHalf = 1300, 
            Total = FirstHalf + SecondHalf // 2500 
        ],
    TotalSales = Sales2007[Total] + Sales2008[Total]
in
    TotalSales  // 4600

Le résultat de l’expression ci-dessus est une valeur numérique (4600) calculée à partir des valeurs liées aux noms Sales2007 et Sales2008.

Si l’expression

L’expression if sélectionne entre deux expressions en fonction d’une condition logique. Par exemple:

if 2 > 1 then
    2 + 2
else  
    1 + 1

La première expression (2 + 2) est sélectionnée si l’expression logique (2 > 1) a la valeur true, et la deuxième expression (1 + 1) est sélectionnée si elle est false. L’expression sélectionnée (dans ce cas 2 + 2) est évaluée et devient le résultat de l’expression if (4).

Errors

Une erreur indique que le processus d’évaluation d’une expression n’a pas pu produire de valeur.

Les erreurs sont générées par les opérateurs et les fonctions qui rencontrent des conditions d’erreur ou à l’aide de l’expression d’erreur. Les erreurs sont gérées à l’aide de l’expression try . Lorsqu’une erreur est générée, une valeur est spécifiée qui peut être utilisée pour indiquer pourquoi l’erreur s’est produite.

let Sales = 
    [ 
        Revenue = 2000, 
        Units = 1000, 
        UnitPrice = if Units = 0 then error "No Units"
                    else Revenue / Units 
    ], 
    UnitPrice = try Number.ToText(Sales[UnitPrice]),
    Result = "Unit Price: " & 
        (if UnitPrice[HasError] then UnitPrice[Error][Message]
        else UnitPrice[Value])
in
    Result

L’exemple ci-dessus accède au Sales[UnitPrice] champ et met en forme la valeur produisant le résultat :

"Unit Price: 2"

Si le Units champ avait été égal à zéro, le UnitPrice champ aurait déclenché une erreur, qui aurait été gérée par le try. La valeur résultante aurait alors été :

"Unit Price: No Units"

Une try expression convertit les valeurs et les erreurs appropriées en valeur d’enregistrement qui indique si l’expression try a géré une erreur, ou non, et la valeur appropriée ou l’enregistrement d’erreur qu’elle a extrait lors de la gestion de l’erreur. Par exemple, considérez l’expression suivante qui déclenche une erreur, puis la gère immédiatement :

try error "negative unit count"

Cette expression prend la valeur d’enregistrement imbriquée suivante, expliquant les recherches sur les champs [HasError]et [Error] les [Message]champs dans l’exemple précédent de prix unitaire.

[ 
    HasError = true, 
    Error = 
        [ 
            Reason = "Expression.Error", 
            Message = "negative unit count", 
            Detail = null 
        ] 
]

Un cas courant consiste à remplacer les erreurs par des valeurs par défaut. L’expression try peut être utilisée avec une clause facultative otherwise pour obtenir uniquement cela sous forme compacte :

try error "negative unit count" otherwise 42 
// 42