Power Fx: fórmulas essenciais do Power Apps
Power Fx é a linguagem do Power Apps. Conheça as fórmulas essenciais como Filter, LookUp, Patch, Collect e Set, e entenda a delegação e a performance.
Seu app trava, some dados ou fica lento, e quase sempre a causa é a fórmula errada
Quando um app de Power Apps entrega o registro errado, deixa a galeria vazia sem motivo aparente ou fica lento com poucos milhares de linhas, a culpa raramente é da plataforma. É da fórmula. O Power Fx é a linguagem de baixo código do Power Apps, declarativa e baseada em expressões, no mesmo espírito das fórmulas do Excel: você descreve o resultado que quer e a plataforma recalcula sozinha quando algo muda. Isso é ótimo para produtividade e péssimo para quem escreve fórmula no chute, porque um erro sutil de delegação ou de escopo de variável só aparece em produção, com o volume real de dados.
Neste artigo eu vou direto às fórmulas que aparecem em praticamente todo app que a gente entrega nos projetos de Power Platform da Fynx: Filter, Search e LookUp para consultar; Patch e Collect para gravar; Set e UpdateContext para variáveis; If e Switch para lógica; Navigate para navegação; e a delegação, que é o conceito que separa um app que escala de um que quebra. Se você quer o panorama completo da plataforma antes de mergulhar aqui, vale ler o nosso guia de Power Apps e Power Automate 2026.
O Power Fx é declarativo, e isso muda como você pensa
Antes das funções, um ajuste de mentalidade. Diferente de linguagens imperativas, no Power Fx você não escreve "faça isto, depois aquilo" em sequência rígida. Você declara expressões que recalculam automaticamente quando as dependências mudam, exatamente como uma célula de Excel se atualiza quando você altera outra. A propriedade Items de uma galeria não é executada uma vez: ela é reavaliada sempre que algo que ela referencia muda.
Na prática, isso significa que boa parte da lógica do app vive dentro de propriedades de controles, não em blocos de código soltos. As poucas ações que realmente disparam efeitos colaterais, gravar um registro, navegar, definir uma variável, ficam em propriedades de evento como OnSelect. Guardar essa diferença evita metade dos erros de quem vem de programação tradicional.
Filter, Search e LookUp são como você consulta dados
Essas três funções lêem dados de uma fonte (Dataverse, SharePoint, SQL, uma coleção) e cada uma resolve um problema diferente. Confundir as três é o erro número um de quem está começando.
| Função | O que faz | Retorna | Quando usar |
|---|---|---|---|
Filter | Devolve todos os registros que atendem a uma ou mais condições | Uma tabela | Listar vários registros por critério exato |
Search | Procura um texto dentro de colunas específicas | Uma tabela | Caixa de busca livre digitada pelo usuário |
LookUp | Devolve o primeiro registro que atende à condição | Um único registro (ou um campo) | Buscar um valor pontual, como um preço |
Filter é o feijão com arroz das galerias. Você passa a fonte e as condições, e ele devolve a tabela filtrada:
Filter(
Vendas,
Status = "Aberto" && Valor > 1000
)
Search foi feito para o campo de busca. Ele varre as colunas que você indicar procurando o texto digitado, sem você precisar montar if de coluna em coluna:
Search(
Clientes,
txtBusca.Text,
"Nome",
"Email",
"Cidade"
)
LookUp é para quando você quer um registro só, ou até um único campo dele. Repare que o terceiro argumento é opcional: se você informar uma coluna, ele devolve só aquele valor em vez do registro inteiro.
LookUp(
Produtos,
Codigo = "SKU-042",
Preco
)
A regra prática: se o resultado alimenta uma galeria, é Filter ou Search. Se você quer um valor pontual para uma variável ou um rótulo, é LookUp.
Patch e Collect são como você grava e manipula dados
Consultar é a metade fácil. Gravar é onde os apps de verdade acontecem, e aqui entram duas funções que fazem coisas bem diferentes.
Patch grava registros na fonte de dados. É a função que cria e atualiza. Para criar um registro novo, você combina Patch com Defaults, que gera um registro em branco da tabela:
Patch(
Chamados,
Defaults(Chamados),
{
Titulo: txtTitulo.Text,
Prioridade: drpPrioridade.Selected.Value,
Status: "Novo"
}
)
Para atualizar um registro existente, você passa o registro no lugar de Defaults e só as colunas que quer mudar. As demais permanecem intactas:
Patch(
Chamados,
galChamados.Selected,
{ Status: "Concluído" }
)
Patch é preferível ao antigo SubmitForm quando você precisa de controle fino, gravar em várias tabelas de uma vez ou salvar sem depender de um controle de formulário na tela. É a ferramenta que a gente usa na maioria dos apps de campo e de aprovação.
Collect faz outra coisa: cria e alimenta coleções em memória, ou seja, tabelas temporárias que vivem no dispositivo enquanto o app está aberto. Serve para carrinho de compras, seleção múltipla, cache de dados para trabalhar offline e montagem de listas antes de gravar tudo de uma vez.
Collect(
colCarrinho,
{ Produto: "Teclado", Qtd: 2, Preco: 120 }
)
Na prática, você quase sempre vai usar ClearCollect, que limpa a coleção antes de preencher. É o padrão para recarregar dados sem duplicar linhas:
ClearCollect(
colProdutos,
Filter(Produtos, Ativo = true)
)
A distinção que importa: Patch persiste na fonte, sobrevive ao fechamento do app. Collect vive só em memória, some quando o app fecha, a menos que você use SaveData para guardar localmente. Coleção não é banco de dados.
Set e UpdateContext definem variáveis com escopos diferentes
Variáveis no Power Fx têm escopo, e escolher o errado gera bugs difíceis de rastrear. Existem duas famílias principais.
Set define variáveis globais, visíveis em todas as telas do app. Use para dados que precisam viajar entre telas: o usuário logado, o item selecionado, um tema, uma flag de permissão.
Set(gblUsuario, User().FullName)
UpdateContext define variáveis de contexto, que existem apenas dentro da tela onde foram criadas. Use para estado local: um indicador de "carregando", a visibilidade de um painel, um valor temporário que não faz sentido fora daquela tela.
UpdateContext({ locCarregando: true })
| Recurso | Set (global) | UpdateContext (contexto) |
|---|---|---|
| Escopo | O app inteiro | Somente a tela atual |
| Sintaxe | Set(nome, valor) | UpdateContext({ nome: valor }) |
| Uso típico | Usuário, tema, item entre telas | Estado local, flags de UI |
| Passa para outra tela | Sim, direto | Não, só via Navigate |
A boa prática que a gente segue: use variável de contexto por padrão e só suba para global quando o dado realmente precisar cruzar telas. Encher o app de variáveis globais que só uma tela usa polui o estado e dificulta a manutenção. E uma convenção de nomes ajuda muito: prefixe globais com gbl e contextos com loc, para bater o olho e saber o escopo.
If e Switch controlam o fluxo da lógica
Toda lógica condicional passa por essas duas. If avalia condições e devolve valores diferentes conforme o resultado. Ele aceita vários pares de condição e valor, funcionando como um encadeamento de "se, senão se":
If(
Valor > 10000, "Aprovação da diretoria",
Valor > 1000, "Aprovação do gestor",
"Aprovação automática"
)
Switch compara uma única expressão contra vários valores possíveis. Quando você está testando o mesmo campo contra uma lista de opções, Switch fica muito mais legível que um If gigante:
Switch(
drpStatus.Selected.Value,
"Aberto", Color.Green,
"Pendente", Color.Orange,
"Fechado", Color.Gray,
Color.Black
)
A regra: use If quando as condições são diferentes entre si (um compara valor, outro compara data, outro compara texto). Use Switch quando você compara a mesma coisa contra vários valores. O último argumento do Switch, sem par, é o valor padrão, o equivalente ao "senão".
Navigate move o usuário entre telas
Navigate troca a tela ativa do app e, de quebra, permite passar dados para a tela de destino. O segundo argumento controla a transição visual, e o terceiro, opcional, envia um contexto para a próxima tela:
Navigate(
TelaDetalhe,
ScreenTransition.Cover,
{ locItemSelecionado: galItens.Selected }
)
Esse terceiro argumento é a forma limpa de passar o registro selecionado de uma galeria para uma tela de detalhe, sem depender de variável global. Na tela de destino, você referencia locItemSelecionado normalmente. Para voltar à tela anterior sem empilhar navegação, use Back(), que também respeita a transição de origem.
A delegação decide o que escala e o que quebra
Guardei o conceito mais importante para o final, porque é o que mais derruba app em produção. Delegação é a capacidade do Power Fx de enviar o processamento para a fonte de dados em vez de trazer tudo para o dispositivo. Quando uma função é delegável para aquela fonte, o filtro roda no servidor e só o resultado volta. Quando não é delegável, o app baixa um lote de registros, limitado pelo teto de linhas para dados não delegáveis (o padrão é 500, configurável até 2000), e processa localmente.
O perigo é silencioso. Com 300 registros de teste, tudo funciona. Em produção, com 50 mil linhas, uma função não delegável enxerga apenas as primeiras 500 e devolve resultado errado, sem erro vermelho, apenas dados faltando. O editor sinaliza isso com um aviso de delegação (o triângulo azul), e ignorar esse aviso é apostar contra o volume futuro.
O que é delegável depende da combinação entre a função, o operador e a fonte de dados. As regras mudam entre Dataverse, SharePoint e SQL Server, então sempre confira a documentação da sua fonte. Ainda assim, alguns padrões se repetem:
| Situação | Delegável na maioria das fontes? |
|---|---|
Filter com =, >, <, <=, >= em coluna simples | Sim |
LookUp com condição simples | Sim |
Search em texto | Depende da fonte |
Filter usando a função Search dentro dele | Frequentemente não |
| Operações sobre uma coleção em memória | Não se aplica, roda local |
Funções como Sum, Sort sobre a fonte | Varia bastante por fonte |
Estratégias que a gente aplica para conviver com o limite: reduza o conjunto primeiro com um filtro delegável no servidor e só depois aplique a lógica que não delega; prefira colunas e operadores que a fonte suporta; e, quando o volume é grande e a consulta é complexa, mova o processamento pesado para a camada de dados, com uma view em SQL ou um fluxo de dados. Esse é justamente o ponto onde app e engenharia de dados se encontram: modelar bem a fonte resolve o que nenhuma fórmula esperta resolve na tela. Você encontra exemplos desse tipo de solução no nosso portfólio de soluções.
Tabela de referência das fórmulas essenciais
Para consulta rápida, o resumo do que cada função faz e o cenário típico de uso:
| Função | Categoria | Para que serve |
|---|---|---|
Filter | Consulta | Retornar vários registros por critério |
Search | Consulta | Busca livre por texto em colunas |
LookUp | Consulta | Retornar um registro ou campo único |
Patch | Gravação | Criar ou atualizar registros na fonte |
Collect / ClearCollect | Gravação | Criar e alimentar coleções em memória |
Set | Variável | Definir variável global entre telas |
UpdateContext | Variável | Definir variável de contexto na tela |
If | Lógica | Condições diferentes entre si |
Switch | Lógica | Mesma expressão contra vários valores |
Navigate | Navegação | Trocar de tela e passar contexto |
Perguntas frequentes
Power Fx é uma linguagem de programação de verdade? Sim, com uma característica marcante: é declarativa e baseada em expressões, no modelo das fórmulas do Excel, e não imperativa como C# ou JavaScript. Você descreve resultados, e a plataforma recalcula automaticamente quando as dependências mudam. É baixo código, mas tem tipos, funções, tabelas e registros como estruturas de primeira classe.
Qual a diferença entre Set e UpdateContext na prática?
Set cria variáveis globais, acessíveis em todas as telas do app, ideais para dados que precisam viajar, como o usuário logado. UpdateContext cria variáveis de contexto, que só existem dentro da tela atual, ideais para estado local de interface. A recomendação é usar contexto por padrão e reservar global para o que realmente cruza telas.
Quando usar Patch em vez de SubmitForm?
Use Patch quando precisa de controle fino: gravar em várias tabelas, salvar sem um controle de formulário na tela, atualizar só algumas colunas de um registro ou montar a gravação a partir de fontes diferentes. SubmitForm é conveniente quando você tem um formulário simples e padrão amarrado a uma única fonte.
Coleção criada com Collect fica salva depois que fecho o app?
Não. Collect cria tabelas em memória que existem só durante a sessão e desaparecem quando o app fecha. Para persistir localmente no dispositivo, use SaveData e recupere com LoadData. Para persistir de verdade na fonte de dados, é Patch ou SubmitForm. Coleção não substitui banco de dados.
O que é o aviso de delegação e por que não devo ignorá-lo? É o triângulo azul que o editor mostra quando uma fórmula não pode ser processada na fonte de dados e vai rodar localmente, respeitando o limite de linhas para dados não delegáveis (500 por padrão, até 2000). Ignorar significa correr o risco de o app enxergar só uma parte dos registros em produção e devolver resultados incompletos, sem nenhum erro visível.
Como aumentar o limite de linhas para dados não delegáveis resolve o problema? Ajuda pouco e mascara a causa. Você pode elevar o teto até 2000 nas configurações do app, mas isso não torna a função delegável: apenas amplia o lote trazido para o dispositivo, o que ainda pesa na performance e continua ignorando registros acima do teto. A solução correta é reescrever a fórmula para ser delegável ou mover o processamento para a fonte.
Domine essas funções e o resto vira detalhe
Filter, Search, LookUp, Patch, Collect, Set, UpdateContext, If, Switch e Navigate cobrem a espinha dorsal de quase todo app de Power Apps, e a delegação é o fio invisível que decide se ele vai escalar. Escrever bem essas fórmulas é a diferença entre um app que resolve o problema no dia a dia e um protótipo que trava no primeiro mês de uso real.
Se você quer tirar um app do papel ou resgatar um que ficou lento e cheio de gambiarras, fale com a gente. A gente faz isso todos os dias.
Quer aplicar isso na sua empresa?
A Fynx implementa BI, Power BI e Power Platform de ponta a ponta. Conte seu cenário e devolvemos um diagnóstico direto ao ponto.
Falar com um especialista