IntroduzioneIntroduction

PanoramicaOverview

Microsoft Power Query offre una potente esperienza di acquisizione dei dati che comprende molte funzionalità.Microsoft Power Query provides a powerful "get data" experience that encompasses many features. Una funzionalità chiave di Power Query è la possibilità di filtrare e combinare, ovvero di eseguire il mashup dei dati da una o più raccolte di origini dati supportate.A core capability of Power Query is to filter and combine, that is, to "mash-up" data from one or more of a rich collection of supported data sources. Qualsiasi mashup di dati di questo tipo viene espresso usando il linguaggio delle formule M di Power Query (noto in modo informale come "M").Any such data mashup is expressed using the Power Query Formula Language (informally known as "M"). Power Query incorpora documenti M in Excel e cartelle di lavoro di Power BI per consentire il mashup ripetibile di dati.Power Query embeds M documents in Excel and Power BI workbooks to enable repeatable mashup of data.

In questo documento viene illustrata la specifica relativa al linguaggio M. Dopo una breve introduzione volta a creare una certa familiarità con il linguaggio, il documento presenta il linguaggio in modo più accurato attraverso vari passaggi progressivi:This document provides the specification for M. After a brief introduction that aims at building some first intuition and familiarity with the language, the document covers the language precisely in several progressive steps:

  1. La struttura lessicale definisce il set di testi lessicalmente validi.The lexical structure defines the set of texts that are lexically valid.

  2. I valori, le espressioni, gli ambienti e le variabili, gli identificatori e il modello di valutazione formano i concetti di base del linguaggio.Values, expressions, environments and variables, identifiers, and the evaluation model form the language's basic concepts.

  3. La specifica dettagliata dei valori, sia primitivi che strutturati, definisce il dominio di destinazione del linguaggio.The detailed specification of values, both primitive and structured, defines the target domain of the language.

  4. I valori si differenziano in base al tipo (a sua volta, un tipo speciale di valore), che caratterizza i principali tipi di valori e contiene metadati aggiuntivi specifici delle forme dei valori strutturati.Values have types, themselves a special kind of value, that both characterize the fundamental kinds of values and carry additional metadata that is specific to the shapes of structured values.

  5. Il set di operatori di M definisce quali tipi di espressioni è possibile formare.The set of operators in M defines what kinds of expressions can be formed.

  6. Le funzioni, un altro tipo di valori speciali, forniscono la base per un'ampia libreria standard per M e consentono l'aggiunta di nuove astrazioni.Functions, another kind of special values, provide the foundation for a rich standard library for M and allow for the addition of new abstractions.

  7. È possibile che si verifichino errori quando si applicano operatori o funzioni durante la valutazione di un'espressione.Errors can occur when applying operators or functions during expression evaluation. Sebbene gli errori non siano valori, esistono metodi di gestione degli errori che eseguono il mapping inverso: dagli errori ai valori.While errors are not values, there are ways to handle errors that map errors back to values.

  8. Le espressioni let consentono l'introduzione di definizioni ausiliarie utili per creare espressioni complesse in passaggi più brevi.Let expressions allow for the introduction of auxiliary definitions used to build up complex expressions in smaller steps.

  9. Le espressioni if supportano la valutazione condizionale.If expressions support conditional evaluation.

  10. Le sezioni forniscono un semplice meccanismo di modularitàSections provide a simple modularity mechanism. (le sezioni non vengono ancora usate da Power Query).(Sections are not yet leveraged by Power Query.)

  11. Una grammatica consolidata raccoglie infine i frammenti di grammatica da tutte le altre sezioni di questo documento in un'unica definizione completa.Finally, a consolidated grammar collects the grammar fragments from all other sections of this document into a single complete definition.

Per i teorici dei linguaggi informatici: il linguaggio delle formule usato in questo documento è un linguaggio funzionale essenzialmente puro, di ordine superiore, tipizzato in modo dinamico e parzialmente "lazy".For computer language theorists: the formula language specified in this document is a mostly pure, higher-order, dynamically typed, partially lazy functional language.

Espressioni e valoriExpressions and values

Il costrutto centrale in M è l 'espressione.The central construct in M is the expression. Un'espressione può essere valutata (calcolata), restituendo un singolo valore.An expression can be evaluated (computed), yielding a single value.

Sebbene molti valori possano essere scritti letteralmente come espressione, un valore non è un'espressione.Although many values can be written literally as an expression, a value is not an expression. Ad esempio, l'espressione 1 restituisce il valore 1, mentre l'espressione 1+1 restituisce il valore 2.For example, the expression 1 evaluates to the value 1; the expressions 1+1 evaluates to the value 2. La distinzione è sottile, ma importante.This distinction is subtle, but important. Le espressioni sono ricette per la valutazione, mentre i valori sono i risultati della valutazione.Expressions are recipes for evaluation; values are the results of evaluation.

Negli esempi seguenti vengono illustrati i diversi tipi di valori disponibili in M. Per convenzione, un valore viene scritto usando il formato letterale in cui verrebbe visualizzato in un'espressione che restituisce solo quel valore.The following examples illustrate the different kinds of values available in M. As a convention, a value is written using the literal form in which they would appear in an expression that evaluates to just that value. Osservare che // indica l'inizio di un commento che continua fino alla fine della riga.(Note that the // indicates the start of a comment which continues to the end of the line.)

  • Un valore primitivo è un valore in una sola parte, ad esempio un valore number, logical, text o null.A primitive value is single-part value, such as a number, logical, text, or null. È possibile usare un valore Null per indicare l'assenza di dati.A null value can be used to indicate the absence of any data.

    123                  // A number
    true                 // A logical
    "abc"                // A text
    null                 // null value
    
  • Un valore elenco è una sequenza ordinata di valori.A list value is an ordered sequence of values. M supporta elenchi infiniti, ma se vengono scritti come valori letterali, gli elenchi hanno una lunghezza fissa.M supports infinite lists, but if written as a literal, lists have a fixed length. I caratteri parentesi graffe { e } indicano l'inizio e la fine di un elenco.The curly brace characters { and } denote the beginning and end of a list.

    {123, true, "A"}     // list containing a number, a logical, and 
                          //     a text 
    {1, 2, 3}            // list of three numbers 
    
  • Un record è un set di campi.A record is a set of fields. Un campo è una coppia nome/valore in cui il nome è un valore di testo univoco all'interno del record del campo.A field is a name/value pair where the name is a text value that is unique within the field's record. La sintassi letterale per i valori dei record consente di scrivere i nomi senza virgolette, con un formato noto anche come identificatori.The literal syntax for record values allows the names to be written without quotes, a form also referred to as identifiers. Di seguito viene illustrato un record contenente tre campi denominati "A", "B" e "C", a cui sono associati i valori 1, 2 e 3.The following shows a record containing three fields named "A", "B", and "C", which have values 1, 2, and 3.

    [ 
          A = 1,  
          B = 2,  
          C = 3 
    ]
    
  • Una tabella è un set di valori organizzati in colonne (identificate per nome) e righe.A table is a set of values organized into columns (which are identified by name), and rows. Non esiste una sintassi letterale per la creazione di una tabella, ma sono disponibili varie funzioni standard per la creazione di tabelle da elenchi o record.There is no literal syntax for creating a table, but there are several standard functions that can be used to create tables from lists or records.

    Ad esempio:For example:

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

    Viene creata una tabella con la forma seguente:This creates a table of the following shape:

    Tabella di esempio nel linguaggio delle formule M

  • Una funzione è un valore che, se richiamato con argomenti, produce un nuovo valore.A function is a value which, when invoked with arguments, produces a new value. Le funzioni vengono scritte elencando i parametri della funzione tra parentesi, seguiti dal simbolo vai-a =>, seguito dall'espressione che definisce la funzione.Function are written by listing the function's parameters in parentheses, followed by the goes-to symbol =>, followed by the expression defining the function. L'espressione si riferisce in genere ai parametri (per nome).That expression typically refers to the parameters (by name).

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

ValutazioneEvaluation

Il modello di valutazione del linguaggio M è progettato sulla base del modello di valutazione comunemente presente nei fogli di calcolo, in cui l'ordine dei calcoli può essere determinato in base alle dipendenze tra le formule nelle celle.The evaluation model of the M language is modeled after the evaluation model commonly found in spreadsheets, where the order of calculation can be determined based on dependencies between the formulas in the cells.

Se sono state scritte formule in un foglio di calcolo, ad esempio Excel, è possibile riconoscere le formule a sinistra che dopo il calcolo consentiranno di ottenere i valori a destra:If you have written formulas in a spreadsheet such as Excel, you may recognize the formulas on the left will result in the values on the right when calculated:

Formula che restituisce un valore

In M, parti di un'espressione possono fare riferimento ad altre parti dell'espressione in base al nome e il processo di valutazione determina automaticamente l'ordine di calcolo delle espressioni a cui si fa riferimento.In M, parts of an expression can reference other parts of the expression by name, and the evaluation process will automatically determine the order in which referenced expressions are calculated.

È possibile usare un record per produrre un'espressione equivalente all'esempio del foglio di calcolo precedente.We can use a record to produce an expression which is equivalent to the above spreadsheet example. Quando si inizializza il valore di un campo, è possibile fare riferimento ad altri campi all'interno del record usando il nome del campo, come indicato di seguito:When initializing the value of a field, we can refer to other fields within the record by using the name of the field, as follows:

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

L'espressione precedente è equivalente alla seguente (in quanto entrambe restituiscono valori uguali):The above expression is equivalent to the following (in that both evaluate to equal values):

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

I record possono essere contenuti, ovvero annidati, in altri record.Records can be contained within, or nest, within other records. È possibile usare l'operatore di ricerca ([]) per accedere ai campi di un record in base al nome.We can use the lookup operator ([]) to access the fields of a record by name. Il record seguente, ad esempio, include un campo denominato Sales contenente un record e un campo denominato Total che accede ai campi FirstHalf e SecondHalf del record Sales:For example, the following record has a field named Sales containing a record, and a field named Total that accesses the FirstHalf and SecondHalf fields of the Sales record:

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

Quando viene valutata, l'espressione precedente è equivalente alla seguente: The above expression is equivalent to the following when it is evaluated: \

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

I record possono essere contenuti anche all'interno di elenchi.Records can also be contained within lists. Per accedere a un elemento di un elenco in base al relativo indice numerico, è possibile usare l'operatore di indice posizionale ({}).We can use the positional index operator ({}) to access an item in a list by its numeric index. Ai valori all'interno di un elenco viene fatto riferimento usando un indice in base zero dall'inizio dell'elenco.The values within a list are referred to using a zero-based index from the beginning of the list. Ad esempio, gli indici 0 e 1 vengono usati per fare riferimento al primo e al secondo elemento nell'elenco seguente:For example, the indexes 0 and 1 are used to reference the first and second items in the list below:

[ 
    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 
]

Per le espressioni di membro elenco e record (nonché per le espressioni let, illustrate più avanti), viene usata la valutazione lazy, ovvero vengono valutate all'occorrenza.List and record member expressions (as well as let expressions, introduced further below) are evaluated using lazy evaluation, which means that they are evaluated only as needed. Per tutte le altre espressioni viene usata invece la valutazione eager, ovvero vengono valutate immediatamente quando vengono rilevate durante il processo di valutazione.All other expressions are evaluated using eager evaluation, which means that they are evaluated immediately, when encountered during the evaluation process. Un modo efficace per tenere conto di questa differenza consiste nel ricordare che la valutazione di un'espressione elenco o record restituirà un valore di elenco o record che ricorda come devono essere calcolati gli elementi dell'elenco o i campi del record, quando richiesto (dagli operatori di ricerca o di indice).A good way to think about this is to remember that evaluating a list or record expression will return a list or record value that itself remembers how its list items or record fields need to be computed, when requested (by lookup or index operators).

FunzioniFunctions

In M, una funzione è un mapping da un set di valori di input a un singolo valore di output.In M, a function is a mapping from a set of input values to a single output value. Una funzione viene scritta specificando prima il set obbligatorio di valori di input (i parametri della funzione) e quindi un'espressione che consenta di calcolare il risultato della funzione usando i valori di input che seguono il simbolo vai a (=>).A function is written by first naming the required set of input values (the parameters to the function) and then providing an expression that will compute the result of the function using those input values (the body of the function) following the goes-to (=>) symbol. Ad esempio:For example:

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

Una funzione è un valore esattamente come un numero o un valore di testo.A function is a value just like a number or a text value. Nell'esempio seguente viene illustrata una funzione che corrisponde al valore di un campo Add che viene quindi richiamata, o eseguita, da vari altri campi.The following example shows a function which is the value of an Add field which is then invoked, or executed, from several other fields. Quando viene richiamata una funzione, viene specificato un set di valori che vengono sostituiti in modo logico per il set di valori di input obbligatorio nell'espressione del corpo della funzione.When a function is invoked, a set of values are specified which are logically substituted for the required set of input values within the function body expression.

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

LibreriaLibrary

M include un set comune di definizioni che è possibile usare nelle espressioni denominato libreria standard o, più semplicemente, libreria.M includes a common set of definitions available for use from an expression called the standard library, or just library for short. Queste definizioni sono costituite da un set di valori denominati.These definitions consist of a set of named values. I nomi dei valori forniti da una libreria possono essere usati in un'espressione anche se non sono stati definiti in modo esplicito dall'espressione.The names of values provided by a library are available for use within an expression without having been defined explicitly by the expression. Ad esempio:For example:

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

OperatoriOperators

M include un set di operatori che possono essere usati nelle espressioni.M includes a set of operators that can be used in expressions. Gli operatori vengono applicati agli operandi per formare espressioni simboliche.Operators are applied to operands to form symbolic expressions. Ad esempio, nell'espressione 1 + 2 i numeri 1 e 2 sono operandi e l'operatore è l'operatore di addizione (+).For example, in the expression 1 + 2 the numbers 1 and 2 are operands and the operator is the addition operator (+).

Il significato di un operatore può variare a seconda del tipo di valori degli operandi.The meaning of an operator can vary depending on what kind of values its operands are. L'operatore di addizione, ad esempio, può essere usato anche con tipi di valori diversi dai numeri:For example, the plus operator can be used with other kinds of values than numbers:

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

Un altro esempio di operatore con significato diverso a seconda dell'operando è l'operatore di combinazione (&):Another example of an operator with operand-depending meaning is the combination operator (&):

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

Non tutte le combinazioni di valori possono essere supportate da un operatore.Note that not all combinations of values may be supported by an operator. Ad esempio:For example:

1 + "2"  // error: adding number and text is not supported

Le espressioni che, quando valutate, riscontrano condizioni di operatore non definite restituiscono errori.Expressions that, when evaluated, encounter undefined operator conditions evaluate to errors. Altre informazioni sugli errori in M verranno fornite nelle sezioni seguenti.More on errors in M later.

MetadatiMetadata

I metadati sono informazioni su un valore associato a un valore.Metadata is information about a value that is associated with a value. I metadati sono rappresentati come un valore di record, denominato record di metadati.Metadata is represented as a record value, called a metadata record. I campi di un record di metadati possono essere usati per archiviare i metadati per un valore.The fields of a metadata record can be used to store the metadata for a value.

Ogni valore ha un record di metadati.Every value has a metadata record. Se il valore del record dei metadati non è stato specificato, il record dei metadati è vuoto (privo di campi).If the value of the metadata record has not been specified, then the metadata record is empty (has no fields).

I record di metadati consentono di associare informazioni aggiuntive a qualsiasi tipo di valore in modo non intrusivo.Metadata records provide a way to associate additional information with any kind of value in an unobtrusive way. L'associazione di un record di metadati a un valore non comporta la modifica del valore o del relativo comportamento.Associating a metadata record with a value does not change the value or its behavior.

Un valore di record di metadati y viene associato a un valore esistente x usando la sintassi x meta y.A metadata record value y is associated with an existing value x using the syntax x meta y. Il codice seguente, ad esempio, associa un record di metadati con i campi Rating e Tags al valore di testo "Mozart":For example, the following associates a metadata record with Rating and Tags fields with the text value "Mozart":

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

Per i valori che contengono già un record di metadati non vuoto, l'applicazione di metadati ha come risultato quello di calcolare l'unione del record di metadati esistente con quello nuovo.For values that already carry a non-empty metadata record, the result of applying meta is that of computing the record merge of the existing and the new metadata record. Le due espressioni seguenti, ad esempio, sono equivalenti sia l'una all'altra sia all'espressione precedente:For example, the following two expressions are equivalent to each other and to the previous expression:

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

È possibile accedere a un record di metadati per un valore usando la funzione Value.Metadata.A metadata record can be accessed for a given value using the Value.Metadata function. Nell'esempio seguente l'espressione nel campo ComposerRating accede al record di metadati del valore nel campo Composer e quindi accede al campo Rating del record di metadati.In the following example, the expression in the ComposerRating field accesses the metadata record of the value in the Composer field, and then accesses the Rating field of the metadata record.

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

Espressione letLet expression

Nella maggior parte degli esempi illustrati finora, nel risultato dell'espressione erano inclusi tutti i valori letterali dell'espressione.Many of the examples shown so far have included all the literal values of the expression in the result of the expression. L'espressione let include un set di valori da calcolare, a cui assegnare nomi e da usare in un'espressione successiva che segue l'istruzione in.The let expression allows a set of values to be computed, assigned names, and then used in a subsequent expression that follows the in. Nell'esempio dei dati sulle vendite, è possibile procedere come segue:For example, in our sales data example, we could do:

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

Il risultato dell'espressione precedente è un valore numerico (4600) calcolato a partire dai valori associati ai nomi Sales2007 e Sales2008.The result of the above expression is a number value (4600) which was computed from the values bound to the names Sales2007 and Sales2008.

Espressione ifIf expression

L'espressione if effettua una selezione tra due espressioni in base a una condizione logica.The if expression selects between two expressions based on a logical condition. Ad esempio:For example:

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

La prima espressione (2 + 2) viene selezionata se l'espressione logica (2 > 1) è true e la seconda espressione (1 + 1) viene selezionata se è false.The first expression (2 + 2) is selected if the logical expression (2 > 1) is true, and the second expression (1 + 1) is selected if it is false. L'espressione selezionata (in questo caso 2 + 2) viene valutata e diventa il risultato dell'espressione if (4).The selected expression (in this case 2 + 2) is evaluated and becomes the result of the if expression (4).

ErrorsErrors

Un errore indica che il processo di valutazione di un'espressione non è stato in grado di produrre un valore.An error is an indication that the process of evaluating an expression could not produce a value.

Gli errori vengono generati dagli operatori e dalle funzioni che riscontrano condizioni di errore o tramite l'espressione error.Errors are raised by operators and functions encountering error conditions or by using the error expression. Gli errori vengono gestiti con l'espressione try.Errors are handled using the try expression. Quando viene generato un errore, viene specificato un valore che può essere usato per indicare il motivo per cui si è verificato l'errore.When an error is raised, a value is specified that can be used to indicate why the error occurred.

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

L'esempio precedente accede al campo Sales[UnitPrice] e formatta il valore producendo il risultato:The above example accesses the Sales[UnitPrice] field and formats the value producing the result:

"Unit Price: 2"

Se il campo Units fosse stato zero, il campo UnitPrice avrebbe generato un errore che sarebbe stato gestito dall'espressione try.If the Units field had been zero, then the UnitPrice field would have raised an error which would have been handled by the try. Il valore risultante sarebbe stato quindi:The resulting value would then have been:

"No Units"

Un'espressione try converte i valori e gli errori in un valore di record che indica se l'espressione try ha gestito o meno un errore, nonché il valore appropriato o il record di errore estratto durante la gestione dell'errore.A try expression converts proper values and errors into a record value that indicates whether the try expression handled and error, or not, and either the proper value or the error record it extracted when handling the error. Si consideri, ad esempio, l'espressione seguente che genera un errore e quindi lo gestisce immediatamente:For example, consider the following expression that raises an error and then handles it right away:

try error "negative unit count"

Questa espressione restituisce il valore di record annidato seguente, che spiega le ricerche nei campi [HasError], [Error] e [Message] nell'esempio di prezzo unitario precedente.This expression evaluates to the following nested record value, explaining the [HasError], [Error], and [Message] field lookups in the unit-price example before.

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

Un caso comune prevede la sostituzione degli errori con i valori predefiniti.A common case is to replace errors with default values. L'espressione try può essere usata con una clausola otherwise facoltativa per ottenere questo risultato in un formato compatto:The try expression can be used with an optional otherwise clause to achieve just that in a compact form:

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