Microsoft Power Fx tabelas

Nota

Microsoft Power Fx é o novo nome para a linguagem de fórmula de aplicações de tela. Estes artigos estão em desenvolvimento, pois a Microsoft extrai a linguagem das aplicações canvas, integra-a com outros produtos da Microsoft Power Platform e disponibiliza-a como open source. Comece com a Visão geral de Microsoft Power Fx para uma introdução ao idioma.

As tabelas Power Fx da Microsoft organizam os dados em registos, campos e colunas provenientes de fontes como Microsoft Excel, SharePoint e SQL Server. Aprenda estas estruturas para escrever fórmulas que acedam, moldam e manipulam dados tabulares de forma eficaz.

  • Os registos contêm uma ou mais categorias de informações relativas a uma pessoa, local ou coisa. Por exemplo, podem conter o nome, o endereço de e-mail e o número de telefone de um cliente individual. Outras ferramentas referem-se aos registos como “linhas” ou “itens.”
  • As tabelas incluem um ou mais registos que contêm as mesmas categorias de informações. Por exemplo, podem conter os nomes, os endereços de e-mail e os números de telefone de 50 clientes.

Pode criar várias fórmulas que assumem o nome de uma tabela como argumento, da mesma forma que uma fórmula do Excel assume uma ou mais referências de células como argumentos. Algumas fórmulas do Power Fx devolvem uma tabela que reflete os outros argumentos que especificar. Por exemplo, pode criar uma fórmula:

  • para atualizar um registo numa tabela ao especificar essa tabela como um de múltiplos argumentos para a função Patch.
  • para adicionar, remover e mudar o nome das colunas de uma tabela ao especificar essa tabela como argumento para as funções AddColumns, DropColumns ou RenameColumns. Nenhuma destas funções modificada a tabela original. Em vez disso, a função devolve outra tabela com base nos outros argumentos que especificar.

Elementos de uma tabela

Captura de ecrã de registos, campos e colunas que formam uma tabela.

Registos

Cada registo contém, pelo menos, uma categoria de informações para uma pessoa, local ou coisa. O exemplo anterior mostra um registo para cada produto (Chocolate, Pão e Água) e uma coluna para cada categoria de informação (Preço, Quantidade disponível e Quantidade em Encomenda).

Numa fórmula, pode referir-se a um registo por si só, fora do contexto de uma tabela, mediante a utilização de chavetas. Por exemplo, o registo { Name: "Strawberries", Price: 7.99 } não está associado a uma tabela. Tenha em atenção que os nomes de campo, tais como Name (Nome) e Price (Preço) nesse exemplo, não estão entre aspas.

Campos

Os campos são pedaços de informação individuais nos registos. Pode ver este tipo de campo como um valor numa coluna relativamente a registos específicos.

Tal como sucede com os controlos, para fazer referência a um campo de um registo, utiliza o .operador no registo. Por exemplo,, First(Products).Name devolve o campo Name (Nome) do primeiro registo na tabela Products (Produtos).

Os campos podem conter outro registo ou tabela, como mostra o exemplo da função GroupBy. Pode aninhar tantos níveis de registos e tabelas quanto pretenda.

Colunas

As colunas referem-se ao mesmo campo de um ou mais registos numa tabela. No exemplo anterior, cada produto tem um campo de preço, e esse preço está na mesma coluna para todos os produtos. A tabela anterior tem quatro colunas, representadas horizontalmente no topo:

  • Nome
  • Preço
  • Quantidade Em Stock
  • Quantidade em Encomenda

O nome da coluna reflete os campos na mesma.

Todos os valores numa coluna são do mesmo tipo de dados. No exemplo anterior, a coluna "Quantidade em Stock" contém sempre um número e não pode conter uma cadeia de caracteres, como "12 unidades", num registo. O valor de qualquer campo também pode ser vazio.

Pode ter referido colunas como "campos" noutras ferramentas.

Tabela

As tabelas incluem um ou mais registos, cada qual com vários campos que têm nomes consistentes em todos os registos.

Qualquer tabela que seja armazenada numa origem de dados ou numa coleção tem um nome, que é utilizado para fazer referência a essa tabela e para a transmitir às funções que assumem tabelas como argumentos. As tabelas também podem ser resultado de uma função ou de uma fórmula.

Tal como no exemplo seguinte, pode exprimir uma tabela numa fórmula através da função Table com um conjunto de registos, que são expressos em chavetas:

Table( { Value: "Strawberry" }, { Value: "Vanilla" } )

Também pode definir uma tabela de coluna única com parênteses retos. Uma forma equivalente de escrever o anterior:

[ "Strawberry", "Vanilla" ]

Fórmulas de tabela

No Excel e no Power Fx vai utilizar fórmulas para manipular os números e as cadeias de texto de formas semelhantes:

  • No Excel, escreva um valor, como 42, na célula A1, e, depois, escreva uma fórmula, como A1+2, noutra célula, para mostrar o valor de 44.
  • No Power Apps defina a propriedade Default de Slider1 como 42, e defina a propriedade Text de uma etiqueta como Slider1.Value + 2 para mostrar o valor de 44.

Em ambos os casos, o valor calculado é alterado automaticamente se modificar os valores dos argumentos (por exemplo, o número na célula A1 ou o valor de Slider1).

Da mesma forma, pode utilizar fórmulas para aceder e manipular dados em tabelas e registos. Pode utilizar os nomes das tabelas como argumentos em algumas fórmulas, tais como Min(Catalog, Price), para mostrar o valor mais baixo na coluna Prices da tabela Catalog (Catálogo). Outras fórmulas disponibilizam tabelas completas como valores de retorno, como RenameColumns(Catalog, "Price", "Cost"), que devolve todos os registos da tabela Catalog, mas altera o nome da coluna Price para Cost (Custo).

Tal como com os números, as fórmulas que envolvem tabelas e registos são recalculadas automaticamente à medida que a tabela ou o registo subjacente é alterado. Se o custo de um produto na tabela Catalog baixar para além do mínimo anterior, o valor de retorno da fórmula Min altera-se automaticamente para corresponder ao mesmo.

Funções de tabelas e propriedades de controlos

Considere a função Lower. Se a variável Bem-vindo contiver a cadeia de texto "Olá, mundo", a fórmula Lower (bem-vindo) retornará "Olá, mundo". Esta função não altera o valor dessa variável. Lower é uma função pura na qual só processa a entrada e produz a saída. Isto é tudo; não tem efeitos colaterais. Todas as funções no Excel e a maior parte das funções no Power Fx são funções puras, que permitem que a pasta de trabalho ou a aplicação seja recalculada automaticamente.

O Power Fx oferece um conjunto de funções que operam em tabelas do mesmo modo. Estas funções tomam tabelas como entrada e filtro, ordenar, transformar, reduzir e resumir tabelas de dados inteiras. Na verdade, Lower e muitas outras funções que normalmente levam um único valor também podem pegar numa tabela de coluna única como entrada.

Muitas funções pegam numa tabela de coluna única como a entrada. Se uma tabela inteira tiver apenas uma coluna, pode especificá-la por nome. Se uma tabela tiver várias colunas, pode especificar uma dessas colunas utilizando a sintaxe Table. Column. Por exemplo, Products.Name devolve a tabela de coluna única dos valores de nome apenas da tabela Produtos.

Pode remodelar completamente uma tabela mas, no entanto, pretende utilizar as funções AddColumns, RenameColumns, ShowColumns ou DropColumns. Novamente, estas funções alteram apenas a sua saída, e não a respetiva origem.

Fórmulas comportamentais

Outras funções foram especificamente concebidas para modificar dados e ter efeitos colaterais. Uma vez que estas funções não são puras, tem de as criar com atenção, e não podem participar na recálculo automático dos valores na aplicação. Pode utilizar estas funções apenas em fórmulas comportamentais.

Âmbito do registo

Algumas funções funcionam avaliando uma fórmula em todos os registos de uma tabela, um registo de cada vez. O resultado da fórmula é utilizado de diferentes formas:

  • AddColumns - A fórmula fornece o valor para a nova coluna.
  • Average, Max, Min, Sum, StdevP, VarP - a fórmula fornece o valor a ser agregado.
  • Filter, Lookup - a fórmula determina se o registo deve ser incluído na saída.
  • Concat - a fórmula determina as cadeias que vão ser concatenadas.
  • Distinct - a fórmula devolve um valor, que é utilizado para identificar registos duplicados.
  • ForAll - a fórmula pode devolver qualquer valor, potencialmente com efeitos secundários.
  • Sort - a fórmula fornece o valor pelo qual ordenar os registos.
  • With - a fórmula pode devolver qualquer valor, potencialmente com efeitos secundários.

Dentro destas fórmulas, pode referenciar os campos do registo que está a ser processado. Cada uma destas funções cria um “âmbito de registo” no qual a fórmula é avaliada e onde os campos do registo estão disponíveis como identificadores de nível superior. Também pode referenciar as propriedades de controlo e outros valores em toda a aplicação.

Por exemplo, pegue numa tabela de Produtos colocada numa variável global:

Captura de ecrã da tabela de Produtos com as quantidades solicitadas e disponíveis.

Set( Products,
    Table(
        { Product: "Widget",    'Quantity Requested': 6,  'Quantity Available': 3 },
        { Product: "Gadget",    'Quantity Requested': 10, 'Quantity Available': 20 },
        { Product: "Gizmo",     'Quantity Requested': 4,  'Quantity Available': 11 },
        { Product: "Apparatus", 'Quantity Requested': 7,  'Quantity Available': 6 }
    )
)

Para determinar se algum destes produtos tem mais pedidos do que o disponível:

Filter( Products, 'Quantity Requested' > 'Quantity Available' )

O primeiro argumento para Filter é a tabela de registos na qual operar e o segundo é uma fórmula. Filter cria um âmbito de registo para avaliar esta fórmula na qual os campos de cada registo estão disponíveis, este caso Product, Quantity Requested e Quantity Available. O resultado da comparação determina se cada registo deve ser incluído no resultado da função:

Captura de ecrã de uma tabela de Produtos filtrada onde a quantidade solicitada excede a quantidade disponível.

Acrescentando a este exemplo, pode calcular quanto de cada produto deve encomendar:

AddColumns( 
    Filter( Products, 'Quantity Requested' > 'Quantity Available' ), 
    "Quantity To Order", 'Quantity Requested' - 'Quantity Available'
)

Aqui adiciona uma coluna calculada ao resultado. O AddColumns tem o seu próprio âmbito de registo que utiliza para calcular a diferença entre o que é solicitado e o que está disponível.

Captura de ecrã da tabela de Produtos após adicionar a coluna Quantidade para Encomenda calculada.

Por fim, pode reduzir a tabela de resultados apenas às colunas que pretende:

ShowColumns(
    AddColumns(
        Filter( Products, 'Quantity Requested' > 'Quantity Available' ),
        "Quantity To Order", 'Quantity Requested' - 'Quantity Available'
    ),
    "Product",
    "Quantity To Order"
)

Captura de ecrã da tabela de resultados com apenas as colunas Produto e Quantidade a Encomendar.

Note que nos exemplos anteriores, usas aspas duplas (") em alguns locais e aspas simples (') noutros. São necessárias aspas simples ao referenciar o valor de um objeto, como um campo ou tabela, se o nome do objeto contiver um espaço. Use aspas duplas quando não estiver a referenciar o valor de um objeto, mas sim a falar sobre ele, especialmente em situações em que o objeto ainda não existe, como no caso das AddColumns.

Desambiguação

Os nomes dos campos que adicionas com o âmbito do registo sobrepõem-se aos mesmos nomes de outras partes da aplicação. Quando esta sobreposição acontece, ainda pode aceder a valores fora do âmbito do registo usando o @ operador de desambiguação :

  • Para aceder a valores de escopos de registos aninhados, use o @ operador com o nome da tabela em que está a operar, seguindo este padrão:
    Table[@FieldName]
  • Para aceder a valores globais, tais como origens de dados, coleções e variáveis de contexto, utilize o padrão [@ObjectName] (sem uma designação de tabela).

Se a tabela em que está a operar for uma expressão, como Filter(Table, ... ), não pode usar o operador de desambiguação. Apenas o âmbito de registo mais interno pode aceder a campos desta expressão de tabela não utilizando o operador de desambiguação.

Por exemplo, imagine que tem uma coleção X:

Captura de ecrã da coleção X contendo os valores 1 e 2.

Pode criar esta coleção usando o ClearCollect( X, [1, 2] ).

E outra coleção Y:

Captura de ecrã da coleção Y contendo os valores A e B.

Pode criar esta coleção usando o ClearCollect( Y, ["A", "B"] ).

Além disso, defina uma variável de contexto com o nome Value (Valor) com esta fórmula: UpdateContext( {Value: "!"} )

Vamos juntar tudo. Neste contexto, a fórmula seguinte:

Ungroup(
    ForAll( X,
        ForAll( Y,
            Y[@Value] & Text( X[@Value] ) & [@Value]
        )
    ),
    "Value"
)

produz esta tabela:

Captura de ecrã do resultado aninhado ForAll, combinando entradas X, Y e globais de Valor.

O que se passa aqui? A função ForAll mais externa define um escopo de registo para X, para que possa aceder ao campo Valor de cada registo à medida que processa. Pode aceder simplesmente usando a palavra Valor ou usando X[@Value].

A função ForAll mais interna define outro âmbito de registo para Y. Como esta tabela também tem um campo Valor definido, usar Valor aqui refere-se ao campo no registo de Y e já não ao de X. Para aceder ao campo Valor de X, deve usar a versão mais longa com o operador de desambiguação.

Como Y é o âmbito de registo mais interno, aceder a campos desta tabela não requer desambiguação, pelo que pode usar esta fórmula com o mesmo resultado:

Ungroup(
    ForAll( X,
        ForAll( Y,
            Value & Text( X[@Value] ) & [@Value]
        )
    ),
    "Value"
)

Todos os âmbitos de registo ForAll substituem o âmbito global. A variável de contexto Value que definiste não está disponível pelo nome sem o operador de desambiguação. Para aceder a este valor, utilize [@Value].

Ungroup uniformiza o resultado, porque as funções ForAll aninhadas resultam numa tabela de resultados aninhada.

Tabelas de coluna única

Para operar numa única coluna a partir de uma tabela, utilize a função Iscolumns como neste exemplo:

ShowColumns( Products, "Product" )

Esta fórmula produz esta tabela de coluna única:

Captura de ecrã de uma tabela de coluna única contendo os valores do Produto.

Para uma alternativa mais curta, especifique Table.Column, que extrai a tabela de coluna única apenas da coluna a partir da tabela. Por exemplo, esta fórmula produz exatamente o mesmo resultado que a utilização de ShowColumns.

Products.Product

Registos Inline

Para expressar registos, são utilizadas chavetas que contêm valores de campo nomeados. Por exemplo, pode expressar o primeiro registo da tabela no início deste tópico com esta fórmula:

{ Name: "Chocolate", Price: 3.95, 'Quantity on Hand': 12, 'Quantity on Order': 10 }

Também pode incorporar fórmulas dentro de outras fórmulas, como este exemplo mostra:

{ Name: First(Products).Name, Price: First(Products).Price * 1.095 }

Pode aninhar registos ao aninhar as chavetas, como este exemplo mostra:

{ 'Quantity': { 'OnHand': ThisItem.QuantOnHand, 'OnOrder': ThisItem.QuantOnOrder } }

Coloque entre plicas o nome de cada coluna que contém um caráter especial, como espaço ou dois pontos. Para utilizar uma plica dentro de um nome de coluna, duplique-a.

Repare que o valor da coluna Price não inclui símbolo de moeda, como um cifrão. Essa formatação é aplicada quando o valor é exibido.

Tabelas inline

Pode criar uma tabela com a função Table e um conjunto de registos. Pode expressar a tabela no início deste tópico com esta fórmula:

Table( 
   { Name: "Chocolate", Price: 3.95, 'Quantity on Hand': 12, 'Quantity on Order': 10 },
   { Name: "Bread", Price: 4.95, 'Quantity on Hand': 34, 'Quantity on Order': 0 },
   { Name: "Water", Price: 4.95, 'Quantity on Hand': 10, 'Quantity on Order': 0 } 
)

Também pode aninhar tabelas:

Table( 
   { Name: "Chocolate", 
     'Quantity History': Table( { Quarter: "Q1", OnHand: 10, OnOrder: 10 },
                                { Quarter: "Q2", OnHand: 18, OnOrder: 0 } ) 
   }
)

Tabelas de valor inline

Pode especificar valores em parênteses retos para criar tabelas de coluna única. A tabela resultante tem uma única coluna, com o nome Value.

Por exemplo, [ 1, 2, 3, 4 ] é equivalente a Table( { Value: 1 }, { Value: 2 }, { Value: 3 }, { Value: 4 } ) e retorna esta tabela:

Captura de ecrã de uma tabela de valores inline contendo os números de 1 a 4.