Tempo de leitura:
Neste artigo vou apresentar a função List.Accumulate em Power Query, que é uma das funções que permite criar listas através de iteração e que funciona como o conceito “while loop” presente em várias linguagens de programação.
Esta função em particular, não trabalha sobre uma lista, mas como o nome indica, permite gerar uma lista, mas neste caso o processo de gerar uma lista é definido em função de uma condição. A lista é gerada enquanto uma condição for verdadeira, assim que a condição deixar de ser verdadeira, a lista deixa de gerar valores.
Sintaxe da função
List.Generate(
initial as function,
condition as function,
next as function,
optional selector as nullable function,
) as list
A função tem algumas particularidades sendo que a principal talvez, seja o facto de todos os parâmetros da função serem definidos como “função”:
- Initial -> representa o valor inicial da lista, sobre o qual a mesma começa a ser gerada. O valor tem de ser definido como função e neste caso sobre a forma explicita de uma função, sem parâmetros: ()=>
- Condition -> Este parâmetro representa a condição avaliada para permitir gerar o valor da lista. É o equivalente a dizer “enquanto a condição for verdadeira… faz algo”. Aqui podemos definir a função explicita ou usar a expressão “each _”.
- Next -> Este parâmetro é que define o sumo da função, o que pretendemos que aconteça com a lista, que na verdade é o valor a gerar. Aqui podemos definir a função explicita ou usar a expressão “each _”
- Selector -> Este parâmetro é opcional e permite definir o que pretendemos que aconteça com a lista depois desta ser gerada. Este parâmetro é muito útil se pretendemos realizar alguma alteração a lista.
Exemplo para a função
Vamos começar por aceder ao Editor do Power Query…

E no editor, vamos começar uma consulta em branco.

Na barra de fórmulas colocamos a expressão:
= List.Generate(
() => 1,
each _ <= 20,
each _ + 1
)

Aplicar o 4 parâmetro – Selector
O 4 parâmetro permite alterar a lista depois da mesma ser gerada. Isto significa que podemos realizar qualquer alteração aos valores da lista gerando uma nova lista. Importante também verificar que neste caso a condição não afeta a nova lista. A condição (parametro 2) é importante para avaliar o valor e definir como o próximo valor (Next -> parametro 3) é gerado. Contudo neste caso o 4º Parâmetro -> Selector, já é executado depois da lista estar criada, então não é afetado pela condição!

Criar a função List.Generate com funções específicas
Em vez de usarmos a expressão “each _” podemos aplicar uma função explicita, com a sintaxe (parametro) => para melhor interpretar os paramentos da função. Apenas o primeiro parâmetro (inicial) é que deve ser definido com a função explicita e sem argumentos.
= List.Generate(
() => 1,
(valor) => valor <= 20,
(valor) => valor + 1,
(valor) => valor * 2
)
O resultado não é alterado, apenas mais lógico e coerente com um parâmetro explicito para a função.

List.Generate com mais de um valor
Se pretendemos gerar uma lista com mais do que um simples valor, podemos criar uma lista a partir de um registo. Se o valor inicial é um registo, o resultado será uma lista com registos aninhados, onde a partir dos quais podemos extrair o valor de um campo.
Vamos iniciar uma nova lista para verificar este comportamento.
= List.Generate (
()=> [numero = 1],
each [numero] <= 12,
each [numero = [numero] + 1]
)

Nota aqui o comportamento nos passos:
- O valor inicial é um registo, apenas com um campo -> número
- A condição avaliar o campo do registo
- O resultado do próximo passo é um Registo, que modifica o campo [numero] e adiciona 1 ao valor.
Atribuir mais campos ao registo
Agora que temos um registo na lista podemos adicionar mais campos.
= List.Generate (
()=> [numero = 1, data = #date(2025, 1, 1)],
each [numero] <= 12,
each [numero = [numero] + 1, data = Date.AddMonths( [data], 1) ]
)

Usar o Selector – 4ª argumento
Agora que sabemos com acrescentar vários campos ao registo, acrescentei mais alguns campos na lista. O resultado é um registo com 4 campos. Mas usando o 4º Argumento -> Selector, podemos “desmontar” a lista para mostrar o pretendido.
= List.Generate (
()=> [numero = 1, data = #date(2025, 1, 1), DiaSemana = Date.DayOfWeekName(#date(2025, 1, 1)), FimMes = Date.EndOfMonth(#date(2025, 1, 1))],
each [numero] <= 12,
each [numero = [numero] + 1, data = Date.AddMonths( [data], 1), DiaSemana = Date.DayOfWeekName(Date.AddMonths([data],1)), FimMes = Date.EndOfMonth(Date.AddMonths([data], 1)) ],
each [DiaSemana]
)

Caso prático – Gerar uma lista de data numa tabela
Vamos então agora a um caso prático, onde vamos gerar uma coluna numa tabela, que permite gerar uma lista em função das datas de Encomenda e Entrega.

Começamos por trazer a tabela para o Power Query através do Separador Dados -> Da Tabela / Intervalo.
Adicionamos uma nova coluna na Tabela
E aplicamos a nossa expressão:
List.Generate (
()=> [inicio = [DataEncomenda], fim = [DataEntrega]],
each [inicio] < [fim],
each [inicio = Date.AddDays([inicio], 1), fim = [fim]],
each [inicio]
)
Explicando a expressão:
- Valor inicial: é um registo composto por 2 campos:
- Inicio -> que armazena a data de encomenda [DataEncomenda]
- Fim -> que armazena a data de entrega [DataEntrega]
- Condição: É definida pelo operador: [inicio] < [fim]
- Next: Altera o valor do campo [inicio] pela função Date.AddDays e mantem o valor do campo [fim]
- Selector: Modifica a lista para apresentar um valor do registo -> [inicio]

A lista é gerada em cada célula da coluna. É uma lista aninhada.

Selecionamos a opção para extrair os valores da lista…

E obtemos a tabela com a informação dos dias que ocorrem entre as duas datas.

Próximo artigo:
Artigo Anterior:
Artigos por Categoria
- Microsoft Excel (44)
- Power Apps (16)
- Power Automate (3)
- Power BI (11)
- Power Query (14)
- Python (3)
- VBA (7)

Leave a Reply