Forum Discussion
Displaying Numbers in Words
- 6 years ago
Here is a more concise version that can also be easily extended to more digit triplets, since the lookup table will be the same for each of the triplets.
Spelt2 = var l = {("1","one","eleven","ten"),("2","two","twelve","twenty"),("3","three","thirteen","thirty"), ("4","four","fourteen","fourty"),("5","five","fifteen","fifty"),("6","six","sixteen","sixty"), ("7","seven","seventeen","seventy"),("8","eight","eighteen","eighty"),("9","nine","nineteen","ninety")} var t = "0" & format(ParameterNumber[ParameterNumber Value],"#") var s = right(t,1) var d = left(right(t,2),1) var h = left(right(t,3),1) var sd = if(d="1",concatenatex(filter(l,[Value1]=s),[Value3]),concatenatex(filter(l,[Value1]=s),[Value2])) var dd = if(d>"1" || d & s = "10",concatenatex(filter(l,[Value1]=d),[Value4]) & " ") var hd = if(h>"0",concatenatex(filter(l,[Value1]=h),[Value2]) & " hundred ") return hd & dd & sdHere's the version for up to six digits:
Spelt2 = var l = {("1","one","eleven","ten"),("2","two","twelve","twenty"),("3","three","thirteen","thirty"), ("4","four","fourteen","fourty"),("5","five","fifteen","fifty"),("6","six","sixteen","sixty"), ("7","seven","seventeen","seventy"),("8","eight","eighteen","eighty"),("9","nine","nineteen","ninety")} var t = "0" & format(ParameterNumber[ParameterNumber Value],"#") var s = right(t,1) var d = left(right(t,2),1) var h = left(right(t,3),1) var ss = if(d="1",concatenatex(filter(l,[Value1]=s),[Value3]),concatenatex(filter(l,[Value1]=s),[Value2])) var dd = if(d>"1" || d & s = "10",concatenatex(filter(l,[Value1]=d),[Value4]) & " ") var hd = if(h>"0",concatenatex(filter(l,[Value1]=h),[Value2]) & " hundred ") var s2 = left(right(t,4),1) var d2 = left(right(t,5),1) var h2 = left(right(t,6),1) var ss2 = if(d2="1",concatenatex(filter(l,[Value1]=s2),[Value3]),concatenatex(filter(l,[Value1]=s2),[Value2])) var dd2 = if(d2>"1" || d2 & s2 = "10",concatenatex(filter(l,[Value1]=d2),[Value4]) & " ") var hd2 = if(h2>"0",concatenatex(filter(l,[Value1]=h2),[Value2]) & " hundred ") return if(ss2>"",hd2 & dd2 & ss2 & " thousand ") & hd & dd & ssIn action:
Anonymous
Here's What I tried to implement this using a measure.
Currently this handles upto 9999.
EX =
//Currently Handles Upto 9999
//Number to be converted into words. Replace this with SELECTEDVALUE or as desired.
VAR Number = SELECTEDVALUE(T[Value])//115
VAR NumberToText = "" & Number
VAR NoOfDigits =
LEN ( NumberToText )
VAR Ones =
SELECTCOLUMNS (
GENERATESERIES ( 0, 9, 1 ),
"Ones Digit", [Value],
"Ones Digit in Words", SWITCH (
[Value],
1, "One",
2, "Two",
3, "Three",
4, "Four",
5, "Five",
6, "Six",
7, "Seven",
8, "Eight",
9, "Nine"
)
)
VAR OneTens =
SELECTCOLUMNS (
GENERATESERIES ( 1, 9, 1 ),
"One Tens Digit", [Value],
"One Tens Words", SWITCH (
[Value],
1, "Eleven",
2, "Twelve",
3, "Thirteen",
4, "Fourteen",
5, "Fifteen",
6, "Sixteen",
7, "Seventeen",
8, "Eighteen",
9, "Nineteen"
)
)
VAR Tens =
SELECTCOLUMNS (
GENERATESERIES ( 1, 9, 1 ),
"Tens Place", [Value],
"Tens Words", SWITCH (
[Value],
1, "Ten",
2, "Twenty",
3, "Thirty",
4, "Fourty",
5, "Fifty",
6, "Sixty",
7, "Seventy",
8, "Eighty",
9, "Ninety"
)
)
VAR PlaceValue =
SELECTCOLUMNS (
GENERATESERIES ( 3, 6, 1 ),
"Place", [Value],
"Place Value", SWITCH ( [Value], 3, "Hundred", 4, "Thousand")
)
VAR X =
SELECTCOLUMNS (
GENERATESERIES ( 1, NoOfDigits, 1 ),
"Index", [Value],
"Dec",
VAR N =
INT ( Number / INT ( 1 & REPT ( "0", [Value] - 1 ) ) )
RETURN
MOD ( N, 10 )
)
VAR numberMod100 = MOD(Number, 100)
VAR Y =
ADDCOLUMNS (
X,
"Text", SWITCH (
TRUE (),
[Index] = 1, SWITCH (
TRUE (),
numberMod100 > 10
&& numberMod100 < 20, MAXX ( FILTER ( OneTens, [One Tens Digit] = [Dec] ), [One Tens Words] ),
MAXX ( FILTER ( Ones, [Ones Digit] = [Dec] ), [Ones Digit in Words] )
),
[Index] = 2, SWITCH (
TRUE (),
numberMod100 > 10
&& numberMod100 < 20, "",
MAXX ( FILTER ( Tens, [Tens Place] = [Dec] ), [Tens Words] )
),
// Handles for 1-9 and beyond index 2
IF (
[Dec] = 0,
"",
// get the Word representation of current Digit
MAXX ( FILTER ( Ones, [Ones Digit] = [Dec] ), [Ones Digit in Words] )
// Concatenate the current digit with its place value.
& " " & MAXX ( FILTER ( PlaceValue, [Place] = [Index] ), [Place Value] )
)
)
)
RETURN
CONCATENATEX(Y, [Text], " ", [Index], DESC)
This can be extended to handle every natural number with few more lines of DAX.
Hope you get the idea.
Hope lbendlin can help on this. I don't know if there's a better way than this.
Thanks
For simplified English you only need to solve for the last group of three digits, in a 1-2 pattern. Any other larger digit places are just repetition, with "thousand", "million" etc slapped on.
At least that's my theory...
- lbendlin6 years ago
Super User
Here's my version for the last three digits. "ParameterNumber[ParameterNumber value]" is the measure that you want to convert. Nothing is returned for Zero.
Spelt = var t = "000" & format(ParameterNumber[ParameterNumber Value],"#") var s = right(t,1) var ss = switch(s,"1","one","2","two","3","three","4","four","5","five","6","six","7","seven","8","eight","9","nine","") var sd = right(t,2) var sds = switch(sd,"01","one","02","two","03","three","04","four","05","five","06","six","07","seven","08","eight","09","nine","10","ten" ,"11","eleven","12","twelve","13","thirteen","14","fourteen","15","fifteen","16","sixteen","17","seventeen" ,"18","eighteen","19","nineteen","") var t1 = left(t,len(t)-1) var d = right(t1,1) var ds = switch(d,"2","twen","3","thir","4","four","5","fif","6","six","7","seven","8","eigh","9","nine","") var dd = switch(d,"0","","1","",ds & "ty ") var t2 = left(t1,len(t1)-1) var h = right(t2,1) var hs = switch(h,"1","one","2","two","3","three","4","four","5","five","6","six","7","seven","8","eight","9","nine","") var hd = switch(h,"0","",hs & " hundred ") return hd & dd & if(d<"2",sds,ss)- lbendlin6 years ago
Super User
Here is a more concise version that can also be easily extended to more digit triplets, since the lookup table will be the same for each of the triplets.
Spelt2 = var l = {("1","one","eleven","ten"),("2","two","twelve","twenty"),("3","three","thirteen","thirty"), ("4","four","fourteen","fourty"),("5","five","fifteen","fifty"),("6","six","sixteen","sixty"), ("7","seven","seventeen","seventy"),("8","eight","eighteen","eighty"),("9","nine","nineteen","ninety")} var t = "0" & format(ParameterNumber[ParameterNumber Value],"#") var s = right(t,1) var d = left(right(t,2),1) var h = left(right(t,3),1) var sd = if(d="1",concatenatex(filter(l,[Value1]=s),[Value3]),concatenatex(filter(l,[Value1]=s),[Value2])) var dd = if(d>"1" || d & s = "10",concatenatex(filter(l,[Value1]=d),[Value4]) & " ") var hd = if(h>"0",concatenatex(filter(l,[Value1]=h),[Value2]) & " hundred ") return hd & dd & sdHere's the version for up to six digits:
Spelt2 = var l = {("1","one","eleven","ten"),("2","two","twelve","twenty"),("3","three","thirteen","thirty"), ("4","four","fourteen","fourty"),("5","five","fifteen","fifty"),("6","six","sixteen","sixty"), ("7","seven","seventeen","seventy"),("8","eight","eighteen","eighty"),("9","nine","nineteen","ninety")} var t = "0" & format(ParameterNumber[ParameterNumber Value],"#") var s = right(t,1) var d = left(right(t,2),1) var h = left(right(t,3),1) var ss = if(d="1",concatenatex(filter(l,[Value1]=s),[Value3]),concatenatex(filter(l,[Value1]=s),[Value2])) var dd = if(d>"1" || d & s = "10",concatenatex(filter(l,[Value1]=d),[Value4]) & " ") var hd = if(h>"0",concatenatex(filter(l,[Value1]=h),[Value2]) & " hundred ") var s2 = left(right(t,4),1) var d2 = left(right(t,5),1) var h2 = left(right(t,6),1) var ss2 = if(d2="1",concatenatex(filter(l,[Value1]=s2),[Value3]),concatenatex(filter(l,[Value1]=s2),[Value2])) var dd2 = if(d2>"1" || d2 & s2 = "10",concatenatex(filter(l,[Value1]=d2),[Value4]) & " ") var hd2 = if(h2>"0",concatenatex(filter(l,[Value1]=h2),[Value2]) & " hundred ") return if(ss2>"",hd2 & dd2 & ss2 & " thousand ") & hd & dd & ssIn action:
- lbendlin6 years ago
Super User
apart from being a nice solution challenge this also brings out one of the uglier sides of DAX. Different from Power Query M (which has the ability to declare functions even if they are not used subsequently) there is no support in DAX for "just in case" functions or application of a measure to parts of a data point.
Let's say you have a seven digit number in you table, and you want to spell it out. Ideally you would convert the number to text, split the text into groups of three, and feed the triplets through the spelling measure, receiving the full text back.
DAX measures don't seem to work that way, they always need the entire value of an existing item to work on. They also do not support recursive calling (as far as I know).
I am not sure if calculation groups may be a possible answer to this but I highly doubt that. marcorusso