IntroduçãoIntroduction

Visão geralOverview

O Microsoft Power Query fornece uma experiência avançada de obtenção de dados que abrange vários recursos.Microsoft Power Query provides a powerful "get data" experience that encompasses many features. Uma das principais funcionalidades do Power Query é filtrar e combinar, ou seja, realizar o mashup de dados de uma ou mais coleções avançadas de fontes de dados compatíveis.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. Qualquer mashup de dados desse tipo é expresso usando a Linguagem de fórmula do Power Query (informalmente conhecida como "M").Any such data mashup is expressed using the Power Query Formula Language (informally known as "M"). Power Query incorpora documentos do M em pastas de trabalho do Excel e do Power BI para habilitar o mashup repetível de dados.Power Query embeds M documents in Excel and Power BI workbooks to enable repeatable mashup of data.

Este documento fornece a especificação para M. Após uma breve introdução que visa criar uma primeira intuição e familiaridade com a linguagem, o documento aborda a linguagem de maneira mais precisa, em várias etapas progressivas: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. A estrutura lexical define o conjunto de textos que são lexicalmente válidos.The lexical structure defines the set of texts that are lexically valid.

  2. Os valores, as expressões, os ambientes, as variáveis, os identificadores e o modelo de avaliação que formam os conceitos básicos da linguagem.Values, expressions, environments and variables, identifiers, and the evaluation model form the language's basic concepts.

  3. A especificação detalhada dos valores, tanto primitivos quanto estruturados, define o domínio de destino da linguagem.The detailed specification of values, both primitive and structured, defines the target domain of the language.

  4. Os valores têm tipos, que são um tipo especial de valor, caracterizam os tipos fundamentais de valores e contêm metadados adicionais que são específicos para as formas de valores estruturados.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. O conjunto de operadores no M define que tipos de expressões podem ser formados.The set of operators in M defines what kinds of expressions can be formed.

  6. As funções, outro tipo de valores especiais, fornecem a base para uma biblioteca padrão avançada para o M e permitem a adição de novas abstrações.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. Os erros podem ocorrer ao se aplicar operadores ou funções durante uma avaliação de expressão.Errors can occur when applying operators or functions during expression evaluation. Embora os erros não sejam valores, há maneiras de tratar erros que mapeiam erros de volta para valores.While errors are not values, there are ways to handle errors that map errors back to values.

  8. As expressões let permitem a introdução de definições auxiliares usadas para criar expressões complexas em etapas menores.Let expressions allow for the introduction of auxiliary definitions used to build up complex expressions in smaller steps.

  9. as expressões if dão suporte à avaliação condicional.If expressions support conditional evaluation.

  10. As seções fornecem um mecanismo de modularidade simples.Sections provide a simple modularity mechanism. (O Power Query ainda não é capaz de tirar proveito de funções.)(Sections are not yet leveraged by Power Query.)

  11. Por fim, uma gramática consolidada coleta os fragmentos de gramática de todas as outras seções deste documento em uma definição completa.Finally, a consolidated grammar collects the grammar fragments from all other sections of this document into a single complete definition.

Para teóricos de linguagem de computador: a linguagem de fórmula especificada neste documento é uma linguagem funcional essencialmente pura, de ordem mais alta, dinamicamente tipada e parcialmente lenta.For computer language theorists: the formula language specified in this document is a mostly pure, higher-order, dynamically typed, partially lazy functional language.

Expressões e valoresExpressions and values

O constructo central no M é a expressão.The central construct in M is the expression. Uma expressão pode ser avaliada (computada), produzindo um valor.An expression can be evaluated (computed), yielding a single value.

Embora muitos valores possam ser escritos literalmente como uma expressão, um valor não é uma expressão.Although many values can be written literally as an expression, a value is not an expression. Por exemplo, a expressão 1 é avaliada como o valor 1; a expressão 1+1 é avaliada como o valor 2.For example, the expression 1 evaluates to the value 1; the expressions 1+1 evaluates to the value 2. Essa distinção é sutil, mas importante.This distinction is subtle, but important. As expressões são receitas para avaliação; os valores são os resultados da avaliação.Expressions are recipes for evaluation; values are the results of evaluation.

Os exemplos a seguir ilustram os diferentes tipos de valores disponíveis em M. Como uma convenção, um valor é escrito usando o formato literal em que eles apareceriam em uma expressão que é avaliada apenas para esse valor.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. (Observe que as // indicam o início de um comentário que continua até o final da linha.)(Note that the // indicates the start of a comment which continues to the end of the line.)

  • Um valor primitivo é um valor de parte única, como um número, lógico, texto ou nulo.A primitive value is single-part value, such as a number, logical, text, or null. Um valor nulo pode ser usado para indicar a ausência de dados.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
    
  • Um valor de lista é uma sequência ordenada de valores.A list value is an ordered sequence of values. O M dá suporte a listas infinitas, mas, se escritas como um literal, as listas têm um comprimento fixo.M supports infinite lists, but if written as a literal, lists have a fixed length. Os caracteres de chave { e } denotam o início e o fim de uma lista.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 
    
  • Um registro é um conjunto de campos.A record is a set of fields. Um campo é um par de nome/valor em que o nome é um valor de texto exclusivo dentro do registro do campo.A field is a name/value pair where the name is a text value that is unique within the field's record. A sintaxe literal para valores de registro permite que os nomes sejam gravados sem aspas, um formato também conhecido como identificadores.The literal syntax for record values allows the names to be written without quotes, a form also referred to as identifiers. O exemplo a seguir mostra um registro que contém três campos denominados "A", "B" e "C", que têm os valores 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 
    ]
    
  • Uma tabela é um conjunto de valores organizados em colunas (que são identificadas por nome) e linhas.A table is a set of values organized into columns (which are identified by name), and rows. Não há nenhuma sintaxe literal para criação de uma tabela, mas há várias funções padrão que podem ser usadas para criar tabelas com base em listas ou registros.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.

    Por exemplo:For example:

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

    Isso cria uma tabela com o seguinte formato:This creates a table of the following shape:

    AA BB
    11 22
    33 44
  • Uma função é um valor que, quando invocado com argumentos, produz um novo valor.A function is a value which, when invoked with arguments, produces a new value. As funções são gravadas pela listagem dos parâmetros da função entre parênteses, seguidos pelo símbolo de ir para =>, seguido pela expressão que define a função.Function are written by listing the function's parameters in parentheses, followed by the goes-to symbol =>, followed by the expression defining the function. Essa expressão normalmente se refere aos parâmetros (por nome).That expression typically refers to the parameters (by name).

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

AvaliaçãoEvaluation

O modelo de avaliação da linguagem M é modelado após o modelo de avaliação normalmente encontrado em planilhas, em que a ordem dos cálculos pode ser determinada com base nas dependências entre as fórmulas nas células.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 você tiver escrito fórmulas em uma planilha como o Excel, poderá reconhecer que as fórmulas à esquerda resultarão nos valores à direita quando calculadas: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:

Fórmula que resulta em um valor

No M, uma expressão pode referenciar outras partes da expressão por nome, e o processo de avaliação determinará automaticamente a ordem na qual as expressões referenciadas serão calculadas.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.

Podemos usar um registro para produzir uma expressão que seja equivalente ao exemplo da planilha acima.We can use a record to produce an expression which is equivalent to the above spreadsheet example. Ao inicializar o valor de um campo, podemos fazer referência a outros campos dentro do registro pelo uso do nome do campo, da seguinte maneira: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  
]

A expressão acima é equivalente à seguinte (no sentido de que ambas são avaliadas para valores iguais):The above expression is equivalent to the following (in that both evaluate to equal values):

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

Os registros podem estar contidos ou aninhados em outros registros.Records can be contained within, or nest, within other records. É possível usar o operador de pesquisa ([]) para acessar os campos de um registro por nome.We can use the lookup operator ([]) to access the fields of a record by name. Por exemplo, o seguinte registro tem um campo chamado Sales com um registro e um campo chamado Total que acessa os campos FirstHalf e SecondHalf do registro 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] 
]

A expressão acima é equivalente à seguinte, quando avaliada:The above expression is equivalent to the following when it is evaluated: </span>

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

Os registros também podem estar contidos em listas.Records can also be contained within lists. É possível usar o operador de índice posicional ({}) para acessar um item em uma lista pelo respectivo índice numérico.We can use the positional index operator ({}) to access an item in a list by its numeric index. Os valores dentro de uma lista são referenciados usando um índice de base zero desde o início da lista.The values within a list are referred to using a zero-based index from the beginning of the list. Por exemplo, os índices 0 e 1 são usados para referenciar o primeiro e o segundo itens na lista abaixo: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 
]

As expressões de membro de lista e de registro (bem como as expressões let, apresentadas mais adiante) são avaliadas usando avaliação lenta, o que significa que são avaliadas somente conforme necessário.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. Todas as outras expressões são avaliadas usando a avaliação rápida, ou seja, imediatamente, quando encontradas durante o processo de avaliação.All other expressions are evaluated using eager evaluation, which means that they are evaluated immediately, when encountered during the evaluation process. Uma boa maneira de pensar sobre nisso é lembrar de que a avaliação de uma expressão de lista ou registro retornará um valor de lista ou registro que se lembra de como seus itens de lista ou campos de registro precisam ser computados, quando solicitado (por operadores de pesquisa ou índice).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).

FunçõesFunctions

No M, uma função é um mapeamento de um conjunto de valores de entrada para um valor de saída.In M, a function is a mapping from a set of input values to a single output value. Para escrever uma função, primeiro é preciso nomear o conjunto necessário de valores de entrada (os parâmetros para a função) e, em seguida, fornecer uma expressão que calcule o resultado da função usando esses valores de entrada (o corpo da função) após o símbolo de ir para (=>).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. Por exemplo:For example:

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

Uma função é um valor, assim como um valor de número ou de texto.A function is a value just like a number or a text value. O exemplo a seguir mostra uma função que é o valor de um campo Add, que é invocada ou executada de vários outros campos.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 uma função é chamada, um conjunto de valores é especificado, que são substituídos logicamente pelo conjunto necessário de valores de entrada dentro da expressão do corpo da função.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
]

BibliotecaLibrary

O M inclui um conjunto comum de definições disponíveis para uso por meio de uma expressão chamada de biblioteca padrão ou simplesmente biblioteca.M includes a common set of definitions available for use from an expression called the standard library, or just library for short. Essas definições consistem em um conjunto de valores nomeados.These definitions consist of a set of named values. Os nomes de valores fornecidos por uma biblioteca estão disponíveis para uso em uma expressão sem terem sido definidos explicitamente pela expressão.The names of values provided by a library are available for use within an expression without having been defined explicitly by the expression. Por exemplo:For example:

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

OperadoresOperators

O M inclui um conjunto de operadores que podem ser usados em expressões.M includes a set of operators that can be used in expressions. Os operadores são aplicados a operandos para formar expressões simbólicas.Operators are applied to operands to form symbolic expressions. Por exemplo, na expressão 1 + 2, os números 1 e 2 são operandos e o operador é o operador de adição (+).For example, in the expression 1 + 2 the numbers 1 and 2 are operands and the operator is the addition operator (+).

O significado de um operador pode variar dependendo do tipo de valores dos seus operandos.The meaning of an operator can vary depending on what kind of values its operands are. Por exemplo, o operador de adição pode ser usado com outros tipos de valores que não sejam números: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)

Outro exemplo de um operador com significado dependente do operando é o operador de combinação (&):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 ]

Observe que nem todas as combinações de valores são compatíveis com um operador.Note that not all combinations of values may be supported by an operator. Por exemplo:For example:

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

As expressões que, quando avaliadas, encontram condições de operador indefinidas são avaliadas como erros.Expressions that, when evaluated, encounter undefined operator conditions evaluate to errors. Mais informações sobre erros no M serão fornecidas posteriormente.More on errors in M later.

MetadadosMetadata

Os metadados são informações sobre um valor que está associado a um valor.Metadata is information about a value that is associated with a value. Os metadados são representados como um valor de registro, chamado de registro de metadados.Metadata is represented as a record value, called a metadata record. Os campos de um registro de metadados podem ser usados para armazenar os metadados de um valor.The fields of a metadata record can be used to store the metadata for a value.

Cada valor tem um registro de metadados.Every value has a metadata record. Se o valor do registro de metadados não tiver sido especificado, o registro de metadados estará vazio (não terá nenhum campo).If the value of the metadata record has not been specified, then the metadata record is empty (has no fields).

Os registros de metadados fornecem uma forma de associar informações adicionais a qualquer tipo de valor de maneira discreta.Metadata records provide a way to associate additional information with any kind of value in an unobtrusive way. A associação de um registro de metadados com um valor não altera o valor nem o comportamento dele.Associating a metadata record with a value does not change the value or its behavior.

Um valor de registro de metadados y é associado a um valor x existente usando a sintaxe x meta y.A metadata record value y is associated with an existing value x using the syntax x meta y. Por exemplo, este código associa um registro de metadados aos campos Rating e Tags com o valor de texto "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"} ]

Para valores que já contêm um registro de metadados não vazio, o resultado de aplicar o operador meta é que a mesclagem do registro de metadados novo e do existente é computada.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. Por exemplo, as seguintes duas expressões são equivalentes uma à outra e à expressão anterior: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"} ])

Um registro de metadados pode ser acessado para um determinado valor usando a função Value.Metadata.A metadata record can be accessed for a given value using the Value.Metadata function. No exemplo a seguir, a expressão no campo ComposerRating acessa o registro de metadados do valor no campo Composer e, em seguida, acessa o campo Rating do registro de metadados.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
]

Expressão letLet expression

Muitos dos exemplos mostrados até agora incluíam todos os valores literais da expressão no resultado da expressão.Many of the examples shown so far have included all the literal values of the expression in the result of the expression. A expressão let permite que um conjunto de valores sejam computados, que nomes sejam atribuídos a eles e, depois, que esses valores sejam usados em uma expressão subsequente que segue a instrução 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. Por exemplo, em nosso exemplo de dados de vendas, poderíamos fazer: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

O resultado da expressão acima é um valor numérico (4600) que foi computado com base nos valores associados aos nomes 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.

Expressão ifIf expression

A expressão if seleciona entre duas expressões com base em uma condição lógica.The if expression selects between two expressions based on a logical condition. Por exemplo:For example:

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

A primeira expressão (2 + 2) será selecionada se a expressão lógica (2 > 1) for verdadeira e a segunda expressão (1 + 1) será selecionada se ela for falsa.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. A expressão selecionada (nesse caso, 2 + 2) é avaliada e torna-se o resultado da expressão if (4).The selected expression (in this case 2 + 2) is evaluated and becomes the result of the if expression (4).

ErrorsErrors

Um erro é uma indicação de que o processo de avaliação de uma expressão não pôde produzir um valor.An error is an indication that the process of evaluating an expression could not produce a value.

Os erros são gerados por operadores e funções que encontram condições de erro ou pelo uso da expressão error.Errors are raised by operators and functions encountering error conditions or by using the error expression. Os erros são tratados usando a expressão try.Errors are handled using the try expression. Quando um erro é gerado, é especificado um valor que pode ser usado para indicar por que o erro ocorreu.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])

O exemplo acima acessa o campo Sales[UnitPrice] e formata o valor que produz o resultado:The above example accesses the Sales[UnitPrice] field and formats the value producing the result:

"Unit Price: 2"

Se o campo Units tivesse sido zero, o campo UnitPrice teria gerado um erro que teria sido tratado pela 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. O valor resultante teria sido:The resulting value would then have been:

"No Units"

Uma expressão try converte valores e erros adequados em um valor de registro que indica se a expressão try tratou um erro ou não, bem como o valor apropriado ou o registro de erro que ela extraiu ao tratar o erro.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. Por exemplo, considere a seguinte expressão que gera um erro e o trata imediatamente:For example, consider the following expression that raises an error and then handles it right away:

try error "negative unit count"

Essa expressão avalia valor de registro aninhado a seguir, explicando as pesquisas de campo [HasError], [Error] e [Message] no exemplo de preço unitário anterior.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 
        ] 
]

Um caso comum é substituir erros por valores padrão.A common case is to replace errors with default values. A expressão try também pode ser usada com uma cláusula otherwise opcional para obter apenas isso em um formato compacto: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