Function Library

DAX

Code Library DAX

Biblioteca de UDFs DAX documentadas na Function Library — Business.* e DateTime.Calendar — com assinatura, parâmetros e exemplo de uso.

Code Library — Biblioteca de UDFs DAX (DataHora, Delta, Estatistica)

Code Library — Biblioteca de UDFs DAX (DataHora, Delta, Estatistica)

Nota de integração

Este material é 100% DAX — nenhum dos três arquivos-fonte (Biblioteca_de_Funções...html, Consulta_DAX.txt, Script_TMDL.txt) contém função M ou código Power Query. Não há nada a incorporar na seção M da Biblioteca a partir desta fonte.

O conteúdo abaixo se conecta diretamente a 07-dax-udf-tipos-parametro-conteudo.md (já auditado) — enquanto aquele arquivo documenta o sistema de tipos de parâmetro de UDF em abstrato, este documenta uma biblioteca real, testada e em produção usando esses tipos. Recomenda-se publicar como subseção /dax/udf/biblioteca ou como bloco de exemplos dentro da própria página de UDF.

MUST

  • Publicar Requisito mínimo = Setembro/2025 ou superior, não Março/2025 — ver correção na seção 1.
  • Manter a documentação do namespace Estatistica — ele existe no código-fonte mas não estava no manual HTML v1.0.0 (que só documentava DataHora e Delta). Esta página corrige essa lacuna de versão.
  • Creditar a biblioteca como conteúdo autoral do projeto (OfficeTuning), não de terceiros — diferente das funções DAX nativas, aqui a Biblioteca é a única fonte de verdade.

AVOID

  • Não republicar o aviso de direitos autorais completo do documento original (é redundante com os termos já definidos para o projeto) — uma nota de autoria simples basta.

1. Correção — requisito mínimo de plataforma

O manual original lista Março/2025 ou superior como requisito para o recurso DEFINE FUNCTION (preview). Isso está incorreto. Múltiplas fontes independentes confirmam que DAX UDFs entraram em preview em setembro de 2025 (16/set/2025, conforme blog de Andrzej Leszkiewicz, Power BI Developer/MVP, publicado no dia do lançamento; confirmado também por artigo da mesma época na Medium). GA (disponibilidade geral) veio em junho/2026 — já registrado em 01-dax-guia-conteudo.md.

Manual originalCorrigido
Requisito mínimoPower BI Desktop, Março/2025 ou superiorPower BI Desktop, Setembro/2025 ou superior (preview) / Junho/2026 (GA)

2. Visão geral da biblioteca (corrigida — 3 namespaces, 11 funções)

NamespaceCategoriaFunçõesDescrição
DataHoraCalendário / Tempo2Geração de tabela calendário completa com dimensões gregoriana, fiscal e ISO 8601
DeltaComparativos temporais6Variação absoluta, percentual, ícone e cor semântica vs. ano anterior
EstatisticaEstatística descritiva3Coeficiente de Variação e classificação de confiabilidade da média

3. Biblioteca DataHora

⚠️ Atualizado (2026-08-08): a fonte real do Code Library já renomeou este escopo para DateTime (não DataHora) e a versão atual da função é significativamente mais rica (mais colunas: estação com cor/emoji, ano fiscal com convenção "rotulado pelo ano em que termina", etc.). Ver 50-dax-code-library-business-datetime-novidades.md para a versão completa e atual — a assinatura abaixo (DataHora.Calendario) é a versão anterior, mantida aqui só como registro histórico.

DataHora.Calendario(StartDate, EndDate, Locale, FirstDay, FiscalYearStartMonth) — ⚠️ ver nota acima, use DateTime.Calendar

Gera uma tabela de datas com 28 colunas analíticas — gregoriano, semana, quinzena, ISO 8601 e calendário fiscal parametrizado.

FUNCTION DataHora.Calendario =
    (
        StartDate            : SCALAR DATETIME VAL,
        EndDate               : SCALAR DATETIME VAL,
        Locale                : SCALAR STRING,
        FirstDay              : SCALAR INT64 VAL,
        FiscalYearStartMonth  : SCALAR INT64 VAL
    ) =>

    VAR vCalendario =
        SELECTCOLUMNS(
            CALENDAR(StartDate, EndDate),
            "Data Referência", [Date]
        )

    RETURN
        ADDCOLUMNS(
            vCalendario,
            "Ano", YEAR([Data Referência]),
            "Semestre #", IF(MONTH([Data Referência]) <= 6, 1, 2),
            "Trimestre #", QUARTER([Data Referência]),
            "Mês #", MONTH([Data Referência]),
            "Mês", FORMAT([Data Referência], "MMMM", Locale),
            "Semana #", WEEKNUM([Data Referência], FirstDay),
            "Dia da Semana", FORMAT([Data Referência], "dddd", Locale),
            "Semana ISO #", WEEKNUM([Data Referência], 21),
            "Ano ISO", YEAR([Data Referência] - (WEEKDAY([Data Referência], 2) - 4)),
            "Mês Fiscal #", MOD(MONTH([Data Referência]) - FiscalYearStartMonth + 12, 12) + 1,
            "Ano Fiscal #", YEAR([Data Referência]) + IF(MONTH([Data Referência]) >= FiscalYearStartMonth, 1, 0)
            -- + 18 colunas adicionais (ver código-fonte completo)
        )

Parâmetros

ParâmetroTipoDescrição
StartDateSCALAR DATETIME VALData de início (inclusive)
EndDateSCALAR DATETIME VALData de fim (inclusive)
LocaleSCALAR STRINGCódigo IETF BCP 47 ("pt-BR", "en-US") — controla nomes de mês/dia
FirstDaySCALAR INT64 VALPrimeiro dia da semana para WEEKNUM/WEEKDAY — ver tabela §3.1
FiscalYearStartMonthSCALAR INT64 VALMês de início do ano fiscal (1-12)

Retorno: TABLE — uma linha por dia, 28 colunas.

Validação técnica:

  • Tabela de valores de FirstDay/WEEKNUM — ✅ confirmada exatamente contra dax.guide/weeknum: 1=domingo, 2=segunda, 11=segunda (1ª convenção ISO-like), 12=terça, 21=ISO 8601 real (semana da primeira quinta-feira do ano).
  • Algoritmo de "Ano ISO" (YEAR(data - (WEEKDAY(data,2)-4))) — ✅ confirmado como o método padrão e correto de cálculo de ano-semana ISO 8601 (método da quinta-feira).

3.1 — Valores de FirstDay

ValorPrimeiro dia da semana
1Domingo
2Segunda-feira
11Segunda-feira (1ª convenção ISO-like)
12Terça-feira
21Segunda-feira — ISO 8601 real (semana da 1ª quinta-feira do ano)

DataHora.Sobre()

Retorna metadados da biblioteca (nome, autor, versão, funções, exemplo) como string multilinha — padrão de autodocumentação usado em todos os 3 namespaces desta Code Library.

4. Biblioteca Delta

Cinco funções encadeáveis para análise de variação temporal: Delta.AADelta.Absoluto / Delta.PercentualDelta.Info / Delta.Cor.

FUNCTION Delta.AA =
    (Valor: ANYREF) =>
    CALCULATE(
        Valor,
        SAMEPERIODLASTYEAR('TabDimCalendario'[Data Referência])
    )

FUNCTION Delta.Absoluto =
    (Valor: ANYREF, ValorAA: ANYREF) =>
    IF(
        ISBLANK(Valor) || ISBLANK(ValorAA),
        BLANK(),
        Valor - ValorAA
    )

FUNCTION Delta.Percentual =
    (Valor: ANYREF, ValorAA: ANYREF) =>
    IF(
        ISBLANK(Valor) || ISBLANK(ValorAA),
        BLANK(),
        DIVIDE(Valor - ValorAA, ValorAA)
    )

FUNCTION Delta.Info =
    (ValorDeltaPercentual: ANYREF) =>
    SWITCH(
        TRUE(),
        ISBLANK(ValorDeltaPercentual), BLANK(),
        ValorDeltaPercentual > 0, "▲",
        ValorDeltaPercentual = 0, "■",
        "▼"
    )

FUNCTION Delta.Cor =
    (ValorDeltaPercentual: ANYREF) =>
    SWITCH(
        TRUE(),
        ISBLANK(ValorDeltaPercentual), BLANK(),
        ValorDeltaPercentual > 0, "#1AAB40",
        ValorDeltaPercentual = 0, "#D9B300",
        "#D64554"
    )

Dependência: todas as funções Delta.* exigem uma tabela de datas chamada TabDimCalendario (coluna [Data Referência]), marcada como tabela de datas e relacionada às tabelas fato.

Exemplo de uso encadeado:

Δ Vendas AA    = Delta.AA([Total Vendas])
Δ Vendas %     = Delta.Percentual([Total Vendas], [Δ Vendas AA])
Δ Vendas Info  = Delta.Info([Δ Vendas %])
Δ Vendas Cor   = Delta.Cor([Δ Vendas %])

4.1 — Sugestão de evolução: ANYREF → MEASUREREF

Todos os 5 parâmetros Valor/ValorAA/ValorDeltaPercentual usam ANYREF, mas na prática são sempre chamados com referência direta a medida (Delta.AA([Total Vendas])). Pela regra prática já documentada em 07-dax-udf-tipos-parametro-conteudo.md ("use o tipo mais específico que a função realmente precisa"), esses parâmetros são candidatos naturais para MEASUREREF:

// Versão atual (ANYREF — aceita qualquer expressão):
FUNCTION Delta.AA = (Valor: ANYREF) => ...

// Versão sugerida (MEASUREREF — só aceita medida existente):
FUNCTION Delta.AA = (Valor: MEASUREREF) => ...

Ganho: validação de tipo em tempo de design (erro claro se alguém passar uma expressão em vez de medida) e garantia automática de transição de contexto, sem depender de CALCULATE defensivo. Custo: nenhum uso legítimo é perdido, já que todos os exemplos do manual já chamam essas funções só com medidas. Não é uma correção — é uma sugestão de reforço de tipo, opcional.

5. Biblioteca Estatistica

Não documentada no manual HTML v1.0.0 — presente apenas no código-fonte (Consulta_DAX.txt, Script_TMDL.txt). Documentada aqui pela primeira vez.

FUNCTION Estatistica.CV =
    (DesvioPadrao: NUMERIC, Media: NUMERIC) =>
    DIVIDE(DesvioPadrao, Media)

FUNCTION Estatistica.ClassificarCV =
    (CV: NUMERIC) =>
    SWITCH(
        TRUE(),
        ISBLANK(CV), BLANK(),
        CV <= 0.15, "Dados concentrados, média confiável.",
        CV <= 0.30, "Variação moderada, use com atenção.",
        "A média não representa o grupo. Troque para a mediana."
    )

Estatistica.CV(DesvioPadrao, Media) — Coeficiente de Variação (σ/μ), validado como a definição estatística padrão. Retorna decimal (0,15 = 15%).

Estatistica.ClassificarCV(CV) — interpreta o CV em 3 faixas: ≤15% (dados concentrados), ≤30% (variação moderada), >30% (média não representativa, sugere usar mediana). Os limiares (15%/30%) são convenção comum em estatística descritiva, não um padrão universal único — vale nota na página de que são um critério prático, ajustável por domínio.

Exemplo de uso:

VAR vCV = Estatistica.CV([Desvio Padrão], [Média])
RETURN Estatistica.ClassificarCV(vCV)

Aviso do autor preservado: evitar Estatistica.CV quando a média for igual ou próxima de zero (DIVIDE retorna BLANK() nesse caso, mas a métrica perde sentido interpretativo mesmo sem erro técnico).

6. Referências originais (preservadas do manual)

#RecursoURL
1DAX function referencelearn.microsoft.com/pt-br/dax/dax-function-reference
2CALENDAR functionlearn.microsoft.com/pt-br/dax/calendar-function-dax
3SAMEPERIODLASTYEAR functionlearn.microsoft.com/pt-br/dax/sameperiodlastyear-function-dax
4WEEKNUM functionlearn.microsoft.com/pt-br/dax/weeknum-function-dax
5FORMAT function (DAX)learn.microsoft.com/pt-br/dax/format-function-dax
6DEFINE FUNCTION — DAX Querylearn.microsoft.com/pt-br/dax/define-function-statement
7Marcar como tabela de dataslearn.microsoft.com/pt-br/power-bi/transform-model/desktop-date-tables
8ISO 8601 — Week dateiso.org/iso-8601-date-and-time-format.html

7. Resumo de correções aplicadas

ItemOriginalCorrigido
Requisito mínimo de plataformaMarço/2025Setembro/2025 (preview) / Junho/2026 (GA)
Namespace EstatisticaAusente do manual v1.0.0Documentado nesta versão (seção 5)
Tipo dos parâmetros Delta.*ANYREF (sem alteração de código)Sugestão de evolução para MEASUREREF registrada (seção 4.1), não aplicada ao código-fonte

8. Onde entra na navegação

Sugestão: /dax/udf/biblioteca — subseção da página de UDF (/dax/udf) já existente, apresentando esta Code Library como exemplo real de aplicação dos tipos de parâmetro documentados ali. Alternativa: seção própria /dax/code-library se o projeto paralelo "Code Library" crescer para incluir mais bibliotecas além de DataHora/Delta/ Estatistica.

Code Library — Extensão Utilitários + Cookbook Adicional

Code Library — Extensão Utilitários + Cookbook Adicional

MUST

  • Publicar a versão corrigida do bloco EVALUATE ROW de teste (seção 1.9) — 2 das 12 chamadas referenciam nomes de função que não existem no DEFINE, e falhariam em tempo de execução.
  • Resolver a duplicação Holidays.GoodFriday / Date.Holidays.GoodFriday antes de publicar — são duas funções idênticas com nomes diferentes (ver seção 1.8).

AVOID

  • Não publicar DATE.YEARLABEL(...) nem DATE.QUARTER(...) como exemplos de chamada — essas funções não existem; os nomes corretos são Date.FiscalYearLabel e Date.FiscalQuarter.

1. Namespace Utilitários — funções novas

1.1 — String.FormatWithLeadingZeros(pNumero, pNumeroDeCaracteres)

Formata um número inteiro com zeros à esquerda até o comprimento desejado.

FUNCTION String.FormatWithLeadingZeros =
    (pNumero: int64 val, pNumeroDeCaracteres: int64 val) =>
    VAR vNumero = ABS(pNumero)
    VAR vNumeroDeCaracteres = MAX(1, ABS(pNumeroDeCaracteres))
    RETURN
        FORMAT(vNumero, REPT("0", vNumeroDeCaracteres))

ABS(pNumero) descarta o sinal antes de formatar — evita "-042" inesperado; MAX(1, ...) garante ao menos 1 caractere mesmo se o chamador passar 0 ou negativo. Exemplo: String.FormatWithLeadingZeros(42, 5)"00042".

1.2 — Statistics.ModeSingle(pField)

Retorna a moda (valor mais frequente) de uma coluna no contexto atual, com desempate determinístico.

FUNCTION Statistics.ModeSingle = (pField: anyref) =>
    VAR vFreqByValue =
        ADDCOLUMNS(
            VALUES(pField),
            "__Freq", CALCULATE(COUNT(pField))
        )
    VAR vTop1 =
        TOPN(1, vFreqByValue, [__Freq], DESC, pField, ASC)
    RETURN
        MAXX(vTop1, pField)

Sugestão de tipo mais específico: pField usa anyref, mas a função só faz sentido com uma referência de coluna (VALUES(pField) exige coluna). Pela regra prática já documentada em 07-dax-udf-tipos-parametro-conteudo.md, COLUMNREF é o tipo correto aqui — ganha validação em tempo de design sem alterar o comportamento em nenhum uso legítimo:

FUNCTION Statistics.ModeSingle = (pField: COLUMNREF) => ...

1.3 — Time.TotalTimeToStr(pTimeField)

Converte uma fração de dia (formato DATETIME do DAX) em string HH:MM:SS, sem limite de 24 horas — útil para durações acumuladas.

FUNCTION Time.TotalTimeToStr = (pTimeField: datetime val) =>
    VAR vHoras = FORMAT(INT(pTimeField * 24), "#00")
    VAR vMinutos = FORMAT(MINUTE(pTimeField), "00")
    VAR vSegundos = FORMAT(SECOND(pTimeField), "00")
    RETURN vHoras & ":" & vMinutos & ":" & vSegundos

INT(pTimeField * 24) permite ultrapassar 24h (ex.: 30 horas acumuladas), diferente de HOUR(), que sempre retorna 0-23 — escolha correta para o caso de uso (duração total, não hora do relógio).

1.4 — Between(pFirstValue, pLastValue, pValue)

Testa se um valor está entre dois limites, em qualquer ordem.

FUNCTION Between = (pFirstValue: anyval, pLastValue: anyval, pValue: anyval) =>
    VAR vMin = MIN(pFirstValue, pLastValue)
    VAR vMax = MAX(pFirstValue, pLastValue)
    RETURN
        pValue >= vMin && pValue <= vMax

Bom exemplo de tipo: anyval é a escolha certa aqui — a função precisa aceitar número, data ou qualquer escalar comparável, sem restringir a um subtipo. Diferente do caso de Statistics.ModeSingle acima, não há tipo mais específico que sirva sem perder generalidade.

1.5 — String.FiveStars(pNumberOfStars, pStarChar)

Gera uma string de 0 a 5 símbolos repetidos (avaliação em estrelas).

FUNCTION String.FiveStars = (pNumberOfStars: int64 val, pStarChar: string val) =>
    VAR vSymbol = IF(ISBLANK(pStarChar), "⭐", pStarChar)
    VAR vNumberOfStars = MIN(5, MAX(0, ABS(pNumberOfStars)))
    RETURN
        REPT(vSymbol, vNumberOfStars)

1.6 — Date.Holidays.EasterDate(pYearNumber) — validado

Calcula a data da Páscoa via algoritmo Meeus/Jones/Butcher ("Anonymous Gregorian Algorithm").

FUNCTION Date.Holidays.EasterDate =
    (pYearNumber: int64 val) =>
    VAR vYear = MIN(9999, MAX(1900, ABS(pYearNumber)))
    VAR vA = MOD(vYear, 19)
    VAR vB = QUOTIENT(vYear, 100)
    VAR vC = MOD(vYear, 100)
    VAR vD = QUOTIENT(vB, 4)
    VAR vE = MOD(vB, 4)
    VAR vF = QUOTIENT(vB + 8, 25)
    VAR vG = QUOTIENT(vB - vF + 1, 3)
    VAR vH = MOD(19 * vA + vB - vD - vG + 15, 30)
    VAR vI = QUOTIENT(vC, 4)
    VAR vK = MOD(vC, 4)
    VAR vL = MOD(32 + 2 * vE + 2 * vI - vH - vK, 7)
    VAR vM = QUOTIENT(vA + 11 * vH + 22 * vL, 451)
    VAR vMonth = QUOTIENT(vH + vL - 7 * vM + 114, 31)
    VAR vDay = 1 + MOD(vH + vL - 7 * vM + 114, 31)
    RETURN
        DATE(vYear, vMonth, vDay)

✅ Validado formula-a-formula contra a especificação canônica do algoritmo (Jean Meeus, Astronomical Algorithms, 1991 — a mesma referência citada no comentário original do código). Cada uma das 14 variáveis intermediárias (a a m) bate exatamente com a implementação de referência. Sem correção necessária.

1.7 — Feriados derivados da Páscoa

Três funções calculam offsets fixos a partir de EasterDate:

FUNCTION Date.Holidays.Carnival = (pYearNumber: int64 val) =>
    VAR vYear = MIN(9999, MAX(1900, ABS(pYearNumber)))
    VAR vEaster = DATE.HOLIDAYS.EASTERDATE(vYear)
    RETURN vEaster - 47   -- Carnaval: 47 dias antes da Páscoa

FUNCTION Date.Holidays.CorpusChristi = (pYearNumber: int64 val) =>
    VAR vYear = MIN(9999, MAX(1900, ABS(pYearNumber)))
    VAR vEaster = DATE.HOLIDAYS.EASTERDATE(vYear)
    RETURN vEaster + 60   -- Corpus Christi: 60 dias depois da Páscoa

Offsets confirmados contra a definição litúrgica padrão: Carnaval (terça-feira) fica 47 dias antes do Domingo de Páscoa; Corpus Christi, 60 dias depois. Ambos corretos.

1.8 — Correção: função duplicada

O código-fonte define duas funções idênticas para Sexta-feira Santa:

-- Definição 1 (sem prefixo Date.)
FUNCTION Holidays.GoodFriday = (pYearNumber: int64 val) => ...

-- Definição 2 (com prefixo Date., mesma lógica)
FUNCTION Date.Holidays.GoodFriday = (pYearNumber: int64 val) => ...

Ambas calculam vEaster - 2 (correto: Sexta-feira Santa é 2 dias antes da Páscoa). Manter apenas Date.Holidays.GoodFriday — segue o padrão de nomenclatura das outras 2 funções de feriado derivado (Date.Holidays.Carnival, Date.Holidays.CorpusChristi) e evita ambiguidade de qual versão está "oficial" na Code Library.

1.9 — Correção: bloco de teste com nomes de função incorretos

O EVALUATE ROW de teste original chama duas funções que não existem com esse nome — falhariam em tempo de execução:

Chamada no teste (errada)Função realmente definida
DATE.YEARLABEL(DATE(2024,7,1), 7)Date.FiscalYearLabel(pDate, pStartMonth)
DATE.QUARTER(DATE(2025,5,15), 7)Date.FiscalQuarter(pDate, pStartMonth)

Bloco de teste corrigido:

EVALUATE
    ROW(
        "Zeros(42,5)", STRING.FORMATWITHLEADINGZEROS(42, 5),
        "Estrelas", STRING.FIVESTARS(5, BLANK()),
        "Between 7∈[5..10]", BETWEEN(5, 10, 7),
        "IsWeekend 2025-09-27", DATE.ISWEEKEND(DATE(2025, 9, 27)),
        "Leap 2028?", DATE.ISLEAPYEAR(2028),
        "Easter 2025", DATE.HOLIDAYS.EASTERDATE(2025),
        "Carnaval 2025", DATE.HOLIDAYS.CARNIVAL(2025),
        "Good Friday 2025", DATE.HOLIDAYS.GOODFRIDAY(2025),
        "Corpus 2025", DATE.HOLIDAYS.CORPUSCHRISTI(2025),
        "IsoWeek 2025-01-05", DATE.ISOWEEKNUMBER(DATE(2025, 1, 5)),
        "FYLabel(2024-07-01,7)", DATE.FISCALYEARLABEL(DATE(2024, 7, 1), 7),
        "FQ(2025-05-15,7)", DATE.FISCALQUARTER(DATE(2025, 5, 15), 7)
    )

Resultados esperados (verificados manualmente):

TesteResultado esperado
IsoWeek 2025-01-051 — Jan/5/2025 (domingo) fecha a 1ª semana ISO de 2025, cuja quinta-feira (2/jan) já está em 2025
Easter 202520/abril/2025
Carnaval 20254/março/2025 (47 dias antes)
Good Friday 202518/abril/2025 (2 dias antes)
Corpus 202519/junho/2025 (60 dias depois)

1.10 — Funções de calendário fiscal (Date.FiscalYear, Date.FiscalMonth, Date.FiscalYearLabel, Date.FiscalQuarter)

Consistentes com a lógica de calendário fiscal já validada em 35-dax-code-library-udfs.md (DataHora.Calendario) — mesmo deslocamento MOD(mês - mêsInício + 12, 12) + 1, agora disponível como funções standalone reutilizáveis fora do contexto de uma tabela calendário completa.

2. Cookbook adicional — medidas e consultas avulsas

Trechos de código soltos, sem necessidade de correção — validados como exemplos de aplicação de funções já auditadas na Biblioteca.

2.1 — Melhor dia de vendas com CONCATENATEX

Best Selling Date =
CONCATENATEX(
    TOPN(1, 'Date', [Total Sales]),
    FORMAT([Date], "dd-mmm | ") & FORMAT([Total Sales], "$#,.0K")
)

Padrão idiomático para extrair um único valor formatado do topo de um ranking sem precisar de SELECTEDVALUE + medida auxiliar.

2.2 — % de ano/mês decorrido

Medida encadeada usando TabCalendário[Dia do Ano] para calcular progresso temporal — útil para metas proporcionais ("estamos em X% do ano, deveríamos estar em Y% da meta").

2.3 — Família de medidas estatísticas (16 medidas)

Conjunto completo de agregações (SUM, AVERAGE, MIN, MAX, STDEV.P, VAR.P, MEDIAN, DISTINCTCOUNT, COUNT) aplicadas tanto à coluna simples (Quantidade) quanto à expressão calculada (Quantidade × Valor Unitário + Frete, via SUMX/AVERAGEX/etc.) — bom exemplo didático do padrão "medida base + medida X" que já está documentado na Biblioteca (lote 1, Agregação).

2.4 — Premiação — SWITCH com ISINSCOPE multinível

Exemplo real de emoji semântico condicionado ao nível de hierarquia ativo (ISINSCOPE em Gerente/Vendedor/Categoria) — padrão avançado que complementa a documentação de ISINSCOPE já existente na Biblioteca (lote 3, Filtro) com um caso de uso de matriz de bonificação.

2.5 — Consulta de documentação de relacionamentos via INFO functions

Consulta DAX Query View sofisticada que usa INFO.TABLES(), INFO.COLUMNS(), INFO.RELATIONSHIPS() combinadas via NATURALLEFTOUTERJOIN para gerar uma tabela legível de todos os relacionamentos do modelo (tabela/coluna de origem e destino, cardinalidade, status ativo/inativo, comportamento de cross-filter).

Valor para a Biblioteca: é um exemplo real e não-trivial de uso das funções INFO.* já auditadas (lote 15) — vale incluir como exemplo avançado na página de INFO Functions ou no guia de DAX Query View (28-dax-query-view-guia.md, seção "INFO Functions — documentação automática"), que hoje só tem exemplos simples de uma tabela por vez.

2.6 — Seta de variação com Unicode

VAR vAASeta =
    SWITCH(
        TRUE(),
        vAAPer = BLANK(), BLANK(),
        vAAPer > 0, "🡽",
        vAAPer = 0, "🢂",
        vAAPer < 0, "🢆"
    )

Variante dos símbolos de seta diagonal/horizontal (🡽🢂🢆) em vez dos triângulos ▲■▼ já usados em Delta.Info (35-dax-code-library-udfs.md) — mesma ideia, símbolos alternativos. Vale documentar as duas opções lado a lado como "escolha de estilo", não uma substituindo a outra.

3. Resumo de correções

ItemProblemaCorreção
Holidays.GoodFriday vs Date.Holidays.GoodFridayFunção duplicada com nomes diferentesManter só Date.Holidays.GoodFriday
DATE.YEARLABEL(...) no testeFunção não existeTrocar por DATE.FISCALYEARLABEL(...)
DATE.QUARTER(...) no testeFunção não existeTrocar por DATE.FISCALQUARTER(...)
Statistics.ModeSingle(pField: anyref)Tipo genérico demaisSugestão: COLUMNREF (não aplicada ao código, é recomendação)

4. Onde entra na navegação

Estende /dax/udf/biblioteca (proposto em 35-dax-code-library-udfs.md) com o namespace Utilitários (String, Date, Date.Holidays, Time, Statistics, Between). Os itens da seção 2 (cookbook avulso) se distribuem entre /dax/cookbook (medidas de negócio) e exemplos avançados nas páginas de função já existentes (INFO.*, ISINSCOPE, CONCATENATEX).

Code Library DAX — Business e DateTime.Calendar

Code Library DAX — Business e DateTime.Calendar

MUST

  • Tratar DateTime.Calendar como a versão canônica/atual do gerador de calendário — supera em riqueza o que 35-dax-code-library-udfs.md registrou como DataHora.Calendario (que tinha descrição vaga, sem o detalhamento de colunas). Atualizar a referência cruzada.
  • Notar que DateTime.Calendar não parametriza hemisfério — a coluna "Estação" assume calendário do hemisfério sul (dezembro a fevereiro = "☀️ Verão") fixo no código, diferente do padrão [Idioma do Projeto] documentado em 46-dax-cookbook-configuracao-cascata-localidade.md, que faz a estação variar por localidade. São dois padrões distintos — esta UDF é a versão "Brasil fixo", o cookbook é a versão internacional.

1. Business.Choosed

FUNCTION Business.Choosed =
    (
        ColumnToCheck: anyref,
        ResultFalse: string
    ) =>
    IF.EAGER (
        HASONEVALUE ( ColumnToCheck ),
        SELECTEDVALUE ( ColumnToCheck ),
        ResultFalse
    )

Retorna o valor único selecionado de uma coluna, ou um texto alternativo se houver mais de um valor no contexto de filtro (padrão clássico de "mostrar seleção ou 'Vários'"). Uso típico: título dinâmico de cartão/página que reage à segmentação.

Título Dinâmico = Business.Choosed('TabDimCliente'[Nome Cliente], "Vários Clientes")

2. Business.ConditionalFormat.Triangle

FUNCTION Business.ConditionalFormat.Triangle =
    (
        PercentValue: anyref
    ) =>
    SWITCH (
        TRUE (),
        PercentValue == BLANK (), BLANK (),
        PercentValue > 0, "TriangleHigh",
        PercentValue < 0, "TriangleLow",
        PercentValue = 0, "TriangleMedium"
    )

Converte um valor percentual de variação (ex.: Delta% AA) em um identificador de ícone de formatação condicional (triângulo cima/baixo/neutro). Retorna texto, não o glifo em si — pensado para alimentar uma coluna de formatação condicional baseada em regras ou um mapeamento de ícone no relatório.

3. DateTime.Calendar — gerador de calendário fiscal completo

FUNCTION DateTime.Calendar =
    (
        StartDate: scalar datetime val,
        EndDate: scalar datetime val,
        Locale: scalar string,
        FirstDay: scalar int64 val,
        FiscalYearStartMonth: scalar int64 val
    ) =>
    VAR Calendario = SELECTCOLUMNS ( CALENDAR ( StartDate, EndDate ), "Data Referência", [Date] )
    RETURN
        ADDCOLUMNS( Calendario, ... )
ParâmetroTipoDescrição
StartDatedatetimeInício do intervalo
EndDatedatetimeFim do intervalo
LocalestringCultura para FORMAT() (ex.: "pt-BR") — afeta nomes de mês/dia
FirstDayint64Primeiro dia da semana para WEEKNUM/WEEKDAY (1=domingo, 2=segunda)
FiscalYearStartMonthint64Mês de início do ano fiscal (1-12)

Colunas geradas (agrupadas por família):

  • Base: Data Referência, Data (AAAAMMDD), Data (ddd dd/mm/aaaa), Ano, Semestre #/nome, Trimestre #/nome, Ano/Trimestre, Mês #/nome/ abreviado, Ano/Mês, Ano/Mês (abreviado), Semana #/nome, Semana do Mês, Quinzena #/nome, Dia da Semana #/nome/abreviado, Fim-de-Semana, Dia do Ano, Dia
  • Estação: Estação # (1-4), Estação (com emoji, ex.: "☀️ Verão"), Estação Cor (hex, ex.: #FCD53F) — fixo para hemisfério sul, ver nota em MUST acima
  • Limites de período: Início/Fim do Mês, Início/Fim do Trimestre, Início/Fim do Ano
  • ISO 8601: Semana ISO #, Ano ISO, Ano-Semana ISO (formato AAAA-SS)
  • Fiscal: Mês Fiscal #, Trimestre Fiscal #, Ano Fiscal Número, Ano Fiscal (FYAA), Trimestre Fiscal (FYAA QN), Ano/Mês Fiscal — convenção: o ano fiscal é rotulado pelo ano em que termina (padrão de mercado)
TabDimCalendario = DateTime.Calendar(DATE(2023,1,1), DATE(2026,12,31), "pt-BR", 2, 7)

Gera calendário 2023-2026, semana começando na segunda, ano fiscal iniciando em julho.

⚠️ Após criar a tabela via esta UDF, é preciso marcá-la manualmente como Tabela de Datas no Power BI (a própria função não faz essa marcação — limitação da engine, não da UDF).

4. DateTime.Calendar.About

FUNCTION DateTime.Calendar.About = () =>
    "📚 Biblioteca: DateTime" & ... & "🧩 Funções: DateTime.Calendar(...)" & ...

Função de autodocumentação — retorna uma string com nome da biblioteca, autor e assinatura da função principal. Mesmo padrão de "Sobre" já visto informalmente em outras libs do Code Library; vale considerar padronizar esse tipo de função .About() em todos os escopos, já que facilita descoberta dentro do próprio Tabular Editor sem precisar consultar a Function Library.

5. Cross-referência

Atualizar 35-dax-code-library-udfs.md: a entrada de DataHora.Calendario deve apontar para este documento como a versão mais completa e atual (DateTime.Calendar), mantendo nota de que o nome mudou de escopo.