Partilhar via


DAX funções definidas pelo utilizador (pré-visualização)

Observação

DAX As funções definidas pelo usuário estão atualmente em visualização.

DAX As funções definidas pelo usuário (UDFs) permitem que você empacote DAX a lógica e a reutilize como qualquer outra DAX função. Os UDFs introduzem uma nova FUNCTION palavra-chave, parâmetros opcionais (escalar, tabela e referências) e auxiliares de verificação de tipo que tornam a criação mais segura e clara. Depois de definir um UDF, você pode usá-lo em uma medida, coluna calculada, cálculo visual ou até mesmo outras funções definidas pelo usuário. Os usuários podem centralizar as regras de negócios, melhorar a capacidade de manutenção e evoluir os 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 no modo de exibição de consulta e noDAXmodo de exibição TMDL, e podem ser exibidos no Gerenciador de modelos no nó Funções.

Habilitar funções definidas pelo usuário

Para testar UDFs no Desktop:

  1. Vá para Opções de arquivo > e opções de configurações>.
  2. Selecione Visualizar recursos e verifique asDAX funções definidas pelo usuário.
  3. Selecione OK e reinicie o Power BI Desktop.

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

Existem vários locais para definir e gerir funções:

  • DAX modo de exibição de consulta (DQV). Defina e modifique funções no DQV. O menu de contexto do DQV também inclui consultas rápidas (Avaliar, Definir e avaliar, e Definir todas as funções neste modelo) para ajudá-lo a testar e gerenciar rapidamente as Funções Definidas pelo Usuário (UDFs).
  • Visualização TMDL. UDFs também podem ser criados e editados em TMDL. A visualização TMDL também inclui o menu de contexto Script TMDL para.
  • Explorador de modelos. As funções existentes podem ser visualizadas no nó Funções no Explorador de modelos.

Ao definir um UDF, siga estes requisitos de nomenclatura:

Nomes das funções:

  • Deve ter uma boa estrutura e ser único dentro do modelo.
  • Pode incluir pontos para espaços de nomes (por exemplo, Microsoft.PowerBI.MyFunc). Não pode começar ou terminar com um período ou ter períodos consecutivos.
  • Além dos pontos, os nomes só podem conter caracteres alfanuméricos ou sublinhados. Não são permitidos espaços ou caracteres especiais.
  • Não deve entrar em DAX conflito com funções incorporadas ou palavras reservadas (por exemplo, medida, função, definição).

Nomes dos parâmetros:

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

Usando o DAX modo de exibição de consulta

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

Formulário geral

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

Sugestão

Use /// para descrições de funções. Comentários de linha única (//) ou multilinha (/* */) 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

Guardar no modelo

Para guardar um UDF da vista de DAX consulta no 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 ecrã da vista de DAX consulta no Power BI Desktop, realçando duas localizações onde pode guardar uma função definida pelo utilizador. O primeiro é o botão Atualizar modelo com alterações na parte superior da vista. A segunda é uma linha de status no editor de código rotulada Atualizar modelo: Adicionar nova função

Usando o modo de exibição TMDL

Você pode definir e/ou atualizar funções definidas pelo usuário na visualização TMDL. Para obter informações adicionais sobre a visualização TMDL, consulte Visualizaçã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

Guardar no modelo

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

Captura de ecrã da vista TMDL no Power BI Desktop, realçando o botão Aplicar na parte superior da vista. Este é 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ídas no script TMDL do modelo semântico ao utilizar um projeto Power BI. Eles podem ser encontrados dentro functions.tmdl da pasta de definição .

Captura de tela do Visual Studio Code de um projeto do Power BI. O Explorer está aberto para a pasta do 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 explorador de modelos

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

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

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

O painel do explorador de modelos no Power BI Desktop exibe o nó Funções expandido. Dois menus de contexto estão abertos: o primeiro menu fornece Consulta Rápida, Renomear, Excluir do modelo, Ocultar na exibição de relatório, Mostrar tudo, Recolher tudo e Expandir tudo. A Consulta Rápida é realçada e selecionada. O segundo menu é destacado e oferece opções de consultas rápidas Avaliar, Definir e avaliar, Definir nova função e Definir todas as funções neste modelo.

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

O painel do 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 TMDL para, Renomear, Excluir do modelo, Ocultar na visualização de relatório, Reexibir tudo, Recolher tudo e Expandir tudo. O script para TMDL é realçado e selecionado. O segundo menu é 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 ( Dynamic Management Views ). 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 apenas 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 a partir de medidas, colunas calculadas, cálculos visuais e outros UDFs. Isso funciona exatamente da mesma forma que chamar funções integradas DAX.

Utilização de uma UDF numa medida

Use uma Função Definida pelo Usuário (UDF) numa medida para aplicar 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 que mostra o Total de Vendas e o Total de Vendas com Imposto. O total de vendas com imposto é destacado. O painel Visualizações está aberto. O total de vendas com imposto é realçado no campo Colunas.

Chamando uma UDF em uma coluna calculada

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

Observação

Ao usar um 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 para o tipo desejado usando CONVERT ou funções semelhantes.

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

Podemos ver este exemplo de medida usado na tabela abaixo:

Tabela que mostra o Valor das Vendas e o Valor das Vendas com Imposto. O Valor das Vendas com Imposto é destacado. O painel de Visualizações está aberto. O Valor das Vendas com Imposto é realçado no campo

Chamando uma UDF em um cálculo visual

Você pode usar UDFs num 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 só operam 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 estejam no visual) para um UDF nesse contexto.

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

Podemos ver este exemplo de medida na tabela abaixo:

No modo de edição de cálculo visual. Tabela que mostra o Valor das Vendas e o Valor das Vendas com Imposto. O Valor das Vendas com Imposto é destacado. A fórmula de cálculo visual do Valor das Vendas com Imposto está destacada.

Chamando uma UDF em outra UDF

Você pode aninhar funções UDFs chamando uma função de outra. Neste exemplo, definimos a nossa UDF simples AddTax e chamamo-la 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 um UDF, você pode, opcionalmente, especificar dicas de tipo para cada parâmetro:

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

As anotações de tipo estão no formato: [type] [subtype] [parameterMode]

Você pode incluir todos, alguns ou nenhum destes tipos de sugestões para cada parâmetro, para tornar as suas funções mais seguras e previsíveis nos locais 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 é avaliado imediatamente no momento da chamada. Isso é útil para funções simples.

Tipo

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

Existem duas famílias de tipos nos DAX parâmetros UDF: tipos de valor e tipos de expressão:

  • Tipos de valor: este 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. Este é o padrão se você omitir o tipo para um parâmetro.
    • Scalar: Aceita um valor escalar (pode adicionar adicionalmente um subtipo).
    • Table: Aceita uma tabela.
  • Tipos de expressão: este argumento passa por uma expressão não avaliada (avaliação preguiçosa). A função decide quando e em que contexto avaliá-la. Isso é necessário para parâmetros de referência e útil quando você precisa controlar o contexto do 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, tabela, calendário ou 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á automaticamente assumido.

Os subtipos são:

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

Modo de Parâmetro

ParameterMode controla quando e onde a expressão do parâmetro é avaliada. São eles:

  • val (avaliação ansiosa): A expressão é avaliada uma vez antes de invocar a função. O valor resultante é então passado para a função. Isso é comum para entradas escalares ou de tabela simples. Este é o padrão se você omitir parameterMode para um parâmetro.
  • expr (avaliação preguiçosa): 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 tanto val como 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 contexto dentro da função. Consulte Exemplo: parâmetro Table como exemplo.

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

Exemplo: Tipo de fundição

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 com entusiasmo. Você também pode conseguir isso apenas incluindo o Int64 subtipo, como 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 Table (valor vs expressão)

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

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 exercício fiscal de 2020. A tabela 'Vendas' já é filtrada pelo ano antes de entrar na função, portanto ALL('Date'), dentro da função, não surte efeito.

CountRowsLater retorna a contagem total de vendas realizadas ao longo de todos os anos. A função recebe uma expressão de tabela não avaliada e a avalia em 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 tempo de execução dos parâmetros passados. Isso permite que UDFs usem controle de contexto, validem parâmetros antecipadamente, normalizem entradas antes do cálculo.

Observação

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

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

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

Categoria Funções
Numeric ISNUMÉRICO,ISNUMBER
Double ISDOUBLE
Número inteiro ISINT64, ISINTEGER
Decimal É_DECIMAL,É_MOEDA
Cordão ISSTRING,ISTEXT
booleano ISBOOLEAN,ISLOGICAL
Data e Hora ISDATETIME

Exemplo: Verifique 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 manipular a entrada não-string na função (neste exemplo, retorna BLANK).

Exemplo: Aceitar vários tipos de parâmetros

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, currency, que 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, ela chamará o auxiliar GetCurrencyNameByKey que procura o nome da moeda com base na chave de moeda. Se a entrada não for um número inteiro, ela chamará o auxiliar GetCurrencyNameByCode que procura o nome da moeda com base no código da 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 DAX as UDFs podem lidar com lógicas mais complexas, veremos um cenário de conversão de moeda. Este exemplo usa verificação de tipos e funções aninhadas para converter um determinado valor numa moeda de destino, usando a taxa de câmbio média ou a taxa de câmbio de fim de dia para uma determinada data.

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 valor de data padrão. A função verifica o tipo de cada entrada e manipula-a de acordo: se pCurrency for um número inteiro, é tratado 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, é tratado como uma chave de data; caso contrário, a função assume 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 câmbio válida, ela retornará a mensagem "nenhuma taxa de câmbio disponível".

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

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

Isso pode ser opcionalmente 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 exemplo de resultado pode ser visto na imagem abaixo.

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

Considerações e limitações

As funções definidas pelo usuário estão atualmente em visualização e, durante a visualização, esteja ciente 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/reexibir um UDF no modelo.

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

  • Não há botão 'criar função' na faixa de opções.

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

  • UDFs não são suportados em modelos sem tabelas.

  • Não há consulta rápida de 'definir com referências' no DAX modo de exibição de consulta.

  • Segurança a Nível de Objeto (OLS) não se transfere para funções nem vice-versa. Por exemplo, considere a seguinte função F que se refere à medida MyMeasuresegura:

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

    quando o MyMeasure é assegurado usando segurança ao nível de objeto, a função F não é automaticamente assegurada. Se F correr sob uma identidade sem acesso a MyMeasure, comporta-se como se MyMeasure não existisse. Recomendamos evitar revelar objetos seguros em nomes e descrições de funções.

Definindo uma UDF:

  • Não há suporte para recursão ou recursão mútua.
  • A sobrecarga de funções não é suportada.
  • Os tipos de retorno explícito não são suportados.

Parâmetros UDF:

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

Suporte IntelliSense:

  • Embora as UDFs possam ser usadas em modelos compostos ou de conexão ao vivo, não há suporte ao IntelliSense.
  • Embora as UDFs possam ser usadas em cálculos visuais, a barra de fórmulas de cálculos visuais não tem suporte ao IntelliSense para UDFs.
  • A vista TMDL não tem suporte apropriado de IntelliSense para UDFs.

Bugs conhecidos

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

  • As referências a um objeto de modelo tabular (por exemplo, medida, tabela, coluna) em um UDF não são atualizadas automaticamente quando esses objetos são renomeados. Se você renomear um objeto do qual um 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.
  • Certos cenários avançados envolvendo UDFs podem resultar em inconsistências do analisador. Por exemplo, os utilizadores podem ver sublinhados vermelhos ou erros de validação ao passar colunas como parâmetros de expr ou ao usar referências de coluna não qualificadas.