Function Library

DAX

DAX Query

Palavras-chave de DAX Query e guia narrativo do DAX Query View no Power BI Desktop.

DAX Query View — Guia de Uso

DAX Query View — Guia de Uso

1. Como acessar

FerramentaComo acessar
Power BI DesktopPainel esquerdo → ícone de tabela com símbolo DAX (disponível desde novembro/2023)
Tabular Editor 3File → New → DAX Query, ou atalho de barra de ferramentas
DAX Studio (gratuito)File → Connect → Power BI Desktop → nova query
Power BI ServiceSemantic Model → DAX Query (Preview — requer workspace Premium/PPU)

Confirmado: o DAX Query View chegou ao Power BI Desktop em preview público no lançamento de novembro de 2023 (blog oficial do Power BI).

2. Barra de fórmulas vs. DAX Query View

AspectoBarra de FórmulasDAX Query View
ObjetivoDefinir medidas e colunasConsultar e explorar dados
RetornaEscalar (número, texto, data)Tabela (linhas e colunas)
Palavra-chaveSUM(tabela[col])EVALUATE + expressão de tabela
Testa contra dados?Só no visualDiretamente, com resultado real
Salva no modelo?Sim — a medida persisteNão — só para análise
Suporta DEFINE?NãoSim — variáveis e medidas temporárias
Ideal paraProdução — publicar métricasDesenvolvimento, debugging, documentação

3. Anatomia de uma query DAX

Uma query completa tem até 4 partes: DEFINE (opcional), EVALUATE (obrigatório), ORDER BY (opcional) e START AT (opcional):

DEFINE
    // Variáveis globais (disponíveis em todo o EVALUATE)
    VAR vDataInicio = DATE(2024, 1, 1)
    VAR vDataFim = DATE(2024, 12, 31)

    // Medida temporária (não salva no modelo)
    MEASURE fVendas[Fat Periodo] =
        CALCULATE(
            SUM(fVendas[Valor]),
            dCalendario[Data] >= vDataInicio &&
            dCalendario[Data] <= vDataFim
        )

    // Tabela temporária
    TABLE tRegioesSul =
        FILTER(dRegioes, dRegioes[Nome] = "Sul")

EVALUATE
    // A tabela a retornar (obrigatório)
    ADDCOLUMNS(
        VALUES(dProdutos[Categoria]),
        "Faturamento", [Fat Periodo]
    )
ORDER BY
    [Faturamento] DESC
START AT "Eletrônicos" // paginação: começar a partir deste valor

4. EVALUATE — a base de toda query

EVALUATE transforma qualquer expressão de tabela em resultado visível. Tudo que retorna tabela em DAX pode ser avaliado com ele:

// Retornar uma tabela inteira (com filtros do contexto)
EVALUATE dProdutos

// Valores distintos de uma coluna
EVALUATE VALUES(dProdutos[Categoria])

// Top-5 vendas por valor
EVALUATE
TOPN(5, fVendas, fVendas[Valor], DESC)

// Resumo com SUMMARIZE
EVALUATE
SUMMARIZE(
    fVendas,
    dProdutos[Categoria],
    "Total", SUM(fVendas[Valor])
)
ORDER BY [Total] DESC

// Múltiplos EVALUATE na mesma query (retorna múltiplas tabelas)
EVALUATE VALUES(dProdutos[Categoria])
EVALUATE VALUES(dRegioes[Nome])

5. DEFINE MEASURE — testar sem publicar

Cria medidas temporárias testáveis com dados reais, sem salvar no modelo — ideal para desenvolvimento iterativo:

DEFINE
    MEASURE fVendas[Ticket Medio Temp] =
        DIVIDE(SUM(fVendas[Valor]), COUNTROWS(fVendas), 0)

    MEASURE fVendas[Margem Bruta Temp] =
        DIVIDE(
            SUM(fVendas[Valor]) - SUM(fVendas[Custo]),
            SUM(fVendas[Valor]),
            0
        )

    MEASURE fVendas[Status Meta Temp] =
        IF([Ticket Medio Temp] > 1500, "Acima da Meta ✅", "Abaixo da Meta ❌")

EVALUATE
ADDCOLUMNS(
    VALUES(dVendedores[Nome]),
    "Ticket Médio", [Ticket Medio Temp],
    "Margem %", [Margem Bruta Temp],
    "Status", [Status Meta Temp]
)
ORDER BY [Ticket Médio] DESC

6. DEFINE VAR — variáveis globais na query

Variáveis em DEFINE ficam disponíveis em todo o bloco EVALUATE — diferente das VAR de medidas, que são locais à fórmula:

DEFINE
    VAR vMesAtual = 4       // Abril
    VAR vAnoAtual = 2024
    VAR vMetaGlobal = 50000 // R$50k de meta global
    VAR vTopN = 5

EVALUATE
TOPN(
    vTopN,
    ADDCOLUMNS(
        VALUES(dVendedores[Nome]),
        "Faturamento",
            CALCULATE(
                SUM(fVendas[Valor]),
                dCalendario[Mes] = vMesAtual,
                dCalendario[Ano] = vAnoAtual
            ),
        "Atingiu Meta",
            IF(
                CALCULATE(SUM(fVendas[Valor]),
                    dCalendario[Mes] = vMesAtual,
                    dCalendario[Ano] = vAnoAtual
                ) >= vMetaGlobal,
                "✅", "❌"
            )
    ),
    [Faturamento], DESC
)

7. DEFINE TABLE — tabelas temporárias

Cria tabelas disponíveis só durante a query, sem precisar de tabelas calculadas permanentes no modelo:

DEFINE
    TABLE tMetasManual =
        DATATABLE(
            "VendedorID", STRING,
            "MetaQ2", DOUBLE,
            {
                {"V-01", 45000},
                {"V-02", 38000},
                {"V-03", 52000},
                {"V-04", 41000}
            }
        )

EVALUATE
NATURALLEFTOUTERJOIN(
    ADDCOLUMNS(
        VALUES(fVendas[VendedorID]),
        "Faturamento", CALCULATE(SUM(fVendas[Valor]))
    ),
    tMetasManual
)

8. INFO Functions — documentação automática

As funções INFO.*/INFO.VIEW.* retornam metadados do modelo como tabelas DAX. Combinadas com EVALUATE, permitem gerar documentação automática do modelo:

// Inventário completo das tabelas
EVALUATE
SELECTCOLUMNS(
    INFO.VIEW.TABLES(),
    "Tabela", [Name],
    "Tipo", [StorageMode],
    "Oculta", [IsHidden],
    "Desc.", [Description]
)
ORDER BY [Tabela]

// Documentação automática de medidas
EVALUATE
SELECTCOLUMNS(
    INFO.VIEW.MEASURES(),
    "Medida", [Name],
    "Tabela", [TableName],
    "Pasta", [DisplayFolder],
    "Fórmula", [Expression],
    "Formato", [FormatString],
    "Oculta", [IsHidden]
)
ORDER BY [Tabela], [Pasta], [Medida]

Atenção: INFO.VIEW.MEASURES(), INFO.VIEW.TABLES(), INFO.VIEW.COLUMNS() e INFO.VIEW.RELATIONSHIPS() exigem permissão de Admin no workspace do Power BI Service. No Power BI Desktop local, funcionam sem restrição.

8.1 — Descrição de medida com /// (novidade jul/2026)

Desde a atualização de julho/2026 do Power BI Desktop, dá para documentar uma medida no próprio código, sem passar pelo Model Explorer — usando a mesma sintaxe de comentário /// que o TMDL já suporta para medidas e funções:

DEFINE
    /// Crescimento de vendas ano a ano, em percentual.
    /// Retorna BLANK() quando não há valor do ano anterior.
    MEASURE Sales[YoY Growth %] =
        DIVIDE(
            [Fat Ano Atual] - [Fat Ano Anterior],
            [Fat Ano Anterior]
        )

EVALUATE
ROW("YoY Growth %", FORMAT([YoY Growth %], "0.0%"))

Depois de escrever o comentário, executar Update model with changes (ou o CodeLens equivalente) grava a descrição direto na propriedade Description da medida no modelo — sem abrir o Model Explorer. A descrição passa a aparecer em 4 lugares: DAX Query View, Model Explorer, Data Pane e tooltip ao passar o mouse sobre a medida.

O que vale documentar em cada bloco ///: o que a medida calcula, regras de negócio relevantes (exclusões, filtros implícitos), quando retorna BLANK(), e em quais indicadores ela costuma aparecer. Descrições genéricas ("Calcula vendas", "Total") não ajudam ninguém — nem o próximo desenvolvedor, nem o Copilot, que lê essas descrições pra responder perguntas em linguagem natural sobre o modelo.

Confirmado: recurso validado contra learn.microsoft.com/en-us/ power-bi/transform-model/dax-query-view (atualizada jun/2026) e três fontes independentes do lançamento de julho/2026 — exemplo idêntico ao usado pela própria documentação oficial da Microsoft.

9. Debugando medidas complexas

O DAX Query View é a ferramenta de debug mais direta do Power BI — isole cada parte de uma medida complexa com DEFINE MEASURE em cadeia e veja o resultado de cada fragmento:

DEFINE
    MEASURE fVendas[Fat Base] = SUM(fVendas[Valor])
    MEASURE fVendas[Fat YTD] = TOTALYTD([Fat Base], dCalendario[Data])
    MEASURE fVendas[Fat YTD LY] =
        CALCULATE([Fat YTD], SAMEPERIODLASTYEAR(dCalendario[Data]))
    MEASURE fVendas[Variacao YoY] =
        DIVIDE([Fat YTD] - [Fat YTD LY], [Fat YTD LY], BLANK())
    MEASURE fVendas[Variacao YoY Fmt] =
        IF(ISBLANK([Variacao YoY]), "Sem dado LY", FORMAT([Variacao YoY], "0.0%"))

EVALUATE
ADDCOLUMNS(
    VALUES(dCalendario[Ano]),
    "Fat Base", [Fat Base],
    "Fat YTD", [Fat YTD],
    "Fat YTD LY", [Fat YTD LY],
    "Variação", [Variacao YoY Fmt]
)

Cada MEASURE intermediária isola uma etapa do cálculo — se o resultado final estiver errado, basta olhar em qual coluna o valor começa a divergir do esperado.

10. Referência rápida de sintaxe

CláusulaSintaxeObrigatório?
DEFINE VARDEFINE VAR x = <valor>Não
DEFINE MEASUREDEFINE MEASURE tabela[medida] = <fórmula>Não
DEFINE TABLEDEFINE TABLE t = <expressão de tabela>Não
EVALUATEEVALUATE <expressão de tabela>Sim (mínimo 1)
ORDER BYORDER BY <col> ASC|DESCNão
START ATSTART AT <valor>Não

11. Atalhos no DAX Query View (Power BI Desktop)

AtalhoAçãoStatus
F5 ou Ctrl+EnterExecutar a queryNão confirmado com fonte isolada — plausível
Shift+Alt+FFormatar a query automaticamente✅ Confirmado — Microsoft Learn
Ctrl+/Comentar/descomentar linha selecionada✅ Confirmado — Microsoft Learn
Ctrl+Alt+PAbrir paleta de comandos✅ Confirmado — Microsoft Learn
Ctrl+SpaceSugestões de autocomplete (IntelliSense)Não confirmado com fonte isolada — padrão comum de editores

Correção aplicada: o texto-fonte listava Ctrl+Shift+F para formatar a query — a documentação oficial do Microsoft Learn confirma que o atalho correto é Shift+Alt+F. Ctrl+Alt+P (paleta de comandos) não estava no texto-fonte e foi adicionado por já estar confirmado na doc oficial. O atalho Ctrl+K do livro-fonte ("adicionar ao modelo") não foi encontrado na documentação — a ação equivalente documentada é o botão/CodeLens "Update model with changes"; substituído por "não confirmado" em vez de publicado como fato.

Nota de curadoria e auditoria

Conteúdo técnico validado contra learn.microsoft.com/en-us/power-bi/transform-model/dax-query-view em 2026-08-05, e atualizado em 2026-08-07 com a seção 8.1 (descrições de medida com ///, novidade de julho/2026 — validada contra a página oficial da Microsoft e três fontes independentes de release notes). Uma correção real encontrada (atalho de formatação). As palavras-chave (DEFINE, MEASURE, TABLE, EVALUATE, ORDER BY, START AT) já estavam auditadas em 01-dax-guia-conteudo.md — este guia adiciona o contexto de uso e exemplos que a Biblioteca ainda não tinha, fechando a lacuna citada no arquivo principal do projeto. Seção de casos avançados com prompts de IA (validação de dados, diagnóstico de RLS, exportação de documentação) omitida desta curadoria por ser redundante com o Cookbook (26-dax-cookbook-casos-uso.md) e o Guia de Prompts (27-dax-guia-prompts.md) — quem quiser esse material pode reaproveitar diretamente do livro-fonte, seção 21.10-21.11.

Cookbook: SQL → DAX Query View (12 padrões)

Cookbook: SQL → DAX Query View (12 padrões)

MUST

  • Publicar as consultas 11 e 12 na versão corrigida (com SUMMARIZECOLUMNS), não na versão original do arquivo-fonte — ver seção 3.
  • Considerar promover a correção da seção 3 a uma 77ª regra de Boas Práticas na categoria "Expressões DAX" — nenhuma das 76 regras já auditadas (30-powerbi-melhores-praticas-conteudo.md) cobre este padrão especificamente.

AVOID

  • Não ensinar SUMMARIZE com colunas de extensão (SUMMARIZE(tabela, coluna, "Nome", expressão)) como se fosse equivalente neutro a SUMMARIZECOLUMNS — o dax.guide marca a função com selo de função depreciada, e a SQLBI recomenda parar de usar esse padrão especificamente para adicionar colunas (agrupamento puro continua OK).

Contexto: por que SQL → DAX Query View

Quem vem de SQL reconhece a lógica de SELECT/WHERE/GROUP BY/ ORDER BY, mas a sintaxe do DAX Query View é diferente o bastante para gerar hesitação. Os 12 padrões abaixo mostram a tradução direta, lado a lado.

1. Consultas simples — SELECT, ORDER BY, TOP, WHERE

1 — SELECT * :

SELECT * FROM TabFatVendasCamisetas;
EVALUATE
    TabFatVendasCamisetas

2/3/4 — ORDER BY (simples, múltiplas colunas, DESC):

SELECT * FROM TabFatVendasCamisetas
ORDER BY [Número da Nota Fiscal] ASC, [Item da Nota Fiscal] ASC;
EVALUATE
    TabFatVendasCamisetas
ORDER BY
    TabFatVendasCamisetas[Número da Nota Fiscal] ASC,
    TabFatVendasCamisetas[Item da Nota Fiscal] ASC

6 — WHERE com AND/IN:

SELECT * FROM TabFatVendasCamisetas
WHERE [Sigla do Tamanho] = 'EG' AND [Código da Modelagem] IN ('M', 'U');
EVALUATE
    FILTER(
        TabFatVendasCamisetas,
        TabFatVendasCamisetas[Sigla do Tamanho] = "EG" &&
        TabFatVendasCamisetas[Código da Modelagem] IN { "M", "U" }
    )

8 — TOP N com ORDER BY embutido:

SELECT TOP 100 * FROM TabFatVendasCamisetas ORDER BY Faturado DESC;
EVALUATE
    TOPN(100, TabFatVendasCamisetas, [Faturado], DESC)

9 — Paginação com START AT:

SELECT * FROM TabFatVendasCamisetas
WHERE [Número da Nota Fiscal] >= '008080'
ORDER BY [Número da Nota Fiscal];
EVALUATE
    TabFatVendasCamisetas
ORDER BY TabFatVendasCamisetas[Número da Nota Fiscal]
START AT "008080"

2. Agrupamento com medidas — o padrão recomendado

5 — GROUP BY com JOIN implícito (medidas do modelo):

SELECT c.[Ano], c.[Mês #], SUM(f.Camisetas) AS Camisetas, SUM(f.Faturado) AS Faturado
FROM TabFatVendasCamisetas f
JOIN TabDimCalendário c ON f.[Data Venda] = c.[Data]
GROUP BY c.[Ano], c.[Mês #]
ORDER BY c.[Ano], c.[Mês #];
EVALUATE
    SUMMARIZECOLUMNS(
        'TabDimCalendário'[Ano],
        'TabDimCalendário'[Mês #],
        "Camisetas", [Camisetas],
        "Faturado", [Faturado]
    )
ORDER BY
    'TabDimCalendário'[Ano],
    'TabDimCalendário'[Mês #]

7 — GROUP BY com WHERE (filtro como 3º argumento):

SELECT c.[Ano], c.[Mês #], SUM(f.Camisetas) AS [Camisetas EG, M&U], SUM(f.Faturado) AS [Faturado EG, M&U]
FROM TabFatVendasCamisetas f JOIN TabDimCalendário c ON f.[Data Venda] = c.[Data]
WHERE f.[Sigla do Tamanho] = 'EG' AND f.[Código da Modelagem] IN ('M', 'U')
GROUP BY c.[Ano], c.[Mês #] ORDER BY c.[Ano], c.[Mês #];
EVALUATE
    SUMMARIZECOLUMNS(
        'TabDimCalendário'[Ano],
        'TabDimCalendário'[Mês #],
        FILTER(
            TabFatVendasCamisetas,
            TabFatVendasCamisetas[Sigla do Tamanho] = "EG" &&
            TabFatVendasCamisetas[Código da Modelagem] IN { "M", "U" }
        ),
        "Camisetas EG, M&U", [Camisetas],
        "Faturado EG, M&U", [Faturado]
    )
ORDER BY
    'TabDimCalendário'[Ano],
    'TabDimCalendário'[Mês #]

10 — SELECT DISTINCT (agrupamento sem medida — uso seguro de SUMMARIZE):

SELECT DISTINCT [Nome da Estampa] FROM TabFatVendasCamisetas;
EVALUATE
    SUMMARIZE(
        'TabFatVendasCamisetas',
        'TabFatVendasCamisetas'[Nome da Estampa]
    )

SUMMARIZE sem colunas de extensão (só agrupamento, equivalente a SELECT DISTINCT) é o único uso considerado seguro pela SQLBI — nenhuma correção necessária aqui.

3. Correção — consultas 11 e 12 (SUMMARIZE com colunas de extensão)

O que o arquivo-fonte tinha (padrão desencorajado):

-- Consulta 11 original — NÃO recomendado
EVALUATE
    SUMMARIZE(
        'TabFatVendasCamisetas',
        'TabFatVendasCamisetas'[Nome da Estampa],
        "Camisetas", [Camisetas],
        "Faturado", [Faturado]
    )
    ORDER BY 'TabFatVendasCamisetas'[Nome da Estampa]

Por que corrigir: o dax.guide marca SUMMARIZE com selo de função depreciada. A SQLBI é direta sobre esse uso específico — adicionar colunas de agregação ("Nome", <expressão>) dentro de SUMMARIZE — recomendando SUMMARIZECOLUMNS como substituto padrão desde que a função existe. O problema não é SUMMARIZE em si (o uso só-agrupamento da consulta 10 continua correto), é especificamente a combinação com colunas de extensão.

Versão corrigida (consulta 11):

EVALUATE
    SUMMARIZECOLUMNS(
        'TabFatVendasCamisetas'[Nome da Estampa],
        "Camisetas", [Camisetas],
        "Faturado", [Faturado]
    )
ORDER BY 'TabFatVendasCamisetas'[Nome da Estampa]

Versão corrigida (consulta 12 — com filtro):

EVALUATE
    SUMMARIZECOLUMNS(
        'TabFatVendasCamisetas'[Nome da Estampa],
        FILTER(
            TabFatVendasCamisetas,
            TabFatVendasCamisetas[Sigla do Tamanho] = "EG" &&
            TabFatVendasCamisetas[Código da Modelagem] IN { "M", "U" }
        ),
        "Camisetas EG, M&U", [Camisetas],
        "Faturado EG, M&U", [Faturado]
    )
ORDER BY 'TabFatVendasCamisetas'[Nome da Estampa]

Atenção a uma diferença semântica real, não só de sintaxe: SUMMARIZECOLUMNS exclui automaticamente grupos onde todas as medidas retornam BLANK — diferente de SUMMARIZE, que mantém a linha mesmo com agregação vazia. Para os casos deste cookbook (medidas de contagem/soma sobre uma tabela fato filtrada) o comportamento tende a coincidir na prática, mas vale testar contra os dados reais antes de substituir em relatórios de produção — não é uma troca 100% transparente em todo cenário.

4. Sugestão: nova regra de Boas Práticas

Nenhuma das 76 regras já auditadas em 30-powerbi-melhores-praticas- conteudo.md cobre "evitar colunas de extensão em SUMMARIZE" — a regra mais próxima (USE_THE_TREATAS_FUNCTION_INSTEAD_OF_INTERSECT) é sobre outro par de funções. Proposta de nova regra, categoria "Expressões DAX":

CampoValor
TítuloEvite colunas de extensão em SUMMARIZE — use SUMMARIZECOLUMNS
Severidade sugeridaMédia (segue o padrão de AVOID_DUPLICATE_MEASURES/USE_THE_DIVIDE_FUNCTION, mesma família de "existe alternativa melhor, não é erro fatal")
O quêSUMMARIZE com colunas de extensão ("Nome", <expressão>) é uma função marcada como depreciada; a alternativa recomendada é SUMMARIZECOLUMNS
Quando usar SUMMARIZE aindaApenas para agrupamento puro, sem colunas de extensão — equivalente a SELECT DISTINCT, esse uso continua correto
Fontedax.guide/summarize (selo de depreciação) + SQLBI "Best practices using SUMMARIZE and ADDCOLUMNS" + SQLBI "All the secrets of SUMMARIZE"

Nota de validação

As 12 consultas foram checadas contra sqlbi.com/articles/best- practices-using-summarize-and-addcolumns, sqlbi.com/articles/all-the- secrets-of-summarize e dax.guide/summarize em 2026-08-06. 10 das 12 já seguiam o padrão recomendado; 2 (consultas 11 e 12) usavam SUMMARIZE com colunas de extensão — corrigidas para SUMMARIZECOLUMNS nesta versão, com nota sobre a diferença semântica de tratamento de grupos vazios.

Esquema de Cores da Barra de Fórmulas DAX — Confirmado

Esquema de Cores da Barra de Fórmulas DAX — Confirmado

MUST

  • Usar os valores desta tabela (medidos), não os do livro-fonte, onde houver divergência — a medição direta é mais confiável que a transcrição do livro.
  • Tratar "Erro" como não confirmado nesta rodada — não foi possível gerar um erro real na captura sem comprometer o exemplo didático da medida usada para o teste.

AVOID

  • Não publicar a cor de erro (#FF444E, citada pelo livro) como confirmada — segue como pendência até haver uma captura real com erro de sintaxe.

1. Tabela de cores confirmada

CategoriaHex confirmadoExemplo no testeFonte
Comentário#008000// Medida didática...Medido (livro citava #007B00 — próximo, diferença mínima)
Palavra-chave (VAR, RETURN)#0000FFVAR, RETURNMedido — livro não distinguia palavra-chave de função
Função (CALCULATE, SUM, SWITCH, IF, TRUE, ISBLANK, BLANK, FORMAT, DIVIDE, ROW, DATE, UNION, SAMEPERIODLASTYEAR)#3165BBCALCULATE(, SUM(Medido = confirma o livro exatamente (#3165BB, "azul lápis")
Variável (v...)#008080vTotalVendas, vClassificacaoMedido — livro não tinha esta categoria
String / texto entre aspas#A31515"Crescimento forte", "M"Medido — livro não tinha esta categoria
Número#0986582025, 120.00, 0.15Medido (2 amostras independentes, mesmo valor)
Referência de tabela/coluna ('Tabela'[Coluna])#001080'TabFatVenda'[ValorVenda]Medido — livro não tinha esta categoria
Operador (= <> >= < - & &&)#000000<>, &, >=Medido = confirma o livro ("texto padrão")
Erro#FF444E (não confirmado nesta rodada)Só o livro — pendente captura com erro real

2. Achado relevante: função ≠ palavra-chave

O livro-fonte tratava "funções" como categoria única. A medição real mostra uma distinção que o livro não capturava: palavras-chave verdadeiras da linguagem (VAR, RETURN) usam um azul puro diferente (#0000FF) do azul usado por funções (CALCULATE, IF, SWITCH etc., #3165BB) — mesmo quando a função tem comportamento de estrutura de controle (IF, SWITCH). Isso é coerente com a própria linguagem DAX: VAR/RETURN são palavras reservadas da sintaxe; IF/SWITCH são, tecnicamente, funções.

3. Metodologia (para repetir se necessário)

  1. Localizar a banda de pixels y de cada linha de código (detecção por atividade de pixel não-branco).
  2. Recortar e ampliar a região com uma régua de coordenadas sobreposta (grade vermelha a cada 20px) para localizar o x de cada token visualmente.
  3. Amostrar uma caixa de pixels centrada no token, contar frequência de cor, descartar branco de fundo (#FFFFFF/quase-branco) e picos de anti-aliasing de borda.
  4. Cross-validar cada categoria em pelo menos 2 ocorrências independentes antes de aceitar o valor (aplicado a função, número, string e variável).

4. Pendência remanescente

  • Cor de erro (#FF444E no livro): precisa de uma nova captura com um erro de sintaxe real (ex.: CALCULAT( faltando uma letra) para confirmar — não incluído nesta rodada por decisão de manter a medida de teste sintaticamente correta.