Forum Discussion
REPLACE Function Returning Unexpected Results
AlbertoFerrari marcorusso and Comunity
This is my first question in the Power Bi Comunity and I realy need your help. Any input would be highly appreciated.
Usually I prefer to search, study and find answers by myself. This time I give up. I searched everywhere and I could not find an answer to my problem. Please allow me to explain in some details and I hope you will be able to read this and provide an answer.
I was writing a DAX code that is supposed to capitalize the first letter of each word. For some reasons, SQL and PQ are not an option and DAX is the only option. I had an idea in my mind and started writing the code and everything was going smooth as planned. Except when I reached the part where I needed to use the EVIL function REPLACE and his EVIL twin SUBSTITUDE
The goal was to create a calculated column, however, I also created a calculated table just to see how the code behaves step by step.
Here is a sample file https://we.tl/t-yN1a77H4fP
And this is the DAX code
Title Case =
VAR CurrentTitle = SELECTCOLUMNS ( FILTER ('Table', 'Table'[Title] = "set field title case" ), "@Title", [Title] )
VAR Length = LEN ( CurrentTitle )
VAR T1 = GENERATESERIES ( 1, Length, 1 )
VAR T2 = ADDCOLUMNS ( T1, "@Title", CurrentTitle, "@SapceLocation", FIND ( " ", CurrentTitle, [Value], BLANK ( ) ) )
VAR T3 = FILTER ( T2, [Value] = 1 || [@SapceLocation] = [Value] )
VAR T4 = ADDCOLUMNS ( T3, "@LetterLocation", IF ( [Value] = 1, 1, [Value] + 1 ) )
VAR T5 = ADDCOLUMNS ( T4, "@FirstLetter", MID ( [@Title], [@LetterLocation], 1 ) )
VAR T6 = ADDCOLUMNS ( T5, "@CapitalLetter", UPPER ( [@FirstLetter] ) )
VAR T7 = ADDCOLUMNS ( T6, "@TitleCase", REPLACE ( [@Title], [@LetterLocation] + 1, 1, [@CapitalLetter] ) )
VAR Result =
{
CONCATENATEX (
T7,
VAR CurrentLocation = [@LetterLocation]
VAR PreviousLocation = MAXX ( FILTER ( T7, [@LetterLocation] < CurrentLocation ), [@LetterLocation] )
VAR NumOfCharachtors = CurrentLocation - PreviousLocation - 1
RETURN
MID ( [@TitleCase], [@LetterLocation], NumOfCharachtors ),
" ",
[@LetterLocation],
ASC
)
}
RETURN
ResultAttached screenshots explains everything
In the first screenshot you can see the REPLACE is stuck!. It only replaces the first letter of the first word with the first capital letter. It is like ADDCOLUMNS is not iterating over the table and is just returning the first result over all the rows!
In the 2nd screenshot I just added (+1) and now the code works perfectly except that it replaces the wrong letters.
I even tried to change the column values manually, using other columns and creating new columns, it ALWAYS works perfectly except when it should produce the result that I want!!!
Also I tried creating index column and use it in SUBSTITUTE function, tried with a calculated column and even a measure and the results are even worse.
I searched every where just to understand how this function really works and why DAX can sometimes be so mean and evil. Unfortunately, could not find the answer. Please help me sleep again.
Best of the best regards,
Tamer
tamerj1 so, becasue until someone else will say otherwise, you found a bug π
In the mean time, I just jumped over it and solved it in another way (I'm adding the DAX Query):EVALUATE VAR _CurrentTitle = SELECTCOLUMNS ( FILTER ('Table', 'Table'[Title] = "set field title case" ), "@Title", [Title] ) VAR _Length = LEN ( _CurrentTitle ) VAR T1 = GENERATESERIES ( 1, _Length, 1 ) VAR T2 = ADDCOLUMNS ( T1, "@Title", _CurrentTitle, "@SapceLocation", FIND ( " ", _CurrentTitle, [Value], BLANK ( ) ) ) VAR T3 = FILTER ( T2, [Value] = 1 || [@SapceLocation] = [Value] ) VAR T4 = ADDCOLUMNS ( T3, "@LetterLocation", IF ( [Value] = 1, 1, [Value] + 1 ) ) VAR T5 = ADDCOLUMNS ( T4, "@FirstLetter", MID ( [@Title], [@LetterLocation], 1 ) ) VAR T6 = ADDCOLUMNS ( T5, "@CapitalLetter", UPPER ( [@FirstLetter] & "" ) ) VAR T7 = ADDCOLUMNS( T6, "@Extracted Letter", MID ( [@Title], [@LetterLocation], COALESCE( MINX( FILTER( T6, [@LetterLocation] > EARLIER([@LetterLocation]) ), VALUE([@LetterLocation]) ), _Length * 3 ) - [@LetterLocation] - 1 ) ) VAR T8 = ADDCOLUMNS ( T7, "@Extracted Letter Title Case", REPLACE ( [@Extracted Letter], 1, 1, [@CapitalLetter] ) ) VAR Result = { CONCATENATEX ( T8, [@Extracted Letter Title Case], " ", [@LetterLocation], ASC ) } RETURN Result
13 Replies
- SpartaBICommunity Champion
tamerj1 so, becasue until someone else will say otherwise, you found a bug π
In the mean time, I just jumped over it and solved it in another way (I'm adding the DAX Query):EVALUATE VAR _CurrentTitle = SELECTCOLUMNS ( FILTER ('Table', 'Table'[Title] = "set field title case" ), "@Title", [Title] ) VAR _Length = LEN ( _CurrentTitle ) VAR T1 = GENERATESERIES ( 1, _Length, 1 ) VAR T2 = ADDCOLUMNS ( T1, "@Title", _CurrentTitle, "@SapceLocation", FIND ( " ", _CurrentTitle, [Value], BLANK ( ) ) ) VAR T3 = FILTER ( T2, [Value] = 1 || [@SapceLocation] = [Value] ) VAR T4 = ADDCOLUMNS ( T3, "@LetterLocation", IF ( [Value] = 1, 1, [Value] + 1 ) ) VAR T5 = ADDCOLUMNS ( T4, "@FirstLetter", MID ( [@Title], [@LetterLocation], 1 ) ) VAR T6 = ADDCOLUMNS ( T5, "@CapitalLetter", UPPER ( [@FirstLetter] & "" ) ) VAR T7 = ADDCOLUMNS( T6, "@Extracted Letter", MID ( [@Title], [@LetterLocation], COALESCE( MINX( FILTER( T6, [@LetterLocation] > EARLIER([@LetterLocation]) ), VALUE([@LetterLocation]) ), _Length * 3 ) - [@LetterLocation] - 1 ) ) VAR T8 = ADDCOLUMNS ( T7, "@Extracted Letter Title Case", REPLACE ( [@Extracted Letter], 1, 1, [@CapitalLetter] ) ) VAR Result = { CONCATENATEX ( T8, [@Extracted Letter Title Case], " ", [@LetterLocation], ASC ) } RETURN Result- tamerj1Community Champion
SpartaBI
This is amazing! splitting the sentence into words bypassed the the "bug" π Great job my friend!!!As small problem when having a single word. The extraction seems to miss the last letter. I guess you can solve that. Otherwise it works perfect!
On the other hand I hope DAX experts can confirm if this is really a bug or this is just a DAX behaviour which we could not understand. I Don't want to be rude but AlbertoFerrari and marcorusso who's more competent than you guys to answer this question.- SpartaBICommunity Champion
tamerj1 my pleasure my friend π I was very happy I had a chance to help you.
I really appreciate your skills.
Regarding the one word, so basically it's just the scenario when the coalesce kicks in, so just need to have there a large enough number. I'm editing the code now in the original message and changing it to be _Lentgh * 3
- tamerj1Community Champion
Thank you SpartaBI for your response.
I want to get Set Field Title Case
I gues there might be more simple solutions. This for sure will be of my intrest. However, it is now more interesting to me to understand why does this function behave this way! What was the mistake which I was not able to spot?!
- SpartaBICommunity Champion
tamerj1 ye, I got now to T7 and looking at the bug haha
Indeed just the fact that it doens't work with
REPLACE ( [@Title], [@LetterLocation], 1, [@CapitalLetter] ) )
But works with
REPLACE ( [@Title], [@LetterLocation] + 1, 1, [@CapitalLetter] ) )
looks like some interesting edge case π