When building KPI charts in Qlik Sense, automatic number formatting is a time-saving function that adjusts values using SI symbols to fit the available space. For example, it shows 875 as it is, 23,475 as 23.4k, and 45,600,000 as 45.6M.
But what happens when you need to display currency? Switching to the "Money" format removes this smart adjustment, forcing you to choose between potentially illegible KPIs due to long numbers, or fixed magnitude formatting (e.g., always in millions), which makes small values look ridiculous (0.000001 M).
Here is how I solved this limitation.
Symptoms:
Example:
This is a limitation in Qlik Sense. The built-in "Money" format does not support dynamic SI scaling. It applies a fixed format, ignoring the value's magnitude.
The workaround:
We debated using nested ifs to check the size of the measure and adjust formatting accordingly. This would work but impacted performance.
For technical reasons, which are far beyond the scope of this blog post, in the Qlik Engine, the calculation path of IF statements is counter-intuitive.
Step one: the engine calculates each possible outcome of the IF for every row of data in the hypercube, that is both the result if true and the result if false.
Step two: the IF statement is resolved and the result set is collapsed with the invalidated values discarded.
This means that the calculation cost of the IF statement grows rapidly with depth and the size of the data set. If we used this logic in multiple measures in the same sheet we could quickly find we over-run our resource limits.
I turned to mathematics for a solution and this was the result:
This approach preserved dynamic scaling and added the currency symbol.
Define a variable in Qlik Sense (e.g., CurrencyFormat) with the expression shown below (note: we do not want the value of this expression to be calculated, so we do not need a preceding ‘=‘):
|
1 PICK( 2 floor(log10($1)/log10(1000))+1, // the absolute value of our parameter in thousands 3 NUM($1/POW(10,floor(log10($1)/log10(1000))*3),'£##0.00'), // the format for units 4 NUM($1/POW(10,floor(log10($1)/log10(1000))*3),'£##0.00k'), // the format for thousands (k) 5 NUM($1/POW(10,floor(log10($1)/log10(1000))*3),'£##0.00M'), // the format for millions (M) 6 NUM($1/POW(10,floor(log10($1)/log10(1000))*3),'£##0.00B') // the format for billions (B) 7 ) |
You may notice that the expression looks a little odd. This is because we are creating a parameterised variable which acts like a custom function. When we call the variable, we provide $1 as a placeholder for the input we will use.
We use: =$(parameterizedVariable(Value to pass))
e.g., =$(CurrencyFormat(<MeasureValue>))
To apply the variable in KPI expression we need data to work with. The following load script will create a table of random values of varying magnitudes:
|
1 num: 2 Load 3 POW(RAND(),5) * 1000000000000 as Number, 4 POW(RAND(),5) * 1000000000000 as Number2, 5 POW(RAND(),5) * 1000000000000 as Number3 6 Autogenerate (1000); 7 |
Once the data load is complete you can apply the formatting in your chart object as follows:
Ensure that you change the Number Formatting to “Measure Expression.”
By making selections validate that the KPI using the "CurrencyFormat" parameterized variable demonstrates the expected behaviour, i.e.:
|
1. ‘875’ → ‘£875’ 2. ‘23,475’ → ‘£23.4k’ 3. ‘45,600,000’ → ‘£45.6M’ 4. ‘12,345,600,000’ → ‘£12.3B’ |
This workaround gives you the best of both worlds: currency formatting + dynamic SI scaling.
Have you used parametrized variables to improve your apps in Qlik Sense? What are your favourite features? Share your tips in the comments!
We’re the UK’s #1 Qlik Partner. With 250+ customers and 25 experts, we can help you with implementation, training, or support.
Not sure where to start? Book a call with our experts today!