Merk
Tilgang til denne siden krever autorisasjon. Du kan prøve å logge på eller endre kataloger.
Tilgang til denne siden krever autorisasjon. Du kan prøve å endre kataloger.
DAX brukerdefinerte funksjoner (UDF-er) lar deg pakke DAX logikk og gjenbruke den som alle andre DAX funksjoner. UDF-er introduserer et nytt FUNCTION nøkkelord, støtteparametere (skalar, tabell og referanser) med valgfrie standarduttrykk, og inkluderer typekontrollhjelpere som gjør forfatterskapet tryggere og tydeligere. Når du har definert en UDF, kan du bruke den i et mål, en beregnet kolonne, en visuell beregning eller til og med andre brukerdefinerte funksjoner. Brukere kan sentralisere forretningsregler, forbedre vedlikeholdbarheten og utvikle beregninger trygt over tid. Funksjoner er førsteklasses modellobjekter du kan opprette og administrere i DAX spørringsvisning og TMDL-visning, og de kan vises i Modellutforsker under Funksjoner-noden .
DAX UDF-er krever databasekompatibilitetsnivå 1702 eller høyere, og funksjonen er generelt tilgjengelig i Power BI Desktop and Power BI Service fra juni 2026-utgivelsen.
Definere og administrere brukerdefinerte funksjoner
Det er flere steder å definere og administrere funksjoner:
- DAX spørringsvisning (DQV). Definere og endre funksjoner i DQV. DQV inkluderer også hurtigspørringer på kontekstmenyen (Evaluer, Definer og evaluer og Definer alle funksjoner i denne modellen) for å hjelpe deg med å teste og administrere UDF-er raskt.
- TMDL-visning. UDF-er kan også forfattes og redigeres i TMDL. TMDL-visningen inkluderer også kontekstmenyen Skript TMDL til.
- Modell utforsker. Nye funksjoner kan opprettes og eksisterende funksjoner kan endres ved hjelp av formellinjen. Eksisterende funksjoner kan vises under Funksjoner-noden i Modellutforsker.
Når du definerer en UDF, må du følge disse navnekravene:
Navn på funksjoner:
- Må være velformet og unik innenfor modellen.
- Kan inkludere punktum (punktum) for navneavstand (for eksempel Microsoft.PowerBI.MyFunc). Kan ikke starte eller slutte med et punktum eller ha sammenhengende perioder.
- Bortsett fra punktum kan navn bare inneholde alfanumeriske tegn eller understrekingstegn. Ingen mellomrom eller spesialtegn tillatt.
- Må ikke komme i konflikt med innebygde DAX funksjoner eller reserverte ord (f.eks. måle, funksjon, definere).
Parameternavn:
- Kan bare inneholde alfanumeriske tegn eller understrekingstegn. Mensene er ikke tillatt.
- Må ikke være et reservert ord.
Bruke DAX spørringsvisning
Du kan definere, oppdatere og evaluere brukerdefinerte funksjoner i DAX spørringsvisning. Hvis du vil ha mer informasjon om DAX spørringsvisning, kan du se DAX spørringsvisning.
Generelt skjema
DEFINE
/// Optional description above the function
/// @param {ParameterType} ParameterName - ParameterDescription
/// ...
/// @returns Return description
FUNCTION <FunctionName> = ( [<ParameterName> [: [<ParameterType>] [<ParameterSubtype>] [<ParameterPassingMode>]] [= <DefaultExpression>], ...] ) => <FunctionBody>
Tips
Ved å bruke JSDoc-blokktagger, dokumenter funksjonene dine med beskrivelser, parameternavn og typer, og returner informasjon for å gjøre dem enklere å konsumere. Merk /// for funksjonsbeskrivelser. Kommentarer med én linje (//) eller flere linjer (/* */) vises ikke i IntelliSense-funksjonsbeskrivelser.
Eksempel: Enkel avgiftsfunksjon
DEFINE
/// AddTax takes in amount and returns amount including tax
/// @param {NUMERIC} amount - The pre-tax value to which tax will be applied
/// @param {NUMERIC} [taxRate] - Optional tax rate to apply, default is 0.1 (10%)
/// @returns The amount including 10% tax
FUNCTION AddTax =
( amount : NUMERIC, taxRate : NUMERIC = 0.1 ) =>
amount * ( 1 + taxRate )
EVALUATE
{ AddTax ( 10 ) }
// Returns 11
Lagre til modellen
Slik lagrer du en UDF fra DAX spørringsvisning til modellen:
- Klikk Oppdater modell med endringer for å lagre alle UDF-er i spørringen.
- Eller klikk Oppdater modell: Legg til ny funksjon over den definerte funksjonen for å lagre én enkelt UDF.
Bruke TMDL-visning
Du kan definere og/eller oppdatere brukerdefinerte funksjoner i TMDL-visning. Hvis du vil ha mer informasjon om TMDL-visning, kan du se TMDL-visning.
Generelt skjema
createOrReplace
/// Optional description above the function
function <FunctionName> = ( [<ParameterName> [: <ParameterType>] [= <DefaultExpression>], ...] ) => <FunctionBody>
Eksempel: Enkel avgiftsfunksjon
createOrReplace
/// AddTax takes in amount and returns amount including tax
function AddTax =
(amount : NUMERIC) =>
amount * 1.1
Lagre til modellen
Klikk på Bruk-knappen øverst i visningen for å lagre alle UDF-er i skriptet til modellen.
Bruke TMDL-skript i et Power BI-prosjekt
UDF-er er også inkludert i TMDL-skriptet for den semantiske modellen når du bruker et Power BI-prosjekt. De finner du i functions.tmdldefinisjonsmappen .
Bruke Modellutforsker
Du kan vise alle brukerdefinerte funksjoner i modellen fra Modellutforsker under Funksjoner-noden . Hvis du vil ha mer informasjon om Modellutforsker, kan du se Modellutforsker.
I DAX spørringsvisning kan du bruke hurtigspørringer på høyreklikkmenyen til en UDF i Modellutforsker for enkelt å definere og evaluere funksjoner.
I TMDL-visningen kan du dra og slippe funksjoner til lerretet eller bruke Skript TMDL til å høyreklikke på menyen til en UDF i Modellutforsker for å generere skript.
Bruke DMV-er til å inspisere UDF-er
Du kan inspisere UDF-er i modellen din ved hjelp av dynamiske administrasjonsvisninger (DMV-er). Disse visningene lar deg spørre etter informasjon om funksjoner, inkludert UDF-er.
Du kan bruke INFO. USERDEFINEDFUNCTIONS fungerer for å inspisere UDF-ene i modellen. Denne funksjonen returnerer full metadata og krever skrivetillatelse.
EVALUATE INFO.USERDEFINEDFUNCTIONS()
Alternativt kan du bruke INFO. FUNCTIONS-funksjonen for å returnere UDF-navn og begrenset metadata.
EVALUATE INFO.FUNCTIONS("ORIGIN", "2")
Bruke en brukerdefinert funksjon
Når en UDF er definert og lagret i modellen, kan du kalle den fra mål, beregnede kolonner, visuelle beregninger og andre UDF-er. Dette fungerer på samme måte som å ringe innebygde DAX funksjoner.
Kalle en UDF i et tiltak
Bruk en UDF i et mål for å bruke gjenbrukbar logikk med full filterkontekst.
Total Sales with Tax = AddTax ( [Total Sales] )
Eksempelmålet er vist i tabellen nedenfor:
Kalle en UDF i en beregnet kolonne
UDF-er kan brukes i en beregnet kolonne for å bruke gjenbrukbar logikk på hver rad i en tabell.
Note
Når du bruker en UDF i en beregnet kolonne, må du sørge for at funksjonen returnerer en skalar av en konsistent type. Se Parametere for mer informasjon. Konverter om nødvendig resultatet til ønsket type ved hjelp av CONVERT eller lignende funksjoner.
Sales Amount with Tax = CONVERT ( AddTax ( 'Sales'[Sales Amount] ), CURRENCY )
Vi kan se dette eksempelmålet brukt i tabellen nedenfor:
Kalle en UDF i en visuell beregning
Du kan bruke UDF-er i en visuell beregning for å bruke logikk direkte på visualobjektet. Hvis du vil ha mer informasjon om visuelle beregninger, kan du se Visuelle beregninger.
Note
Visuelle beregninger fungerer bare på felt som finnes i visualobjektet. De får ikke tilgang til modellobjekter som ikke er en del av visualobjektet, og du kan ikke sende modellobjekter (for eksempel kolonner eller mål som ikke er i visualobjektet) til en UDF i denne konteksten.
Sales Amount with Tax = AddTax ( [Sales Amount] )
Vi kan se dette eksempeltiltaket i tabellen nedenfor:
Kalle en UDF i en annen UDF
Du kan neste UDF-er ved å kalle en funksjon fra en annen. I dette eksemplet definerer vi vår enkle AddTax UDF og kaller den i en annen 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
Parametere
DAX UDF-er støtter mellom 0 og 256 parametere. Når du definerer parametere for en UDF, kan du eventuelt angi typetips for hver parameter:
-
Type: hvilken type verdi parameteren aksepterer (
AnyVal,Scalar,Table, ,AnyRef,CalendarRef,ColumnRef, ellerMeasureRefTableRef). -
Undertype (bare for skalartype): den spesifikke skalardatatypen (
Variant,Int64,Decimal,DoubleStringDateTimeBoolean, eller ).Numeric -
Parametermodus: når argumentet evalueres (
valellerexpr).
Typetips er i formatet: [type] [subtype] [parameterMode]
Du kan inkludere alle, noen eller ingen av disse typetipsene for hver parameter for å gjøre funksjonene dine tryggere og mer forutsigbare på anropssteder. Hvis du utelater alt og bare skriver parameternavnet, oppfører det seg som AnyVal val, noe som betyr at argumentet evalueres umiddelbart ved anropstidspunktet. Dette er nyttig for enkle funksjoner.
Du kan også gjøre parameteren til en valgfri parameter ved å inkludere et standarduttrykk med .= <DefaultExpression> Dette betyr at kalleren kan velge å utelate argumentet, og hvis de gjør det, vil standarduttrykket bli brukt som argumentverdi.
Type:
Type definerer argumentkategorien parameteren godtar, og om den sendes som en verdi eller et uttrykk.
Det finnes to typefamilier i DAX UDF-parametere: verdityper og uttrykkstyper:
-
Verdityper: Dette argumentet evalueres umiddelbart (eager evaluation) når funksjonen kalles og den resulterende verdien sendes inn i funksjonen.
-
AnyVal: Godtar en skalar eller en tabell. Dette er standard hvis du utelater type for en parameter. -
Scalar: Godtar en skalarverdi (kan i tillegg legge til en undertype). -
Table: Godtar en tabell.
-
-
Uttrykkstyper: Dette argumentet passerer et uevaluert uttrykk (lat evaluering). Funksjonen bestemmer når og i hvilken sammenheng den skal evalueres. Dette er nødvendig for referanseparametere og nyttig når du trenger å kontrollere filterkonteksten (f.eks. inne i CALCULATE).
exprTyper kan være referanser til en kolonne, tabell, kalender eller mål.-
AnyRef: Godtar enhver referanse. Det tilsvarer å ikke spesifisere en uttrykkstype. -
CalendarRef: Godtar en referanse til en kalender. -
ColumnRef: Godtar en referanse til en kolonne. -
MeasureRef: Godtar en referanse til et mål. -
TableRef: Godtar en referanse til en tabell.
-
Verdityper (AnyVal, Scalar, ) Tablestøtter implisitt typestøping. Uttrykkstyper (AnyRef, CalendarRef, ColumnRef, MeasureRef, ) TableRefgjør det ikke.
Undertype
Med undertype kan du definere en bestemt Scalar datatype. Hvis du definerer en undertype, trenger du ikke eksplisitt å definere parameteren som en Scalar type, dette antas automatisk.
Undertyper er:
-
Variant: Godtar enhver skalar. -
Int64: Godtar et helt tall. -
Decimal: Godtar en desimal med fast presisjon (for eksempel Valuta eller Penger). -
Double: Godtar en flyttallsdesimal. -
String: Godtar tekst. -
DateTime: Godtar dato/klokkeslett. -
Boolean: Godtar TRUE/FALSE. -
Numeric: Godtar alle numeriske verdier (Int64,DecimalellerDoubleundertyper)
Parameter-modus
ParameterMode (også kalt parameteroverføringsmodus eller enkelt parametermodus) styrer når og hvor parameteruttrykket evalueres. Disse er:
-
val(ivrig evaluering): Uttrykket evalueres én gang før funksjonen påkalles. Den resulterende verdien sendes deretter inn i funksjonen. Dette er vanlig for enkle skalar- eller tabellinnganger. Dette er standard hvis du utelater parametermodus for en parameter. -
expr(lat evaluering): Uttrykket evalueres inne i funksjonen, potensielt i en annen kontekst (f.eks. radkontekst eller filterkontekst) og muligens flere ganger hvis det refereres til flere ganger eller i iterasjoner. Dette er nødvendig for referanseparametere og nyttig når du trenger å kontrollere evalueringskonteksten.
Typen Scalar kan bruke enten val eller expr. Bruk når val du vil at skalaren skal evalueres én gang i anroperens kontekst. Bruk når expr du vil utsette evalueringen og eventuelt bruke kontekst i funksjonen. Se Eksempel: Tabellparameter som et eksempel.
Uttrykkstypene (AnyRef, ColumnRef, osv.) må være expr som referansene (kolonner, tabeller, mål osv.) må evalueres i funksjonens kontekst.
Følgende tabell oppsummerer den effektive/tillatte parameterenMode:
| Type: | ParameterMode ikke spesifisert | ParameterMode: val |
ParameterMode: expr |
|---|---|---|---|
(Ikke spesifisert) / AnyVal |
val |
val |
expr |
Scalar, Table |
val |
val |
expr |
AnyRef |
expr |
Ikke tillatt | expr |
CalendarRef, , ColumnRef, MeasureRefTableRef |
expr |
Ikke tillatt | expr |
En expr parameter evalueres lat innenfor funksjonskroppen, slik at den kun arver filterkonteksten. Derimot evalueres en val parameter ivrig før den går inn i funksjonskroppen, og arver derfor både rad-konteksten og filter-konteksten til kalleren.
Standarduttrykk
Når du tildeler et standarduttrykk til en parameter ved bruk av = <DefaultExpression>, blir den parameteren valgfri. Kalleren kan utelate argumentet, og standarduttrykket brukes som argumentverdi. Følgende atferd gjelder:
-
Posisjon: Valgfrie parametere kan vises i hvilken som helst posisjon. Nødvendige parametere kan komme etter valgfrie fordi kallere kan la et argument stå tomt for å bruke standarduttrykket (f.eks.
MyFunc(1,,3)utelater det andre argumentet). Imidlertid bestemmes det minste antallet argumenter (aritet) til funksjonen av posisjonen til den høyre nødvendige parameteren. For eksempel, hvis en funksjon har tre parametere og bare den andre er valgfri, må kallere fortsatt levere minst tre argumenter. - Kontekst: Om filter-konteksten og rad-konteksten arves, bestemmes av parametermodusen til parameteren knyttet til standarduttrykket.
- Omfang: Et standarduttrykk kan kun referere til navn (kolonner, tabeller, mål, variabler, funksjoner osv.) som er synlige der UDF er definert, ikke der den kalles. Den kan ikke referere til en annen valgfri parameter i UDF.
- Type: Typekontroll mot parameterens typehint håndheves kun når standarduttrykket brukes. Hvis en kaller gir et eksplisitt argument, brukes typehintet mot det argumentet i stedet.
Eksempel: Type casting
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
Dette bruker en Scalar type, Int64 subtype og val parameterMode for forutsigbar avrunding og tekst-til-tall-tvang, i tillegg til å sikre at alle uttrykk blir ivrig evaluert. Du kan også oppnå dette ved å bare inkludere Int64 undertypen som vist i eksemplet nedenfor. Ikke-numeriske strenger vil resultere i en feil.
DEFINE
/// returns x as an Int64
FUNCTION CastToInt = (
x : INT64
) =>
x
EVALUATE
{ CastToInt ( 3.4 ), CastToInt ( 3.5 ), CastToInt ( "5" ) }
// returns 3, 4, 5
Eksempel: Tabellparameter (verdi kontra uttrykk)
Hvis du vil illustrere hvordan UDF parameterModus påvirker filterkonteksten, bør du vurdere to funksjoner som begge teller rader i Salg-tabellen. Begge bruker CALCULATETABLE(t, ALL('Date')) i kroppene sine, men den ene parameteren er erklært som en val (ivrig evaluering) og den andre som expr (lat evaluering):
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 returnerer antall salg bare for RÅ2020. Salgstabellen er allerede filtrert etter året før du går inn i funksjonen, så ALL('Date') inne i funksjonen har ingen effekt.
CountRowsLater returnerer antall salg for alle år. Funksjonen mottar et uevaluert tabelluttrykk og evaluerer det under ALL('Date'), og fjerner det eksterne år-filteret.
Typekontroll
Typekontroll i UDF-er kan gjøres med nye og eksisterende typekontrollfunksjoner som du kan kalle inne i funksjonsteksten for å bekrefte kjøretidstypen for passerte parametere. Dette gjør at UDF-er kan bruke kontekstkontroll, validere parametere på forhånd, normalisere innganger før beregning.
Note
For expr parameterMode-parametere utføres typekontroller når parameteren refereres til i funksjonsteksten (ikke på funksjonskalltidspunktet).
Tilgjengelige typekontrollfunksjoner
UDF-er kan bruke følgende funksjoner til å teste skalarverdier. Hver retur TRUE/FALSE avhenger av om verdien som er oppgitt, er av den typen.
| Kategori | Functions |
|---|---|
| Numerisk | ERTALL,ISNUMBER |
| Dobbel | ISDOUBLE |
| Heltall | ISINT64, HELTALL |
| Decimal | ISDECIMAL,ERCURRENCY |
| Streng | ISSTRING,ISTEXT |
| boolsk | ISBOOLSK,ISLOGICAL |
| Dato og klokkeslett | ISDATETIME |
Eksempel: Sjekk om parameteren er en streng
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
Dette forhindrer feil og lar deg bestemme hvordan du skal håndtere ikke-strenginngang i funksjonen (i dette eksemplet returnerer BLANK).
Eksempel: Godta flere parametertyper
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"
Dette eksemplet viser hvordan du bruker typekontroll i UDF-er til å godta flere inndatatyper på en sikker måte og returnere ett enkelt, forutsigbart resultat.
GetCurrencyName tar ett argument, currency, som kan være enten en heltallsvalutanøkkel eller en tekstvalutakode. Funksjonen kontrollerer argumenttypen med ISINT64. Hvis inndataene er et heltall, kaller den hjelperen GetCurrencyNameByKey som slår opp valutanavnet basert på valutanøkkelen. Hvis inndataene ikke er et heltall, kaller den hjelperen GetCurrencyNameByCode som slår opp valutanavnet basert på valutakoden.
Nyttige informasjonsfunksjoner
Følgende informasjonsfunksjoner er nyttige når man lager UDF-er:
- TABLEOF: Returnerer hele tabellen knyttet til en gitt kolonne, mål eller kalender.
- NAMEOF: Returnerer navnet på en tabell, kolonne, mål eller kalender som en tekststreng
Eksempel: En MODEX-funksjon
Følgende eksempel viser en grunnleggende implementering av en MODEX-funksjon som returnerer den hyppigst forekommende verdien(e) av et uttrykk evaluert over en tabell. Den brukes TABLEOF til automatisk å løse riktig tabell ut fra den gitte referansen.
DEFINE
FUNCTION MODEX = (
e : ANYREF
) =>
VAR newTable =
ADDCOLUMNS ( TABLEOF ( e ), "expr", e )
VAR freqTable =
GROUPBY ( newTable, [expr], "count", SUMX ( CURRENTGROUP (), 1 ) )
VAR maxCount =
MAXX ( freqTable, [count] )
VAR topResults =
FILTER ( freqTable, [count] = maxCount )
RETURN
SELECTCOLUMNS ( topResults, "expr", [expr] )
EVALUATE
MODEX ( [Total Sales] )
Definer flere funksjoner samtidig
UDF-er lar deg definere flere funksjoner i en enkelt spørring eller skript, noe som gjør det enkelt å organisere gjenbrukbar logikk. Dette er spesielt nyttig når du vil innkapsle relaterte beregninger eller hjelperutiner sammen. Funksjoner kan evalueres sammen eller hver for seg.
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
Avansert eksempel: Fleksibel valutakonvertering
For å vise hvordan DAX UDF-er kan håndtere mer kompleks logikk, vil vi se på et valutakonverteringsscenario. I dette eksemplet brukes typekontroll og nestede funksjoner til å konvertere et gitt beløp til en målvaluta ved hjelp av enten gjennomsnitts- eller valutakursen på slutten av dagen for en gitt dato.
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
Funksjonen ConvertToCurrency aksepterer fleksible inndatatyper for både valuta og dato. Brukere kan angi enten en valutanøkkel eller datonøkkel direkte eller angi en valutakode eller standard datoverdi. Funksjonen kontrollerer typen til hver inngang og håndterer den deretter: hvis pCurrency det er et heltall, behandles det som en valutanøkkel, ellers antar funksjonen en valutakode og prøver å løse den tilsvarende nøkkelen.
pDate følger et lignende mønster, hvis det er et helt tall, behandles det som en datonøkkel; Ellers antar funksjonen at det er en standard datoverdi og konverteres til en datonøkkel ved hjelp av ConvertDateToDateKey hjelpefunksjonen. Hvis funksjonen ikke kan bestemme en gyldig ekseksjonskurs, returnerer den meldingen "ingen valutakurs tilgjengelig".
Denne logikken kan deretter brukes til å definere et mål, for eksempel Totalt salg i lokal valuta.
Total Sales in Local Currency =
ConvertToCurrency (
SELECTEDVALUE ( 'Currency'[Code] ),
SELECTEDVALUE ( 'Date'[DateKey] ),
TRUE,
[Total Sales]
)
Dette kan eventuelt pares med en dynamisk formatstreng for å vise resultatet i riktig valutaformat.
CALCULATE (
MAX ( 'Currency'[Format String] ),
'Currency'[Code] == SELECTEDVALUE ( 'Currency'[Code] )
)
Et eksempelresultat kan sees i skjermbildet nedenfor.
Hensyn og begrensninger
Brukerdefinerte funksjoner har følgende begrensninger:
Generelt:
Kan ikke skjule/vise en UDF i modellen.
Kan ikke plassere UDF-er i visningsmapper.
Kan ikke kombinere UDF-er med oversettelser.
UDF-er støttes ikke i modeller uten tabeller.
Ingen 'definer med referanser' hurtigspørring i DAX spørringsvisning.
UDF-er i en live-tilkoblet modell vises ikke i modellutforskervisningen.
Object-Level Security (OLS) overføres ikke til funksjoner eller omvendt. For eksempel, vurder følgende funksjon
Fsom refererer til sikret målMyMeasure:function F = () => [MyMeasure] + 42når sikringen
MyMeasuresikres med objektnivåsikkerhet, sikres ikke funksjon F automatisk. HvisFkjører under en identitet uten tilgang tilMyMeasure, oppfører den seg som omMyMeasureikke eksisterer. Vi anbefaler å unngå å avsløre sikre objekter i funksjonsnavn og beskrivelser.Formeljustering og avhengighetsberegning støttes, med en kjent begrensning rundt ukvalifiserte navn. Fordi ukvalifiserte navn tolkes som målreferanser, kan de ikke pålitelig fastsettes eller inkluderes i avhengighetssporing når de er ment å referere til kolonner. Et ukvalifisert navn er en objektreferanse som ikke inkluderer et tabellprefiks.
Definere en UDF:
- Rekursjon eller gjensidig rekursjon støttes ikke.
- Overbelastning av funksjoner støttes ikke.
- Eksplisitt returtype støttes ikke.
UDF-parametere:
- Parameterbeskrivelser støttes ikke.
- UDF-er kan ikke returnere en
enumverdi. Innebygde funksjoner som godtarenumverdier som funksjonsparametere, kan ikke bruke UDF-er i denne sammenhengen. - Ubundne parametere av typen hint
exprevalueres ikke.
IntelliSense-støtte:
- Selv om rapportbaserte målinger i en live connect-rapport kan referere til UDF-er deklarert i kildemodellen, finnes det ingen IntelliSense-støtte. Modellbaserte mål i en sammensatt modell kan ikke referere til UDF-er deklarert i kildemodellen.
- Selv om UDF-er kan brukes i visuelle beregninger, har ikke formellinjen for visuelle beregninger IntelliSense-støtte for UDF-er.
- TMDL-utvidelsen for Visual Studio Code har begrenset IntelliSense-støtte for UDF-er.
- SQL Server Management Studio har ikke IntelliSense-støtte for UDF-er.
- Visse avanserte bruk av UDF-er kan føre til parser-inkonsistenser. Brukere kan for eksempel se røde understrekinger eller valideringsfeil når de sender kolonner som
exprparametere eller bruker ukvalifiserte kolonnereferanser.