DAX Workout 001 - Dynamic Format Strings

Am absolutely loving the range of solutions coming through already, and the exchange of ideas in the discussion.

This is *exactly * the dynamic we were hoping for in putting these workouts together.

Keep 'em coming, and keep up the great work, folks!

7 Likes

Kim C, Thank you for this submission, your solution was simple and easy to follow.

1 Like

I answered using the simplest method that I could find

formatted value = 
VAR val = SELECTEDVALUE(Data[Dollar Amount])
VAR Formatted = IF(val/1000000000>1, FORMAT(val/1000000000,"$#.0B"),
IF(val/1000000>1, FORMAT(val/1000000,"$#.0M"),
IF(val/1000>1, FORMAT(val/1000,"$#.0K"),
FORMAT(val, "$#"))))
RETURN Formatted
1 Like

Hi, Here my solution:
image

Dax Formula

image

3 Likes

My solution.

Dax Code

Formated Measure =
VAR _Value = MAX(‘Dollar Amount’[Dollar Amount])
VAR _NumberOfDigits =
LEN(_Value)
VAR _Switch =
SWITCH(
TRUE(),
_NumberOfDigits <=3 , Format(_Value,“$#,0”),
_NumberOfDigits > 3 && _NumberOfDigits <= 6, FORMAT(_Value, “$#,.0k”),
_NumberOfDigits > 6 && _NumberOfDigits <= 9, FORMAT(_Value, “$#,.00M”),
_NumberOfDigits > 9 , FORMAT(_Value, “$#,.0B”)
)

RETURN
_Switch

Revisited code

Formated Measure =
VAR _Value = MAX(‘Dollar Amount’[Dollar Amount])
VAR _NumberOfDigits =
LEN(INT(_Value))
VAR _Switch =
SWITCH(
TRUE(),
_NumberOfDigits <=3 , Format(_Value,“$#,0”),
_NumberOfDigits > 3 && _NumberOfDigits <= 6, FORMAT(_Value, “$#,.0k”),
_NumberOfDigits > 6 && _NumberOfDigits <= 9, FORMAT(_Value, “$#,.00M”),
_NumberOfDigits > 9 , FORMAT(_Value, “$#,.0B”)
)

RETURN
_Switch

Thanks for this workouts
Ondrej

2 Likes

@Ondrej, I think you probably will have problems when the data set will have decimal numbers. For example, 1258.56. The LEN function will return 7 and it will format as M instead of k.

4 Likes

@Ondrej ,
Adding to what @AlexandreAndrade said…what if you measure the length of the integer portion of _Value?

2 Likes

Workout001_Result

Below is the DAX code I used;

New Dollar Amount =
VAR Amount = SELECTEDVALUE(Data[Dollar Amount])

VAR FormattedAmount =
SWITCH(TRUE(),
Amount > 1000000000, CONCATENATE ( “$”,FORMAT(DIVIDE(Amount,1000000000),“0.0B”)),
Amount > 1000000, CONCATENATE ( “$”,FORMAT(DIVIDE(Amount,1000000),“0.00M”)),
Amount > 1000, CONCATENATE ( “$”,FORMAT(DIVIDE(Amount,1000),“0.0K”)),
Amount < 1000,CONCATENATE ( “$”,FORMAT(Amount,“0” )))
RETURN
FormattedAmount

1 Like

Yes, that would be the solution in my opinion. I revisited the original solution.

Thank you for the feedback @AlexandreAndrade and @kaDargo

3 Likes

I jumped in here with trepidation with very limited DAX knowledge. I had an idea of what to do but got stuck pretty quickly. I then worked through some of the simpler solutions and must say that I learnt a lot and then rewrote and compared a few of the solutions and results. Definitely an accelerated way of learning and seeing how DAX works in practice. I am not going to repost solutions that are here but thanks to all who contributed.

3 Likes

I think many of these solutions will be similar in form.

One thing that interests me is variable naming, so I gain a lot from seeing how others name theirs.

I hope you post your solution.

1 Like

I really like this one as well

Clean formatting- and easy to debug later as well

2 Likes

Hey everyone!

@tweinzapfel - Thanks for this great challenge :blush:
I saw great solutions so far and really enjoyed it.

Here is what I got:
image

And here is my solution:

Formatted Results = 
VAR SelectedAmount = SELECTEDVALUE( Data[Dollar Amount] )
RETURN
FORMAT( SUM(Data[Dollar Amount]), 
    SWITCH( TRUE,
        SelectedAmount < 1000, "$#,#", 
        SelectedAmount < 1000000, "$#,.0K",
        SelectedAmount < 1000000000, "$#,,.0M",
        "$#,,,.0B"
    )
)

Have fun :slight_smile:
Hossein

6 Likes

You get my vote for simplest to read, repeat and execute!

2 Likes

The responses are very interesting, as the output ends up being a text it works well for cards and tables.
However, it doesn’t work so well if you need to sum up the values.

I have a situation where I would like to apply this logic across a clustered column chart because i have ranges from 1 million down to 100. The auto sizing in the visual doesn’t work well.

Here are my 2 ways and solutions for Dax functions

Formatted Result (Calculated Column) =
SWITCH(
TRUE(),
LEN(FORMAT( Data[Dollar Amount], “General Number”)) >9, FORMAT(DIVIDE(Data[Dollar Amount],1000000000),“$#.0B”),
LEN(FORMAT( Data[Dollar Amount], “General Number”)) >6, FORMAT(DIVIDE(Data[Dollar Amount],1000000),“$#.00M”),
LEN(FORMAT( Data[Dollar Amount], “General Number”)) >3, FORMAT(DIVIDE(Data[Dollar Amount],1000),“$#.0K”),
FORMAT(Data[Dollar Amount], “$#”)
)

Formatted Result (Measure) =

Var vSelectedValue =
SELECTEDVALUE(Data[Dollar Amount])

Var vFormatValue =
SWITCH(
TRUE(),
vSelectedValue>=1000000000, FORMAT(DIVIDE(vSelectedValue,1000000000),“$#.0B”),
vSelectedValue>=1000000, FORMAT(DIVIDE(vSelectedValue,1000000),“$#.00M”),
vSelectedValue>=1000, FORMAT(DIVIDE(vSelectedValue,1000),“$#.0K”),
FORMAT(vSelectedValue,“$#”)
)
Capture

Return
vFormatValue

2 Likes


Learning mode…

1 Like

@DaveC How [Value1] and [Value2] is obtained. Can you explain?

VAR CalcTable = 
    TOPN(
        1,
        FILTER(
            {
                (DIVIDE(CurrentNum, 1), BLANK()), 
                (DIVIDE(CurrentNum, 1000), "K"), 
                (DIVIDE(CurrentNum, 1000000), "M"), 
                (DIVIDE(CurrentNum, 1000000000), "B")
            },
            [Value1] > 1
        ),
        [Value1],
        ASC
    )

“Value1” and “Value2” are the names that are automatically assigned to the table that was created using the { } table constructor.

{
         (DIVIDE(CurrentNum, 1), BLANK()), 
         (DIVIDE(CurrentNum, 1000), "K"), 
         (DIVIDE(CurrentNum, 1000000), "M"), 
         (DIVIDE(CurrentNum, 1000000000), "B")
}

creates a table with the result of the DIVIDE function in column “Value1” and the text strings containing the letters in column “Value2”.

Hope this makes sense…

1 Like

Ok, Excellent!