Loops em Power Query com List.Accumulate: Guia Completo

Tempo de leitura:

4–7 minutes

Neste artigo vou mostrar-te a função List.Accumulate! Uma função extraordinária que permite realizar loops sobre uma lista!

A função funciona como um iterador, ou seja, percorre os itens de uma lista, executando uma determinada ação em cada item, mas ao contrário de um iterador normal, esta função tem memória! Guarda o estado (state) da última iteração.

Ao ser executada esta função acede ao item atual da lista e ao resultado da última iteração, na operação realizada, a função usa o resultado da operação como o input para o próximo passo da iteração.

Parece confuso, mas o processo é bastante simples!

Sintaxe da função

Vamos começar por conhecer a sintaxe da função!

List.Accumulate (

     List as list,

     Seed as any,

     Accumulator as function )

Que significa o seguinte:

List.Accumulate (

     List as list,                   // Lista a iterar

     Seed as any,                    // valor inicial

     Accumulator as function )       // Operação realizada

  • List: A lista para a função. A função List.Accumulate itera (percorre) cada valor na lista enquanto aplica a função acumuladora (Accumulator)
  • Seed: Este é apenas o ponto de partida, que pode ser um valor, uma lista, ou até uma tabela.
  • Accumulator: A operação a realizar, com as instruções necessárias para a função executar para cada item da lista. A função acumuladora tem 2 argumentos -> State e Current. Os nomes podem ser dados conforme o que o utilizador pretende.
    • State é o valor acumulado, que começa com o valor inicial (seed).
    • Current é o valor / item atual da lista.

Depois de executada a 1ª iteração o “state” deixa de ser (seed) e passa a ser o último valor da operação acumuladora (a memória) que é executada com o próximo item da lista! E assim sucessivamente até terminar a lista!

Exemplo 1: List.Acumulate simples

Neste primeiro exemplo vamos perceber o resultado que sai da função. Esta questão é importante, pois está relacionado com o parâmetro seed. Seed é o valor inicial, que como indicado na descrição pode ser um valor, uma lista, uma tabela, por exemplo. Isto significa que este ponto inicial é fundamental para perceberes a função. Se o seed for um valor, a função List.Accumulate devolve um valor, se for uma lista, devolve uma lista e por exemplo se for uma tabela, devolve uma tabela.

Exemplo da função:

No primeiro passo começamos por criar uma lista: = {1..5}

No passo seguinte, colocamos a expressão.

= List.Accumulate (

    Origem,

    1,

    (state, current) => state + current

)

Diagrama explicativo da função List.Accumulate em Excel, mostrando a lista de valores de 1 a 5, o valor inicial (seed) como 1, e a função acumuladora que soma o estado atual com o valor atual.

Como podes verificar, o resultado é um valor -> 16. A função está a acumular, fazendo uma simples soma entre o estado (state) e o valor atual (current). Mas como o valor inicial (seed) é um número, a função retorna um número.

Eis o processo mais visual…

Tabela explicativa da função List.Accumulate com os passos do cálculo acumulativo entre estado e valor atual.

O qual podes ver numa lógica do cálculo acumulativo realizado com uma operação simples em Excel.

Tabela ilustrando a função List.Accumulate, mostrando os estados e passos da iteração com exemplos de cálculo.

E que resulta no valor 16.

Tabela ilustrativa mostrando o funcionamento da função List.Accumulate, com colunas para 'state' (Último Estado), 'current' (Atual) e Acumulador, demonstrando cinco passos de iteração com valores acumulativos.

O resultado é sempre o “resultado” do último passo!

Exemplo 2: List.Acumulate simples a devolver uma lista

O próximo exemplo é exatamente o mesmo, mas vamos devolver uma lista! Para devolver uma lista, na operação efetuada precisamos de ajustar alguns detalhes.

  • A função acumuladora é -> estado (state) + atual (current): neste caso como o nosso estado inicial é uma lista, o estado também será uma lista. Não é possível somar uma lista com um valor. Desta forma a função acumuladora necessita de obter o último valor da lista (List.Last) para depois podermos somar ao valor atual da lista.

= List.Accumulate (

    {1..5}, // Lista inicial

    {1},    // Valor inicial em lista (seed)

    (estado, atual) => estado & {List.Last(estado) + atual} //Resultado em Lista

)

Exemplo visual da função List.Accumulate em Power Query, mostrando a sintaxe e o processo de acumulação de valores em uma lista.

Exemplo 3: List.Acumulate com texto

Quando temos uma lista de texto é também possível realizar um loop sobre a lista. E realizar operações. Este exemplo é semelhante aos anteriores, mas estamos a trabalhar com uma lista de texto.

= List.Accumulate (

    Origem,

    {“1”},

    (estado, atual) => estado & {List.Last(estado) & “-” & atual}

)

Diagrama explicativo da função List.Accumulate no Excel, mostrando os passos para acumular uma lista de letras e gerar um resultado em texto.

Exemplo 4: List.Acumulate uma Tabela

O próximo exemplo já é um pouco mais aliciante pois vamos iniciar com uma Tabela. O seed é uma tabela, e consequentemente o resultado continuará a ser uma tabela!

Vamos começar por criar uma tabela simples em Power Query.

A interface do Power Query mostrando a janela de criação de uma tabela, com a opção de introduzir dados e uma tabela de exemplo.

Imagina agora inserir uma coluna com o desconto de 10 % aplicado.

Tela do Power Query mostrando a adição de uma coluna personalizada com a fórmula aplicada para calcular descontos sobre valores.

O resultado é o seguinte…

Código M do Power Query que adiciona uma coluna de desconto a uma tabela, multiplicando os valores por 0,1 e especificando o tipo de dados como numérico.

Mas o objetivo é, comparar vários descontos! Assim temos um exemplo perfeito para a função List.Accumulate, pois podemos ter os descontos numa lista, e acumular a criação de uma nova coluna, mantendo o estado (Tabela) como memória.

Depois de termos a Tabela e o exemplo do código base para criação da nova coluna. Vamos criar a lista a iterar.

Exemplo de uma lista no Excel com valores decimais de 0,1 a 0,5 em uma fórmula.

Agora com a Função List.Accumulate, podemos criar uma coluna nova sobre cada um dos valores da lista. Apenas temos de fazer alguns ajustes ao código.

= List.Accumulate (

    ListaDescontos,

    Tabela,

    (EstadoTabela, ColunaAtual) =>

        Table.AddColumn(
            EstadoTabela,

            Text.From(ColunaAtual * 100) & “% Desconto”,

            each [Valor] * ColunaAtual, type number

        )

 )

No cenário da função temos apenas as seguintes adaptações.

  • EstadoTabela: Representa a nossa tabela
  • Text.From(ColunaAtual * 100) & “% Desconto”: Apenas uma adaptação para colocar o nome da nova coluna mais dinâmico.
  • ColunaAtual: Representa o valor atual da lista, e assim o desconto aplicado.
Captura de tela de uma fórmula List.Accumulate no Excel, mostrando uma tabela com itens e valores, além de colunas para diferentes percentuais de desconto.

Exemplo 5: Iterar sobre as colunas de uma Tabela Existente

No último exemplo da função List.Accumulate vamos iterar sobre as colunas de uma Tabela já existente. O objetivo agora não é adicionar colunas, mas sim realizar uma transformação sobre todas as colunas.

Assim começamos por uma tabela.

Tabela com dados de departamentos, incluindo os valores de vendas mensais de Janeiro a Maio.

Testamos a solução em primeiro lugar com uma coluna, para podermos adaptar mais facilmente o código. O teste será saber o parcial de cada departamento sobre o total global.

Uma vez que vamos usar as colunas como iterador, precisamos em primeiro lugar de uma lista com os nomes das colunas a iterar.

= List.Skip(Table.ColumnNames(Tabela), 1)

Código no Excel para extrair os nomes das colunas de uma tabela, começando pela segunda coluna, com a função List.Skip.

Agora, vamos testar realizar uma transformação numa coluna, por exemplo Janeiro, para obter o valor de cada departamento sobre o valor total.

= Table.TransformColumns (

    Tabela,

    {

        {“Janeiro”, each _ / List.Sum(Tabela[Janeiro]), Decimal.Type}

    })

Esta fórmula, da função Table.TransformColumns é a base para realizarmos a transformação a todas as restantes colunas.

Código em Excel mostrando a função Table.TransformColumns aplicada a uma tabela de dados financeiros, destacando a coluna de Janeiro e os valores correspondentes por departamento.

Adaptar o código para a função List.Accumulate

Agora já temos todos os ingredientes para adaptar o código para a função List.Accumulate.

= List.Accumulate (

    ListaNomes,

    Tabela,

    (EstadoTabela, ColunaAtual) =>

        Table.TransformColumns (

            EstadoTabela,

            {

                {ColunaAtual, each _ / List.Sum(Table.Column(EstadoTabela, ColunaAtual)), Percentage.Type}

            }

      )

)

Por uma questão de contexto de avaliação usamos aqui a função Table.Column para identificar a variável da tabela (EstadoTabela) e não a Tabela original a iterar.

Código da função List.Accumulate em Power Query aplicado a uma tabela com percentagens por departamentos.

Uma vez que a lista com os nomes da coluna da tabela, é variável e versátil, existindo novas colunas a iteração é direta!

Próximo artigo:

Artigo Anterior:


Comments

Leave a Reply

Discover more from Exceldriven

Subscribe now to keep reading and get access to the full archive.

Continue reading