Compartilhar via


DAX Funções definidas pelo usuário (versão prévia)

Observação

DAX As funções definidas pelo usuário estão atualmente em versão prévia.

DAX UDFs (funções definidas pelo usuário) permitem empacotar DAX lógica e reutilizá-la como qualquer outra DAX função. As UDFs introduzem uma nova FUNCTION palavra-chave, parâmetros opcionais (escalar, tabela e referências) e auxiliares de verificação de tipos que tornam a criação mais segura e clara. Depois de definir uma UDF, você pode usá-la em uma medida, coluna calculada, cálculo visual ou até mesmo outras funções definidas pelo usuário. Os usuários podem centralizar regras de negócios, melhorar a manutenção e desenvolver cálculos com segurança ao longo do tempo. As funções são objetos de modelo de primeira classe que você pode criar e gerenciar na visualização de consulta e no modo de exibição TMDL, e podem ser exibidas no Gerenciador de Modelos no nó Funções.

Habilitar funções definidas pelo usuário

Para experimentar UDFs na área de trabalho:

  1. Vá para Arquivo > Opções e Configurações > Opções.
  2. Selecione recursos de visualização e verifique DAX as funções definidas pelo usuário.
  3. Selecione OK e reinicie o Power BI Desktop.

Definir e gerenciar funções definidas pelo usuário

Há vários locais para definir e gerenciar funções:

  • DAX Exibição de consulta (DQV). Definir e modificar funções no DQV. O DQV também inclui consultas rápidas no menu de contexto (Avaliar, Definir e Avaliar, e Definir todas as funções do modelo) para ajudá-lo a testar e gerenciar UDFs rapidamente.
  • Exibição TMDL. UDFs também podem ser criados e editados no TMDL. O modo de exibição TMDL também inclui Script TMDL para do menu de contexto.
  • Gerenciador de modelos. As funções existentes podem ser exibidas no nó Funções no Explorador de Modelos.

Ao definir uma UDF, siga estes requisitos de nomenclatura:

Nomes de função:

  • Precisa ser bem-definido e exclusivo dentro do modelo.
  • Pode incluir períodos (pontos) para espaçamento de nomes (por exemplo, Microsoft.PowerBI.MyFunc). Não é possível iniciar ou terminar com um período ou ter períodos consecutivos.
  • Além dos períodos, os nomes só podem conter caracteres alfanuméricos ou sublinhados. Nenhum espaço ou caracteres especiais permitidos.
  • Não deve entrar em conflito com funções internas DAX ou palavras reservadas (por exemplo, medida, função, definição).

Nomes de parâmetro:

  • Só pode conter caracteres alfanuméricos ou sublinhados. Períodos não são permitidos.
  • Não deve ser uma palavra reservada.

Usando DAX o modo de exibição de consulta

Você pode definir, atualizar e avaliar funções definidas pelo usuário na DAX exibição de consulta. Para obter informações adicionais sobre o modo DAX de exibição de consulta, consulte DAX.

Formulário geral

DEFINE
    /// Optional description above the function
    FUNCTION <FunctionName> = ( [ParameterName]: [ParameterType], ... ) => <FunctionBody>

Dica

Use /// para descrições de função. Os comentários de linha única (//) ou de várias linhas (/* */) não aparecerão nas descrições de função do IntelliSense.

Exemplo: Função fiscal simples

DEFINE
    /// AddTax takes in amount and returns amount including tax
    FUNCTION AddTax = 
        ( amount : NUMERIC ) =>
            amount * 1.1

EVALUATE
{ AddTax ( 10 ) }
// Returns 11

Salvando no modelo de dados

Para salvar um UDF da visualização de consulta DAX para o modelo:

  • Clique em Atualizar modelo com alterações para salvar todas as UDFs na consulta.
  • Ou clique em Atualizar modelo: adicione uma nova função acima da função definida para salvar um único UDF.

Captura de tela do modo de exibição de DAX consulta no Power BI Desktop, realçando dois locais em que você pode salvar uma função definida pelo usuário. O primeiro é o modelo de atualização com o botão de alterações na parte superior do modo de exibição. A segunda é uma linha de status no modelo de atualização rotulado pelo editor de código: Adicionar nova função

Usando o modo de exibição TMDL

Você pode definir e/ou atualizar funções definidas pelo usuário no modo de exibição TMDL. Para obter informações adicionais sobre o modo de exibição TMDL, consulte o modo de exibição TMDL.

Formulário geral

createOrReplace
    /// Optional description above the function
    function <FunctionName> = ( [ParameterName]: [ParameterType], ... ) => <FunctionBody>

Exemplo: Função fiscal simples

createOrReplace
    /// AddTax takes in amount and returns amount including tax
    function AddTax = 
        (amount : NUMERIC) =>
            amount * 1.1

Salvando no modelo de dados

Clique no botão Aplicar na parte superior da exibição para salvar todas as UDFs no script no modelo.

Captura de tela do modo de exibição TMDL no Power BI Desktop, realçando o botão Aplicar na parte superior da exibição. Esse é o local onde você pode salvar uma função definida pelo usuário.

Usando o script TMDL em um projeto do Power BI

UDFs também são incluídos no script TMDL de modelo semântico ao usar um projeto do Power BI. Eles podem ser encontrados na functions.tmdl pasta de definição .

Captura de tela do Visual Studio Code de um projeto do Power BI. O Explorer está aberto à pasta de modelo semântico. 'functions.tmdl' está aberto no editor de código. Três funções são exibidas: CustomerLifetimeValue, AverageOrderValue e AddTax.

Usando o Gerenciador de Modelos

Você pode exibir todas as funções definidas pelo usuário no modelo do Gerenciador de Modelos no nó Funções. Para obter informações adicionais sobre o Gerenciador de Modelos, consulte o Gerenciador de Modelos.

Painel do Gerenciador de Modelos no Power BI Desktop mostrando o nó de Funções expandido. Três funções definidas pelo usuário estão listadas: AddTax, AverageOrderValue e CustomerLifetimeValue.

No DAX modo de exibição de consulta, você pode usar consultas rápidas no menu de clique com o botão direito do mouse de um UDF no Gerenciador de Modelos para definir e avaliar facilmente as funções.

O painel do Explorador de Modelos no Power BI Desktop exibe o nó Functions expandido. Dois menus de contexto estão abertos: o primeiro menu fornece Consulta rápida, Renomear, Excluir do modelo, Ocultar no modo de exibição de relatório, Reexibir tudo, Recolher tudo e Expandir tudo. Consulta rápida está realçada e selecionada. O segundo menu está realçado e oferece opções de Consulta rápida: Avaliar, Definir e avaliar, Definir nova função e Definir todas as funções no modelo.

No modo de exibição TMDL, você pode arrastar e soltar funções na tela ou usar o Script TMDL no menu de clique com o botão direito do mouse de um UDF no Gerenciador de Modelos para gerar scripts.

O painel Explorador de Modelos no Power BI Desktop exibe o nó Funções expandido. Dois menus de contexto estão abertos: o primeiro menu fornece Script para TMDL, Renomear, Excluir do modelo, Ocultar no modo de exibição de relatório, Reexibir tudo, Recolher tudo e Expandir tudo. Script para TMDL está realçado e selecionado. O segundo menu está realçado e oferece opções de Script para TMDL: guia Script e Área de Transferência.

Usando DMVs para inspecionar UDFs

Você pode inspecionar UDFs em seu modelo usando DMVs ( Exibições de Gerenciamento Dinâmico ). Essas exibições permitem que você consulte informações sobre funções, incluindo UDFs.

Você pode usar a função INFO.FUNCTIONS para inspecionar as UDFs no modelo. Para restringir o resultado somente a UDFs, especifique o ORIGIN parâmetro como 2.

EVALUATE INFO.FUNCTIONS("ORIGIN", "2")

Essa consulta retorna uma tabela de todas as UDFs atualmente no modelo, incluindo seu nome, descrição e metadados associados.

Usando uma função definida pelo usuário

Depois que um UDF é definido e salvo no modelo, você pode chamá-lo de medidas, colunas calculadas, cálculos visuais e outros UDFs. Isso funciona da mesma forma que chamar funções integradas DAX.

Invocando uma UDF em uma medida

Use uma UDF em uma medida para aplicar a lógica reutilizável com contexto de filtro completo.

Total Sales with Tax = AddTax ( [Total Sales] )

A medida de exemplo é mostrada na tabela abaixo:

Tabela mostrando Total de Vendas e Vendas Totais com Imposto. Total de Vendas com Imposto é realçado. O painel visualizações está aberto. O total de vendas com imposto é realçado bem no campo Colunas.

Chamando uma UDF em uma coluna calculada

UDFs podem ser usados em uma coluna calculada para aplicar lógica reutilizável a cada linha de uma tabela.

Observação

Ao usar uma UDF em uma coluna calculada, verifique se a função retorna um escalar de um tipo consistente. Consulte Parâmetros para obter mais informações. Se necessário, converta o resultado no tipo desejado usando CONVERT ou funções semelhantes.

Sales Amount with Tax = CONVERT ( AddTax ( 'Sales'[Sales Amount] ), CURRENCY )

Podemos ver esta medida de exemplo usada na tabela abaixo:

Tabela mostrando Valor de Vendas e Valor de Vendas com Imposto. Valor de Vendas com Imposto está destacado. O Painel de Visualizações está aberto. O Valor de Vendas com Imposto está destacado no campo Colunas.

Chamando uma UDF em um cálculo visual

Você pode usar UDFs em um cálculo visual para aplicar lógica diretamente à visualização. Para obter informações adicionais sobre cálculos visuais, consulte Cálculos Visuais.

Observação

Os cálculos visuais operam apenas em campos presentes no visual. Eles não podem acessar objetos de modelo que não fazem parte do visual e você não pode passar objetos de modelo (como colunas ou medidas que não estão no visual) para uma UDF neste contexto.

Sales Amount with Tax = AddTax ( [Sales Amount] )

Podemos ver esta medida de exemplo na tabela abaixo:

No modo de edição de cálculo visual. Tabela mostrando Valor de Vendas e Valor de Vendas com Imposto. Valor de Vendas com Imposto é realçado. A fórmula de cálculo visual do valor de Vendas com Imposto está realçada.

Chamando uma UDF em outra UDF

Você pode encadear UDFs chamando uma função de outra. Neste exemplo, definimos nossa UDF simples AddTax e a chamamos em outra UDF, AddTaxAndDiscount.

DEFINE
    /// AddTax takes in amount and returns amount including tax
    FUNCTION AddTax = 
        ( amount : NUMERIC ) =>
            amount * 1.1

	FUNCTION AddTaxAndDiscount = 
        (
			amount : NUMERIC,
			discount : NUMERIC
		) =>
		    AddTax ( amount - discount )

EVALUATE
{ AddTaxAndDiscount ( 10, 2 ) }
// Returns 8.8

Parâmetros

DAX UDFs podem aceitar zero ou mais parâmetros. Ao definir parâmetros para uma UDF, você pode, opcionalmente, especificar dicas de tipo para cada parâmetro:

  • Tipo: que tipo de valor o parâmetro aceita (AnyVal, , ScalarTableou AnyRef).
  • Subtipo (somente para tipo escalar): o tipo de dados escalar específico (Variant, , Int64, Decimal, Double, String, DateTime, Booleanou Numeric).
  • ParameterMode: quando o argumento é avaliado (val ou expr).

As dicas de tipo estão na forma: [type] [subtype] [parameterMode]

Você pode incluir todas, algumas ou nenhuma dessas dicas de tipo para cada parâmetro para tornar suas funções mais seguras e previsíveis em sites de chamada. Se você omitir tudo e apenas escrever o nome do parâmetro, ele se comporta como AnyVal val, o que significa que o argumento será avaliado imediatamente no momento da solicitação. Isso é útil para funções simples.

Tipo

O tipo define a categoria do argumento que seu parâmetro aceita e se ele é passado como um valor ou uma expressão.

Há duas famílias de tipos em DAX parâmetros UDF: tipos de valor e tipos de expressão:

  • Tipos de valor: esse argumento é avaliado imediatamente (avaliação ansiosa) quando a função é chamada e o valor resultante é passado para a função.
    • AnyVal: aceita um escalar ou uma tabela. Esse é o padrão se você omitir o tipo de um parâmetro.
    • Scalar: aceita um valor escalar (além disso, pode adicionar um subtipo).
    • Table: Aceita uma tabela.
  • Tipos de expressão: esse argumento passa uma expressão não avaliada (avaliação lenta). A função decide quando e em qual contexto avaliá-la. Isso é necessário para parâmetros de referência e útil quando você precisa controlar o contexto de filtro (por exemplo, dentro CALCULATE). expr os tipos podem ser referências a uma coluna, tabela, calendário ou medida.
    • AnyRef: aceita uma referência (uma coluna, uma tabela, um calendário ou uma medida).

Subtipo

O subtipo permite definir um tipo de dados específico Scalar . Se você definir um subtipo, não precisará definir explicitamente o parâmetro como um Scalar tipo, isso será assumido automaticamente.

Os subtipos são:

  • Variant: aceita qualquer escalar.
  • Int64: Aceita um número inteiro.
  • Decimal: aceita uma decimal de precisão fixa (como Moeda ou Dinheiro).
  • Double: aceita uma decimal de ponto flutuante.
  • String: aceita texto.
  • DateTime: aceita data/hora.
  • Boolean: aceita TRUE/FALSE.
  • Numeric: aceita qualquer valor numérico (Int64ou DecimalDouble subtipos)

ModoDeParâmetro

ParameterMode controla quando e onde a expressão de parâmetro é avaliada. Estes são:

  • val (avaliação ansiosa): a expressão é avaliada uma vez antes de invocar a função. Em seguida, o valor resultante é passado para a função. Isso é comum para entradas escalares ou de tabela simples. Esse é o padrão se você omitir parameterMode para um parâmetro.
  • expr (avaliação lenta): a expressão é avaliada dentro da função, potencialmente em um contexto diferente (por exemplo, contexto de linha ou contexto de filtro) e possivelmente várias vezes se referenciada várias vezes ou dentro de iterações. Isso é necessário para parâmetros de referência e útil quando você precisa controlar o contexto de avaliação.

O Scalar tipo pode usar ou val ou expr. Use val quando quiser que o escalar seja avaliado uma vez no contexto do chamador. Use expr quando quiser adiar a avaliação e, possivelmente, aplicar o contexto dentro da função. Veja exemplo: Parâmetro de tabela como exemplo.

O AnyRef tipo deve ser expr porque as suas referências (colunas, tabelas, medidas etc.) precisam ser avaliadas no contexto da função.

Exemplo: conversão de tipo

DEFINE
    /// returns x cast to an Int64
    FUNCTION CastToInt = (
            x : SCALAR INT64 VAL
        ) =>
        x

EVALUATE
{ CastToInt ( 3.4 ), CastToInt ( 3.5 ), CastToInt ( "5" ) }
// returns 3, 4, 5

Isso usa um Scalar tipo, Int64 subtipo e val parameterMode para arredondamento previsível e coerção de texto para número, além de garantir que todas as expressões sejam avaliadas imediatamente. Você também pode conseguir isso apenas incluindo o Int64 subtipo, conforme visto no exemplo abaixo. Cadeias de caracteres não numéricas resultarão em um erro.

DEFINE
    /// returns x as an Int64
    FUNCTION CastToInt = (
            x : INT64
        ) =>
        x

EVALUATE
{ CastToInt ( 3.4 ), CastToInt ( 3.5 ), CastToInt ( "5" ) }
// returns 3, 4, 5

Exemplo: Parâmetro de tabela (valor vs expressão)

Para ilustrar como o parâmetro UDF parameterMode afeta o contexto de filtro, considere duas funções que contam as linhas na tabela 'Vendas'. Ambos usam CALCULATETABLE(t, ALL('Date')) em seus corpos, mas um parâmetro é declarado como uma val (avaliação imediata) e o outro como expr (avaliação preguiçosa):

DEFINE
    /// Table val: receives a materialized table, context can't be changed
    FUNCTION CountRowsNow = (
            t : TABLE VAL
        ) =>
        COUNTROWS ( CALCULATETABLE ( t, ALL ( 'Date' ) ) )
    
    /// Table expr: receives an unevaluated expression, context CAN be changed
    FUNCTION CountRowsLater = (
            t : TABLE EXPR
        ) =>
        COUNTROWS ( CALCULATETABLE ( t, ALL ( 'Date' ) ) )

EVALUATE
{
    CALCULATE ( CountRowsNow ( 'Sales' ), 'Date'[Fiscal Year] = "FY2020" ),
    CALCULATE ( CountRowsLater ( 'Sales' ), 'Date'[Fiscal Year] = "FY2020" )
}
// returns 84285, 121253

CountRowsNow retorna a contagem de vendas somente para o ano fiscal de 2020. A tabela 'Vendas' já está filtrada pelo ano antes da inserção da função, portanto ALL('Date'), dentro da função, não tem efeito.

CountRowsLater retorna o número de vendas para todos os anos. A função recebe uma expressão de tabela não avaliada e a avalia sob ALL('Date'), removendo o filtro de ano externo.

Verificação de tipo

A verificação de tipo em UDFs pode ser feita com funções de verificação de tipo novas e existentes que você pode chamar dentro do corpo da função para confirmar o tipo de runtime de parâmetros passados. Isso permite que as UDFs usem controle de contexto, validem parâmetros antecipadamente, normalizem entradas antes do cálculo.

Observação

Para parâmetros no modo parameterMode, as verificações de tipo ocorrem quando o parâmetro é referenciado no corpo da função (e não no momento em que a função é chamada).

Funções de verificação de tipo disponíveis

UDFs podem usar as funções a seguir para testar valores escalares. Cada retorno TRUE/FALSE dependendo se o valor fornecido é desse tipo.

Categoria Functions
Numeric ISNUMERIC, ISNUMBER
Double ISDOUBLE
Número inteiro ISINT64, ISINTEGER
Decimal ISDECIMAL, ISCURRENCY
String ISSTRING, ISTEXT
booleano ISBOOLEAN, ISLOGICAL
Data e hora ISDATETIME

Exemplo: verificar se o parâmetro é uma cadeia de caracteres

DEFINE
    /// Returns the length of a string, or BLANK if not a string
    FUNCTION StringLength = (
            s
        ) =>
        IF ( ISSTRING ( s ), LEN ( s ), BLANK () )

EVALUATE
{ StringLength ( "hello" ), StringLength ( 123 ) }
// Returns: 5, BLANK

Isso evita erros e permite que você decida como lidar com a entrada não cadeia de caracteres na função (neste exemplo, retorna BLANK).

Exemplo: aceitar vários tipos de parâmetro

DEFINE
    /// Helper 1: get currency name by int64 key
    FUNCTION GetCurrencyNameByKey = (
            k : INT64
        ) =>
        LOOKUPVALUE ( 'Currency'[Currency], 'Currency'[CurrencyKey], k )
    
    /// Helper 2: get currency name by string code
    FUNCTION GetCurrencyNameByCode = (
            code : STRING
        ) =>
        LOOKUPVALUE ( 'Currency'[Currency], 'Currency'[Code], code )
    
    /// Accepts key (int64) or code (string) and returns the currency name
    FUNCTION GetCurrencyName = (
            currency
        ) =>
        IF (
            ISINT64 ( currency ),
            GetCurrencyNameByKey ( currency ),
            GetCurrencyNameByCode ( currency )
        )

EVALUATE
{ GetCurrencyName ( 36 ), GetCurrencyName ( "USD" ) }
// returns "Euro", "US Dollar"

Este exemplo mostra como usar a verificação de tipo em UDFs para aceitar com segurança vários tipos de entrada e retornar um único resultado previsível. GetCurrencyName usa um argumento, currencyque pode ser uma chave de moeda de número inteiro ou um código de moeda de texto. A função verifica o tipo de argumento com ISINT64. Se a entrada for um inteiro, ele chamará o auxiliar GetCurrencyNameByKey que pesquisa o nome da moeda com base na chave de moeda. Se a entrada não for um inteiro, ele chamará o auxiliar GetCurrencyNameByCode que pesquisa o nome da moeda com base no código de moeda.

Definir várias funções ao mesmo tempo

As UDFs permitem definir várias funções em uma única consulta ou script, facilitando a organização da lógica reutilizável. Isso é especialmente útil quando você deseja encapsular cálculos relacionados ou rotinas auxiliares juntos. As funções podem ser avaliadas em conjunto ou individualmente.

DEFINE
    /// Multiplies two numbers
    FUNCTION Multiply = (
            a,
            b
        ) =>
        a * b

    /// Adds two numbers and 1
    FUNCTION AddOne = (
            x,
            y
        ) =>
        x + y + 1

    /// Returns a random integer between 10 and 100
    FUNCTION RandomInt = () =>
        RANDBETWEEN ( 10, 100 )

EVALUATE
{ Multiply ( 3, 5 ), AddOne ( 1, 2 ), RandomInt () }
// returns 15, 4, 98

Exemplo avançado: conversão de moeda flexível

Para mostrar como as DAX UDFs podem lidar com uma lógica mais complexa, examinaremos um cenário de conversão de moeda. Este exemplo utiliza verificação de tipos e funções aninhadas para converter um determinado valor em uma moeda-alvo, usando a taxa de câmbio média ou do final do dia para uma data específica.

createOrReplace
	function ConvertDateToDateKey =  
		( 
			pDate: scalar variant 
		) => 
		YEAR ( pDate ) * 10000 + MONTH ( pDate ) * 100 + DAY ( pDate ) 
	
	function ConvertToCurrency = 
		( 
			pCurrency:scalar variant, 
			pDate: scalar variant, 
			pUseAverageRate: scalar boolean, 
			pAmount: scalar decimal 
		) => 
		var CurrencyKey = 
			EVALUATEANDLOG ( 
				IF ( 
					ISINT64 ( pCurrency ), 
					pCurrency, 
					CALCULATE ( 
						MAX ( 'Currency'[CurrencyKey] ), 
						'Currency'[Code] == pCurrency 
					) 
				) 
				, "CurrencyKey" 
			) 

		var DateKey = 
			EVALUATEANDLOG ( 
				SWITCH ( 
					TRUE, 
					ISINT64 ( pDate ), pDate, 
					ConvertDateToDateKey ( pDate ) 
				) 
				, "DateKey" 
			) 

		var ExchangeRate = 
			EVALUATEANDLOG ( 
				IF ( 
					pUseAverageRate, 
					CALCULATE ( 
						MAX ( 'Currency Rate'[Average Rate] ), 
						'Currency Rate'[DateKey] == DateKey, 
						'Currency Rate'[CurrencyKey] == CurrencyKey 
					), 
					CALCULATE ( 
					MAX ( 'Currency Rate'[End Of Day Rate] ), 
						'Currency Rate'[DateKey] == DateKey, 
						'Currency Rate'[CurrencyKey] == CurrencyKey 
					) 
				) 
				, "ExchangeRate" 
			) 

		var Result = 
			IF ( 
				ISBLANK ( pCurrency ) || ISBLANK ( pDate ) || ISBLANK ( pAmount ), 
				BLANK (), 
				IF ( 
					ISBLANK ( ExchangeRate ) , 
					"no exchange rate available", 
					ExchangeRate * pAmount 
				) 
			) 

		RETURN Result

A ConvertToCurrency função aceita tipos de entrada flexíveis para moeda e data. Os usuários podem fornecer uma chave de moeda ou chave de data diretamente ou fornecer um código de moeda ou um valor de data padrão. A função verifica o tipo de cada entrada e a manipula adequadamente: se pCurrency for um número inteiro, ela é tratada como uma chave de moeda; caso contrário, a função assume um código de moeda e tenta resolver a chave correspondente. pDate segue um padrão semelhante, se for um número inteiro, ele será tratado como uma chave de data; caso contrário, a função pressupõe que é um valor de data padrão e é convertida em uma chave de data usando a ConvertDateToDateKey função auxiliar. Se a função não puder determinar uma taxa de exchnage válida, ela retornará a mensagem "nenhuma taxa de câmbio disponível".

Essa lógica pode ser usada para definir uma medida, como Vendas Totais em Moeda Local.

Total Sales in Local Currency = 
ConvertToCurrency (
    SELECTEDVALUE ( 'Currency'[Code] ),
    SELECTEDVALUE ( 'Date'[DateKey] ),
    TRUE,
    [Total Sales]
)

Opcionalmente, isso pode ser emparelhado com uma cadeia de caracteres de formato dinâmico para exibir o resultado no formato de moeda apropriado.

CALCULATE (
    MAX ( 'Currency'[Format String] ),
    'Currency'[Code] == SELECTEDVALUE ( 'Currency'[Code] )
)

Um resultado de exemplo pode ser visto na captura de tela abaixo.

Tabela mostrando Data Completa, Moeda, Total de Vendas em Moeda Local e Vendas Totais.

Considerações e limitações

As funções definidas pelo usuário estão atualmente em versão prévia e, durante a visualização, lembre-se das seguintes considerações e limitações:

Geral:

  • Não é possível criar ou modelar DAX UDFs no Serviço.

  • Não é possível ocultar/remover um UDF no modelo.

  • Não é possível colocar UDFs em pastas de exibição.

  • Nenhum botão de "criar função" na faixa de opções.

  • Não é possível combinar UDFs com traduções.

  • Não há suporte para UDFs em modelos sem tabelas.

  • Não há consulta rápida "definir com referências" na visualização de consulta DAX.

  • Object-Level Security (OLS) não é transferida para funções ou vice-versa. Por exemplo, considere a seguinte função F que se refere à medida MyMeasureprotegida:

    function F = () => [MyMeasure] + 42
    

    quando MyMeasure é protegido usando segurança em nível de objeto, a função F não é automaticamente segura. Se F é executado em uma identidade sem acesso a MyMeasure, ele age como se MyMeasure não existisse. É recomendável evitar a revelação de objetos seguros em nomes de função e descrições.

Definindo uma UDF:

  • Não há suporte para recursão ou recursão mútua.
  • Não há suporte para sobrecarga de função.
  • Não há suporte para tipos de retorno explícitos.

Parâmetros UDF:

  • Não há suporte para parâmetros opcionais.
  • Não há suporte para descrições de parâmetro.
  • UDFs não podem retornar um enum valor. As funções internas que aceitam enum valores como parâmetros de função não poderão usar UDFs nesse contexto.
  • Parâmetros indefinidos da dica expr de tipo não são avaliados.

Suporte do IntelliSense:

  • Embora as UDFs possam ser usadas em modelos de conexão em tempo real ou de composição, não há suporte do IntelliSense.
  • Embora UDFs possam ser usados em cálculos visuais, a barra de fórmulas de cálculos visuais não tem suporte do IntelliSense para UDFs.
  • A visualização TMDL não possui suporte adequado do IntelliSense para UDFs.

Erros conhecidos

Os seguintes problemas são conhecidos no momento e podem afetar a funcionalidade:

  • As referências a um objeto de modelo de tabela (por exemplo, medida, tabela, coluna), em uma UDF (Função Definida pelo Usuário), não são atualizadas automaticamente quando esses objetos são renomeados. Se você renomear um objeto do qual uma UDF depende, o corpo da função ainda conterá o nome antigo. Você deve editar manualmente a expressão UDF para atualizar todas as referências ao objeto renomeado.
  • Determinados cenários avançados envolvendo UDFs podem resultar em inconsistências de analisador. Por exemplo, os usuários podem ver sublinhados vermelhos ou erros de validação ao passar colunas como expr parâmetros ou usar referências de coluna não qualificadas.