Condividi tramite


DAX Funzioni definite dall'utente (anteprima)

Annotazioni

DAX Le funzioni definite dall'utente sono attualmente in anteprima.

DAX Le funzioni definite dall'utente consentono di confezionare la logica e riutilizzarla allo stesso modo di una qualsiasi altra funzione. Le UDF introducono una nuova FUNCTION parola chiave, parametri opzionali (scalari, tabelle e riferimenti) e strumenti di verifica dei tipi che rendono la creazione più sicura e chiara. Dopo aver definito una funzione definita dall'utente, è possibile usarla in una misura, in una colonna calcolata, nel calcolo visivo o anche in altre funzioni definite dall'utente. Gli utenti possono centralizzare le regole business, migliorare la gestibilità ed evolvere i calcoli in modo sicuro nel tempo. Le funzioni sono oggetti modello di prima classe che è possibile creare e gestire nella visualizzazione della query e nella visualizzazione DAX, e possono essere visualizzate in Esplora modelli nel nodo Funzioni.

Abilitare le funzioni definite dall'utente

Per provare le UDFs in Desktop:

  1. Passare a File > Opzioni e impostazioni > Opzioni.
  2. Selezionare Funzionalità di anteprima e controllare DAX le funzioni definite dall'utente.
  3. Selezionare OK e riavviare Power BI Desktop.

Definire e gestire funzioni definite dall'utente

Esistono diverse posizioni per definire e gestire le funzioni:

  • DAX vista query (DQV). Definire e modificare le funzioni in DQV. DQV include anche query rapide nel menu di scelta rapida (Valuta, Definisci e valuta, e Definisci tutte le funzioni in questo modello) per aiutarti a testare e gestire rapidamente le funzioni definite dall'utente.
  • Vista TMDL. Le UDF possono anche essere create e modificate in TMDL. La visualizzazione TMDL include anche l'opzione del menu di scelta rapida Script TMDL su.
  • Esplora modelli. Le funzioni esistenti possono essere visualizzate nel nodo Funzioni in Esplora modelli.

Quando si definisce una UDF (funzione definita dall'utente), seguire le seguenti linee guida per la denominazione:

Nomi di funzione:

  • Deve essere ben formato e univoco all'interno del modello.
  • Può includere punti per la suddivisione degli spazi dei nomi (ad esempio, Microsoft.PowerBI.MyFunc). Impossibile iniziare o terminare con un punto o avere periodi consecutivi.
  • Oltre ai punti, i nomi possono contenere solo caratteri alfanumerici o caratteri di sottolineatura. Non sono consentiti spazi o caratteri speciali.
  • Non deve essere in conflitto con funzioni predefinite DAX o parole riservate (ad esempio, misura, funzione, definizione).

Nomi dei parametri:

  • Può contenere solo caratteri alfanumerici o caratteri di sottolineatura. I periodi non sono consentiti.
  • Non deve essere una parola riservata.

Utilizzo della visualizzazione delle query DAX

È possibile definire, aggiornare e valutare le funzioni definite dall'utente nella DAX visualizzazione delle query. Per ulteriori informazioni sulla DAX vista query, vedere DAX vista query.

Modulo generale

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

Suggerimento

Usare /// per le descrizioni delle funzioni. I commenti a riga singola (//) o a più righe (/* */) non verranno visualizzati nelle descrizioni delle funzioni IntelliSense.

Esempio: Funzione fiscale semplice

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

EVALUATE
{ AddTax ( 10 ) }
// Returns 11

Salvataggio sul modello

Per salvare una UDF (funzione definita dall'utente) dalla DAX della visualizzazione query al modello:

  • Fare clic su Aggiorna modello con le modifiche per salvare tutte le UDF (funzioni definite dall'utente) nella query.
  • In alternativa, fare clic su Aggiorna modello: aggiungi una nuova funzione sopra la funzione definita per salvare una singola UDF.

Screenshot della DAX visualizzazione query in Power BI Desktop, evidenziando due posizioni in cui è possibile salvare una funzione definita dall'utente. Il primo è il pulsante Aggiorna modello con modifiche nella parte superiore della visualizzazione. La seconda è una riga di stato nell'editor di codice con etichetta Update model: Add new function

Uso della vista TMDL

È possibile definire e/o aggiornare le funzioni definite dall'utente nella visualizzazione TMDL. Per altre informazioni sulla vista TMDL, vedere tmdl view.

Modulo generale

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

Esempio: Funzione fiscale semplice

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

Salvataggio sul modello

Fare clic sul pulsante Applica in alto nella visualizzazione per salvare tutte le funzioni definite dall'utente (UDF) nello script nel modello.

Screenshot della visualizzazione TMDL in Power BI Desktop, evidenziando il pulsante Applica nella parte superiore della visualizzazione. Si tratta del percorso in cui è possibile salvare una funzione definita dall'utente.

Uso dello script TMDL in un progetto di Power BI

Le funzioni definite dall'utente sono incluse anche nello script TMDL del modello semantico quando si usa un progetto di Power BI. Sono disponibili all'interno functions.tmdl della cartella di definizione .

Screenshot di Visual Studio Code di un progetto di Power BI. Explorer è aperto alla cartella del modello semantico. 'functions.tmdl' è aperto nell'editor di codice. Vengono visualizzate tre funzioni: CustomerLifetimeValue, AverageOrderValue e AddTax.

Uso dell'Esplora Modelli

È possibile visualizzare tutte le funzioni definite dall'utente nel modello da Esplora modelli nel nodo Funzioni . Per altre informazioni su Esplora modelli, vedere Esplora modelli.

Pannello Esplora modelli in Power BI Desktop che mostra il nodo Funzioni espanso. Sono elencate tre funzioni definite dall'utente: AddTax, AverageOrderValue e CustomerLifetimeValue.

Nella DAX visualizzazione query è possibile usare query rapide nel menu di scelta rapida di una funzione definita dall'utente in Esplora modelli per definire e valutare facilmente le funzioni.

Il riquadro Esplora modelli in Power BI Desktop visualizza il nodo Funzioni espanse. Sono aperti due menu di scelta rapida: il primo menu fornisce query rapide, Rinomina, Elimina dal modello, Nascondi nella visualizzazione report, Scopri tutto, Comprimi tutto ed Espandi tutto. Le query rapide sono evidenziate e selezionate. Il secondo menu è evidenziato e offre opzioni Query rapide Valuta, Definisci e valuta, Definisci nuova funzione e Definisci tutte le funzioni in questo modello.

Nella visualizzazione TMDL è possibile trascinare e rilasciare funzioni nell'area di disegno o usare Script TMDL nel menu di scelta rapida di una funzione definita dall'utente (UDF) in Esplora modelli per generare script.

Il riquadro Esplora modelli in Power BI Desktop visualizza il nodo Funzioni espanso. Sono aperti due menu di scelta rapida: il primo menu fornisce Script TMDL in, Rinomina, Elimina dal modello, Nascondi nella visualizzazione report, Scopri tutto, Comprimi tutto ed Espandi tutto. Script to TMDL è evidenziato e selezionato. Il secondo menu è evidenziato e offre le opzioni Script to TMDL: scheda Script e Appunti.

Uso di DMV per controllare le funzioni definite dall'utente

È possibile esaminare le funzioni definite dall'utente nel modello usando DMV (Dynamic Management Views). Queste viste consentono di eseguire query sulle funzioni, incluse le UDF.

È possibile usare la funzione INFO.FUNCTIONS per esaminare le FDU nel modello. Per limitare il risultato solo alle funzioni definite dall'utente, specificare il ORIGIN parametro come 2.

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

Questa query restituisce una tabella di tutte le funzioni definite dall'utente attualmente presenti nel modello, inclusi il nome, la descrizione e i metadati associati.

Uso di una funzione definita dall'utente

Dopo aver definito e salvato una funzione definita dall'utente nel modello, è possibile richiamarla da misure, colonne calcolate, calcoli visualizzati e altre funzioni definite dall'utente. Questo funziona come la chiamata di funzioni predefinite DAX .

Chiamata di una funzione definita dall'utente in una metrica

Utilizzare una funzione di definizione dell'utente in una misura per applicare logica riutilizzabile con un contesto di filtro completo.

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

La misura di esempio è illustrata nella tabella seguente:

Tabella che mostra le vendite totali e le vendite totali con iva. Le vendite totali con iva sono evidenziate. Il riquadro Visualizzazioni è aperto. Le vendite totali con imposta sono evidenziate nell'area Campi colonne.

Chiamata di una funzione definita dall'utente in una colonna calcolata

Le UDF (funzioni definite dall'utente) possono essere usate in una colonna calcolata per applicare logica riutilizzabile a ogni riga di una tabella.

Annotazioni

Quando si usa una funzione definita dall'utente in una colonna calcolata, assicurarsi che la funzione restituisca un valore scalare di tipo coerente. Per altre informazioni, vedere Parametri . Se necessario, convertire il risultato nel tipo desiderato usando CONVERT o funzioni simili.

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

È possibile vedere questa misura di esempio usata nella tabella seguente:

Tabella che mostra l'importo delle vendite e l'importo delle vendite con IVA. L'importo delle vendite con IVA è evidenziato. Il riquadro Visualizzazioni è aperto. L'importo delle vendite con IVA è evidenziato nell'area Campi colonne.

Chiamata di una funzione definita dall'utente in un calcolo visivo

È possibile usare funzioni definite dall'utente in un calcolo visivo per applicare la logica direttamente all'oggetto visivo. Per altre informazioni sui calcoli visivi, vedere Calcoli visivi.

Annotazioni

I calcoli visivi operano solo sui campi presenti nell'oggetto visivo. Non possono accedere agli oggetti modello che non fanno parte dell'oggetto visivo e non è possibile passare oggetti modello (ad esempio colonne o misure non presenti nell'oggetto visivo) in una funzione definita dall'utente in questo contesto.

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

È possibile vedere questa misura di esempio nella tabella seguente:

In modalità di modifica del calcolo visivo. Tabella che mostra l'importo vendite e l'importo delle vendite con iva. L'importo delle vendite con iva è evidenziato. La formula di calcolo visiva per l'importo delle vendite con imposta è evidenziata.

Chiamare una funzione definita dall'utente all'interno di un'altra funzione definita dall'utente

È possibile annidare le UDF chiamando una funzione da un'altra. In questo esempio definiamo il nostro semplice UDF AddTax e lo chiamiamo in un altro 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

Parametri

DAX Le funzioni definite dall'utente possono accettare zero o più parametri. Quando si definiscono i parametri di una funzione definita dall'utente, è possibile specificare delle indicazioni di tipo per ciascun parametro come opzione:

  • Tipo: tipo di valore accettato dal parametro (AnyVal, Scalar, Tableo AnyRef).
  • Sottotipo (solo per il tipo scalare): tipo di dati scalare specifico (Variant, Int64, DecimalDouble, String, DateTime, Boolean, o Numeric).
  • ParameterMode: quando l'argomento viene valutato (val o expr).

I suggerimenti di tipo sono nel formato: [type] [subtype] [parameterMode]

È possibile includere tutti, alcuni o nessuno di questi hint di tipo per ogni parametro per rendere le funzioni più sicure e più prevedibili nei siti di chiamata. Se si omettono tutti gli elementi e si scrive semplicemente il nome del parametro come AnyVal val, il che significa che l'argomento viene valutato immediatamente in fase di chiamata. Ciò è utile per funzioni semplici.

TIPO

Il tipo definisce la categoria dell'argomento accettato dal parametro e se viene passato come valore o espressione.

Esistono due famiglie di tipi nei DAX parametri UDF: tipi di valore e tipi di espressione:

  • Tipi valore: questo argomento viene valutato immediatamente (valutazione eager) quando viene chiamata la funzione e il valore risultante viene passato alla funzione.
    • AnyVal: accetta uno scalare o una tabella. Si tratta dell'impostazione predefinita se si omette il tipo per un parametro.
    • Scalar: accetta un valore scalare (può anche aggiungere un sottotipo).
    • Table: Accetta una tabella di dati.
  • Tipi di espressione: questo argomento passa un'espressione non valutata (valutazione pigra). La funzione decide quando e in quale contesto valutarlo. Questa operazione è necessaria per i parametri di riferimento ed è utile quando è necessario controllare il contesto di filtro, ad esempio all'interno di CALCULATE. expr I tipi possono essere riferimenti a una colonna, una tabella, un calendario o una misura.
    • AnyRef: accetta un riferimento (una colonna, una tabella, un calendario o una misura).

Sottotipo

Sottotipo consente di definire un tipo di dati specifico Scalar . Se si definisce un sottotipo, non è necessario definire in modo esplicito il parametro come Scalar tipo, viene automaticamente assunto.

I sottotipi sono:

  • Variant: accetta qualsiasi scalare.
  • Int64: accetta un numero intero.
  • Decimal: accetta un decimale a precisione fissa, ad esempio Valuta o Denaro.
  • Double: accetta un decimale a virgola mobile.
  • String: accetta testo.
  • DateTime: accetta data/ora.
  • Boolean: accetta TRUE/FALSE.
  • Numeric: accetta qualsiasi valore numerico (Int64, Decimalo Double sottotipi)

ModalitàParametro

ParameterMode controlla quando e dove viene valutata l'espressione di parametro. Si tratta di:

  • val (valutazione anticipata): l'espressione viene valutata una volta prima di richiamare la funzione. Il valore risultante viene quindi passato alla funzione. Questo è comune per gli input scalari o di tabella semplici. Si tratta dell'impostazione predefinita se si omette parameterMode per un parametro.
  • expr (valutazione differita): L'espressione viene valutata all'interno della funzione, potenzialmente in un contesto diverso (ad esempio, contesto di riga o contesto di filtro) ed eventualmente più volte se viene fatto riferimento più volte o in caso di iterazioni. Questa operazione è necessaria per i parametri di riferimento e utile quando è necessario controllare il contesto di valutazione.

Il Scalar tipo può usare val o expr. Usare val quando si vuole che il scalare venga valutato una volta nel contesto del chiamante. Usare expr quando si vuole rinviare la valutazione ed eventualmente applicare il contesto all'interno della funzione. Vedere Esempio: Parametro table come esempio.

Il tipo AnyRef deve essere expr poiché i suoi riferimenti (colonne, tabelle, misure e così via) devono essere valutati nel contesto della funzione.

Esempio: Cast dei tipi

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

In questo modo viene usato un tipo Scalar, un sottotipo Int64 e una modalità parametro val per l'arrotondamento prevedibile e la coercizione da testo a numero, oltre a garantire che tutte le espressioni vengano valutate immediatamente. È anche possibile ottenere questo risultato includendo il Int64 sottotipo come illustrato nell'esempio seguente. Le stringhe non numeriche genereranno un errore.

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

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

Esempio: parametro Tabella (valore vs espressione)

Per illustrare come il parametro UDF parameterMode influisce sul contesto di filtro, consideriamo due funzioni che conteggiano entrambe le righe nella tabella 'Sales'. Entrambi usano CALCULATETABLE(t, ALL('Date')) nei rispettivi corpi, ma un parametro viene dichiarato come val (valutazione eager) e l'altro come expr (valutazione lazy):

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 restituisce il conteggio delle vendite solo per FY2020. La tabella 'Sales' è già filtrata in base all'anno prima di immettere la funzione, quindi ALL('Date') all'interno della funzione non ha alcun effetto.

CountRowsLater restituisce il conteggio delle vendite per tutti gli anni. La funzione riceve un'espressione di tabella non elaborata e la valuta in ALL('Date'), eliminando il filtro esterno sull'anno.

Controllo dei tipi

Il controllo dei tipi nelle funzioni definite dall'utente può essere eseguito con funzioni di controllo dei tipi nuove ed esistenti che è possibile chiamare all'interno del corpo della funzione per confermare il tipo di runtime dei parametri passati. In questo modo, le UDF possono usare il controllo del contesto, convalidare i parametri in anticipo, normalizzare gli input prima del calcolo.

Annotazioni

Per expr i parametri parameterMode, i controlli di tipo si verificano quando viene fatto riferimento al parametro nel corpo della funzione (non al momento della chiamata di funzione).

Funzioni di controllo dei tipi disponibili

Le funzioni definite dall'utente (UDF) possono utilizzare le funzioni seguenti per testare i valori scalari. Ogni valore restituito TRUE/FALSE dipende dal fatto che il valore specificato sia di quel tipo.

Categoria Functions
Numeric ISNUMERIC, ISNUMBER
Double ISDOUBLE
Numero intero ISINT64, ISINTEGER
Decimal ISDECIMAL, ISCURRENCY
String ISSTRING, ISTEXT
Boolean ISBOOLEAN, ISLOGICAL
Data e ora ISDATETIME

Esempio: Controllare se il parametro è una stringa

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

Ciò impedisce gli errori e consente di decidere come gestire l'input non stringa nella funzione (in questo esempio restituisce BLANK).

Esempio: Accettare più tipi di parametro

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"

In questo esempio viene illustrato come utilizzare il controllo dei tipi nelle UDF (funzioni definite dall'utente) per garantire la sicurezza dell'accettazione di più tipi di input e restituire un risultato unico e prevedibile. GetCurrencyName accetta un argomento, currency, che può essere una chiave di valuta numero intero o un codice di valuta di testo. La funzione controlla il tipo di argomento con ISINT64. Se l'input è un numero intero, chiama l'helper GetCurrencyNameByKey che cerca il nome della valuta in base alla chiave di valuta. Se l'input non è un numero intero, chiama l'helper GetCurrencyNameByCode che cerca il nome della valuta in base al codice di valuta.

Definire più funzioni contemporaneamente

Le FDU consentono di definire più funzioni in una query o uno script singolo, facilitando l'organizzazione della logica riutilizzabile. Ciò è particolarmente utile quando si desidera incapsulare calcoli correlati o routine helper insieme. Le funzioni possono essere valutate insieme o singolarmente.

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

Esempio avanzato: Conversione di valuta flessibile

Per illustrare in che DAX modo le funzioni definite dall'utente possono gestire una logica più complessa, verrà esaminato uno scenario di conversione di valuta. In questo esempio vengono utilizzati il controllo dei tipi e le funzioni nidificate per convertire un determinato importo in una valuta di destinazione utilizzando il tasso di cambio medio o di fine giornata per una data specifica.

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

La ConvertToCurrency funzione accetta tipi di input flessibili per valuta e data. Gli utenti possono fornire direttamente una chiave di valuta o una chiave data oppure fornire un codice valuta o un valore di data standard. La funzione controlla il tipo di ogni input e la gestisce di conseguenza: se pCurrency è un numero intero, viene considerata come chiave di valuta. In caso contrario, la funzione presuppone un codice di valuta e tenta di risolvere la chiave corrispondente. pDate segue un modello simile, se è un numero intero, viene considerato come una chiave data; in caso contrario, la funzione presuppone che sia un valore di data standard e venga convertito in una chiave data usando la ConvertDateToDateKey funzione helper. Se la funzione non è in grado di determinare un tasso di estrazione valido, restituisce il messaggio "Nessun tasso di cambio disponibile".

Questa logica può quindi essere usata per definire una misura, ad esempio Total Sales in Local Currency.

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

Questa opzione può essere facoltativamente abbinata a una stringa di formato dinamico per visualizzare il risultato nel formato di valuta appropriato.

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

Un risultato di esempio può essere visualizzato nello screenshot seguente.

Tabella che mostra la data completa, la valuta, le vendite totali nella valuta locale e le vendite totali.

Considerazioni e limitazioni

Le funzioni definite dall'utente sono attualmente in anteprima e durante l'anteprima, tenere presenti le considerazioni e le limitazioni seguenti:

Generale:

  • Impossibile creare o modellare DAX funzioni definite dall'utente nel servizio.
  • Impossibile nascondere o mostrare una UDF nel modello.
  • Impossibile inserire funzioni definite dall'utente nelle cartelle di visualizzazione.
  • Nessun pulsante "crea funzione" sulla barra multifunzione.
  • Impossibile combinare funzioni definite dall'utente (UDF) con traduzioni.
  • Le UDF non sono supportate nei modelli senza tabelle.

Definizione di una UDF (Funzione Definita dall'Utente):

  • La ricorsione o la ricorsione reciproca non è supportata.
  • L'overload delle funzioni non è supportato.
  • Tipi restituiti espliciti non supportati.

Parametri della funzione definita dall'utente:

  • I parametri facoltativi non sono supportati.
  • Le descrizioni dei parametri non sono supportate.
  • Le funzioni definite dall'utente non possono restituire un enum valore. Le funzioni predefinite che accettano valori enum come parametri non potranno usare le funzioni definite dall'utente in tale contesto.
  • I parametri di tipo hint non associati non vengono valutati.

Supporto di IntelliSense:

  • Anche se le funzioni definite dall'utente (UDF) possono essere utilizzate nei modelli di connessione dal vivo o compositi, non è disponibile alcun supporto per IntelliSense.
  • Sebbene le UDF possano essere utilizzate nei calcoli visivi, la barra della formula dei calcoli visivi non offre supporto IntelliSense per le UDF.
  • La visualizzazione TMDL non ha un supporto adeguato di IntelliSense per le UDF.

Bug noti

I problemi seguenti sono attualmente noti e possono influire sulle funzionalità:

  • I riferimenti a un oggetto modello tabulare (ad esempio, misura, tabella, colonna) in una funzione definita dall'utente (UDF) non vengono aggiornati automaticamente quando tali oggetti vengono rinominati. Se rinomini un oggetto da cui dipende una FDU, il corpo della funzione conterrà comunque il nome precedente. È necessario modificare manualmente l'espressione UDF per aggiornare tutti i riferimenti all'oggetto rinominato.
  • Alcuni scenari avanzati che coinvolgono UDF possono comportare incoerenze del parser. Ad esempio, gli utenti possono visualizzare sottolineature rosse o errori di convalida quando si passano colonne come expr parametri o si usano riferimenti a colonne non qualificate.