Want to format a measure based on a slicer selection, the measure value, or another conditional way? Now you can! With dynamic format strings for measures a DAX expression can now be used to determine what format string a measure will use.
These dynamic format strings for measures are the same dynamic format strings already available in calculation groups! If you are familiar with these in calculation items, the DAX patterns you used there are applicable here to individual measures. Learn more about calculation groups at https://aka.ms/calculationgroups.
The FORMAT function can also be used in a measure DAX expression to conditionally apply a format string, but the drawback is if the measure was a numeric data type, the use of FORMAT changes the measure to a text data type. As a text data type the measure is then no longer usable as values in visuals. To maintain the measure as a numeric data type and conditionally apply a format string, you can now use dynamic format strings for measures to get around this drawback!
Dynamic format strings for measures is in public preview. To use this feature first go to File > Options and settings > Options > Preview features and check the box next to Dynamic format strings for measures.
To add a dynamic format string to a measure,
- Click on the measure in the Data pane.
- In Measure tools ribbon, expand the Format list box.
- Then choose Dynamic.
- Now a new list box should appear to the left of the DAX formula bar with Formatย selected. This list box is how I can switch between the measure DAX expression and the dynamic format string DAX expression. The static format string the measure had before switching to Dynamic will be pre-populated as a string in the DAX formula bar.
- I can overwrite this pre-populated string with whatever DAX expression will output the desired format string for my measure. In this case I am looking up the appropriate currency format string from the โCountry Currency Format Stringsโ table and enter this DAX expression:
SELECTEDVALUEย (
ย ย ย ย ‘Countryย Currencyย Formatย Strings'[Format],
ย ย ย ย “\$#,0.00;(\$#,0.00);\$#,0.00”
) - I click the check mark to save the dynamic format string for my measure to the model.
- Then I can see the dynamic format string working in the visual.
To remove the dynamic format string and return to using one of the static format strings:
- After selecting the measure in the Data pane, I go to the Measure tools ribbon and expand the Format list box.
- I can pick any other format option.
- A dialog will appear asking if I want to proceed as there is no undo to this action. Click Change to proceed. To go back to using a dynamic format string, I will have to provide the DAX expression again.
Here are some examples to get you started on creating dynamic format strings for measures in your own reports.
1) Currency conversion and showing the results with the correct currency format string โ A common scenario is in a report converting from one currency to another. When the value is converted, the report should show the converted currency in the appropriate format.
There are step by step instructions available at https://learn.microsoft.com/power-bi/create-reports/desktop-dynamic-format-strings#example to set up the Adventure Works 2020 PBIX file with the needed tables for this currency conversion example.
Here in my Adventure Works 2020 data model, I have the yearly conversion rates for some countries in the table โYearly Average Exchange Ratesโ.
I also have a table with the countries I want to convert to, and their currency format strings as the ‘Country Currency Format Strings’ table.
To join these to my existing tables, I add relationships to the new tables.
First, I create a relationship between the โCountry Currency Format Stringsโ table and โYearly Average Exchange Ratesโ on the Country column. Make the relationship one to many and so that โCountry Currency Format Stringsโ filters โYearly Average Exchange Ratesโ.
Second, I create a relationship between the โDateโ table and the โYearly Average Exchange Ratesโ table on the Year column. Make the relationship many to many and so that โDateโ table filtersโ the โYearly Average Exchange Ratesโ table.
With all this set up, I then create a measure to compute the exchange rate with this DAX expression:
IFย (
ย ย ย ย ISBLANKย (
ย ย ย ย ย ย ย ย SELECTEDVALUEย (ย ‘Countryย Currencyย Formatย Strings'[Country]ย )
ย ย ย ย )
ย ย ย ย ย ย ย ย ||ย SELECTEDVALUEย (ย ‘Countryย Currencyย Formatย Strings'[Country]ย )ย =ย “Unitedย States”,
ย ย ย ย 1,
ย ย ย ย AVERAGEย (ย ‘Yearlyย Averageย Exchangeย Rates'[Yearlyย Averageย Exchangeย Rate]ย )
)
And then I create the measure [Converted Sales Amount] to convert my existing [Sales Amount] measure to other currencies with this DAX expression:
Convertedย Salesย Amountย =
SUMXย (
ย ย ย ย ‘Date’,
ย ย ย ย CALCULATEย (
ย ย ย ย ย ย ย ย [Salesย Amount]ย *ย [Exchangeย Rateย (Yearlyย Avg)]
ย ย ย ย )
)
Finally, I define a dynamic format string DAX expression to apply the correct format string on [Converted Sales Amount] measure.
ย ย ย ย ‘Countryย Currencyย Formatย Strings'[Format],
ย ย ย ย “\$#,0.00;(\$#,0.00);\$#,0.00”
)
Now when a country is selected in the slicer, the [Converted Sales Amount] shows not only the converted [Sales Amount] but also shows the value in the specified format. And because this is done with the dynamic format strings for measures, the underlying data type of the measure remains numeric and is usable in any visual like before.
2) User driven format strings โ Different teams may want to see the report formatted in different ways for their reporting needs. Dynamic format strings for measures can be report user driven to indicate how they want to see the number formatted. And in some formatting cases, such as when abbreviating 1,000s, the dynamic format strings for measures can also conditionally format based on the measure value.
For the top slicer I create a calculated table to define the format strings in my model. In Modeling ribbon I click on New table and enter the following DAX expression:
DATATABLEย (
ย ย ย ย “Select”,ย STRING,
ย ย ย ย “Formatย Stringย forย $”,ย STRING,
ย ย ย ย {
ย ย ย ย ย ย ย ย {ย “inย Kย (1,000s)”,ย “$#,##0,.0ย K”ย },
ย ย ย ย ย ย ย ย {ย “inย Mย (1,000s)”,ย “$#,##0,.0ย M”ย },
ย ย ย ย ย ย ย ย {ย “๐ต“,ย “$#,##0๐ต“ย },
ย ย ย ย ย ย ย ย {ย “Full”,ย “$#,##0”ย },
ย ย ย ย ย ย ย ย {ย “Fullย withย decimals”,ย “$#,##0.00”ย }
ย ย ย ย }
)
Which looks like this in the Data view:
Now I create this measure:
Then I go to the Measure tools ribbon and choose Dynamic from the Format list box. In the DAX formula bar, I enter the following dynamic format string DAX expression:
ย ย ย ย LEFTย (
ย ย ย ย ย ย ย ย SELECTEDVALUEย (ย ‘Selectย format'[Select]ย ),
ย ย ย ย ย ย ย ย 2
ย ย ย ย )ย =ย “in”
ย ย ย ย ย ย ย ย &&ย SELECTEDMEASUREย ()ย <ย 1000,
ย ย ย ย “$#,##0”,
ย ย ย ย SELECTEDVALUEย (
ย ย ย ย ย ย ย ย ‘Selectย format'[Formatย Stringย forย $],
ย ย ย ย ย ย ย ย “$#,##0.00”
ย ย ย ย )
)
I could have alternatively also written it without using SELECTEDMEASURE() using the measure name itself, [Sales Amount (Pick)], like this:
ย ย ย ย LEFTย (
ย ย ย ย ย ย ย ย SELECTEDVALUEย (ย ‘Selectย format'[Select]ย ),
ย ย ย ย ย ย ย ย 2
ย ย ย ย )ย =ย “in”
ย ย ย ย ย ย ย ย &&ย [Salesย Amountย (Pick)]ย <ย 1000,
ย ย ย ย “$#,##0”,
ย ย ย ย SELECTEDVALUEย (
ย ย ย ย ย ย ย ย ‘Selectย format'[Formatย Stringย forย $],
ย ย ย ย ย ย ย ย “$#,##0.00”
ย ย ย ย )
)
With this now in place, the visuals with [Sales Amount (Pick)] will show the value in the specified format. In the cases where abbreviating to 1000s such as when using K to abbreviate, any number under 1000 will show the full value and not be abbreviated.
3) Measure driven format strings โ In the previous example the measure itself was used to determine how the value would be formatted when abbreviated by 1000s. I can take this further and have the measure value fully determine the abbreviation limits and formatting. This is like the โAutoโ option in display units on visuals, but now I get to define exactly how it works with my measure using dynamic format strings.
I create a new measure called [Sales Amount (Auto)] defined as:
And I add this dynamic format string expression to [Sales Amount (Auto)]:
ย ย ย ย TRUEย (),
ย ย ย ย SELECTEDMEASUREย ()ย <ย 1000,ย “$#,##0”,
ย ย ย ย SELECTEDMEASUREย ()ย <ย 1000000,ย “$#,##0,.0K”,
ย ย ย ย “$#,##0,,.0M”
)
If I had negative values, I could include those limits, and if I had very large numbers, I could also abbreviate and format them appropriately too. Now the visuals will show this measure abbreviated and in format I have defined:
4) Locale driven currency conversion โ I may know the locale of the country I am converting to, but not the exact currency format rules, or noticed it is tricky to get that format string correct for currencies that flip the . and , in their format strings. Here we can leverage the updated FORMAT function that can also take a locale argument! When used with the dynamic format strings for measures we can still keep the measure as a numeric data type and use FORMAT. The drawback to this approach is you cannot customize the currency format string for that locale further.
I create the Locale table using the Modeling ribbonโs New table and enter the following DAX expression:
DATATABLEย (
ย ย ย ย “Locale”,ย STRING,
ย ย ย ย “Country”,ย STRING,
ย ย ย ย {
ย ย ย ย ย ย ย ย {ย “en-US”,ย “Unitedย States”ย },
ย ย ย ย ย ย ย ย {ย “de-DE”,ย “Euroย Zone”ย },
ย ย ย ย ย ย ย ย {ย “pt-BR”,ย “Brazil”ย },
ย ย ย ย ย ย ย ย {ย “fr-FR”,ย “Euroย Zone”ย },
ย ย ย ย ย ย ย ย {ย “en-AU”,ย “Australia”ย },
ย ย ย ย ย ย ย ย {ย “fr-CA”,ย “Canada”ย },
ย ย ย ย ย ย ย ย {ย “da-DK”,ย “Denmark”ย },
ย ย ย ย ย ย ย ย {ย “en-SE”,ย “Sweden”ย },
ย ย ย ย ย ย ย ย {ย “se-SE”,ย “Sweden”ย },
ย ย ย ย ย ย ย ย {ย “en-CH”,ย “Switzerland”ย },
ย ย ย ย ย ย ย ย {ย “en-GB”,ย “Unitedย Kingdom”ย },
ย ย ย ย ย ย ย ย {ย “ja-JP”,ย “Japan”ย }
ย ย ย ย }
)
I then create a relationship from the โLocaleโ table to the โCountry Currency Format Stringsโ table on the Country column. This should be many to one, and cross filtering in both directions for this example. As these are small tables and not part of a complex model, I am ok with the using cross filtering in both directions here.
I create a new measure [Converted Sales Amount (Locale)] with this DAX expression:
[Convertedย Salesย Amount]
And give [Converted Sales Amount (Locale)] measure the following dynamic format string DAX expression:
ย ย ย ย SELECTEDVALUEย (ย Locale[Locale]ย )
RETURN
ย ย ย ย “‘”
ย ย ย ย ย ย ย ย &ย FORMATย (
ย ย ย ย ย ย ย ย ย ย ย ย SELECTEDMEASUREย (),
ย ย ย ย ย ย ย ย ย ย ย ย “Currency”,
ย ย ย ย ย ย ย ย ย ย ย ย _locale
ย ย ย ย ย ย ย ย )ย &ย “‘”
The FORMAT function itself will output a string that already formatted the value of the measure into the appropriate currency format for the given locale. Because I want this string to be used literally, that is, I donโt want any part of it to be used like a format string, I am wrapping it in single quotes.
Now I can use this locale driven currency formatting in the visuals!
I can now compare the locale driven currency format strings with the first example where I defined the format string manually.
These four examples are just the beginning. I’m excited to see all the other creative ways you’ll use dynamic format strings for measures in your reports! There are some things to keep in mind using dynamic format strings for measures.
- Visual display units: Visuals have formatting options that may impact how the format string is displayed, so if the formatting is showing unexpectedly in a visual, go to the visual Format options search for โDisplay unitsโ and change it from โAutoโ to โNoneโ.
- The measure itself can be referenced directly in its dynamic format string for measures by using its name, for example [Measure A], or indirectly by using SELECTEDMEASURE().
- Report measures: Dynamic format strings for measures are only for model measures. Report measures which can be added to a live connect report cannot have dynamic format string for measures. Currently there is a bug where Dynamic does show in the Measure tools ribbon Format list box and when selected the Measure/Format drop down to the left of the DAX formula bar will show, but you cannot add a DAX expression. This will be fixed in a future release, and the report measures will not see the Dynamic option in the Format list box.
- DirectQuery over AS: When you click the Make changes to this model on a live connect report this will shift the connection to the DirectQuery over AS, and generally we allow you to make changes to the format strings of the remote model measures. For public preview of dynamic format strings for measures,
- Remote model measures with dynamic format strings defined will be blocked from making format string changes, to a static format string or to a different dynamic format string DAX expression.
- Remote model measures cannot be changed from a static format string to a dynamic format string DAX expression defined in the local model.
- Local model measures will also be blocked from using dynamic format strings for measures.
These restrictions are being explored and may change in future releases of Power BI Desktop.
Try dynamic format strings for measuresย today and learn more atย https://learn.microsoft.com/power-bi/create-reports/desktop-dynamic-format-strings.