Skip to main content

Notifications

Number to word conversion tool

Currently there is no out-of-box feature available in PowerApps and Flow to convert a numerical value into word and hence this blog walks you through how to build one. This blog is an extension of Brian Dang's 'Expanded Word Form for place value' blog.

 

Scenario:
A scenario I came across was to take a numerical dollar value and convert that into a word form to be printed on pre-printed checks. Hence I created a screen which has the numerical value, the word form and the full name of the person. This blog only focuses on the numerical to word conversion piece.

 

Video:

 


Formulas:

Capture.JPG

 

Set(WholeNumberVar, First(Split(TextInput.Text,".")));If(!IsBlank(Find(".",TextInput.Text)),Set(DecimalNumberVar,Last(Split(TextInput.Text,"."))),"");

Clear(expandedForm);

// Create a table that separates each digit to include its Value and Position. Make a placeholder for its Place and Period.
ForAll(RenameColumns(Split(WholeNumberVar.Result,""),"Result","Char"),
Collect(expandedForm,
{
Value: Value(Char),
Position:
// Determine the position of each character as a difference between the length of the number and how many digits have already been collected.
Len(WholeNumberVar.Result)-CountRows(expandedForm),
Place: 0,
Period: 0
}
)
);

// Update the Place and Period using the Position.
ForAll(RenameColumns(expandedForm,"Position","Pos"),
Patch(expandedForm,LookUp(expandedForm,Pos=Position),
{
Place:
// Determine if a given column is a one, ten, or hundred based on its position.
Switch(true,
Mod(Pos-1,3)=0,1,
Mod(Pos+1,3)=0,10,
100
),
Period:
// Determine what Period a digit belongs to based on its position.
RoundUp(Pos/3,0)-1
}
)
)

 

Capture2.JPG

 

If(IsBlank(Find(".",TextInput.Text)),
Concatenate(
Concat(
GroupBy(expandedForm,"Period","PeriodGroup"),

// Read the hundred in the period.
LookUp(PlaceValue_1,Digit=LookUp(PeriodGroup,Place=100).Value,Word & " ") &

// For 10-19, read the tens and ones together, otherwise separately.
If(LookUp(PeriodGroup,Place=10).Value=1,
LookUp(PlaceValue_1,Digit=Value(Concat(Filter(PeriodGroup,Place<>100),Text(Value))),Word & " "),
Concat(Filter(PeriodGroup,Place<>100),LookUp(PlaceValue_1,Digit=Value && Column=Place,Word & " "))
) &

// Read the period.
Coalesce(LookUp(Period_1,Group=Period,Name & ", "),"")),"dollars"),
Concatenate(
Concat(
GroupBy(expandedForm,"Period","PeriodGroup"),

// Read the hundred in the period.
LookUp(PlaceValue_1,Digit=LookUp(PeriodGroup,Place=100).Value,Word & " ") &

// For 10-19, read the tens and ones together, otherwise separately.
If(LookUp(PeriodGroup,Place=10).Value=1,
LookUp(PlaceValue_1,Digit=Value(Concat(Filter(PeriodGroup,Place<>100),Text(Value))),Word & " "),
Concat(Filter(PeriodGroup,Place<>100),LookUp(PlaceValue_1,Digit=Value && Column=Place,Word & " "))
) &

// Read the period.
Coalesce(LookUp(Period_1,Group=Period,Name & ", "),"")
),Concatenate("dollars & ",DecimalNumberVar.Result,"/100 cents")))


Here's what the expandedForm collection looks like

 

Capture3.JPG

 

Conclusion:

As mentioned in the video this app is an extension of Brian Dang's app which uses Components. Attached is a zipped file contains a copy of both the Excel spreadsheet and the MSAPP file which you can use. 

Comments

*This post is locked for comments

  • tu22 Profile Picture tu22 44
    Posted at
    Number to word conversion tool

    for anyone who got the same error:

    RenameColumns(Split(WholeNumberVar.Value, ""), "Result", "Char") the function renamecolumn have some invalid argument

     

    change it .Result to .Value and it should be fine

  • tu22 Profile Picture tu22 44
    Posted at
    Number to word conversion tool

    does anyone have a solution to this yet? 

    RenameColumns(Split(WholeNumberVar.Value, ""), "Result", "Char") the function renamecolumn have some invalid argument

     

    please let me know

  • WeamGhaffar Profile Picture WeamGhaffar
    Posted at
    Number to word conversion tool

    the name 'Result' isn't valid, how can I fix this?Image.jpeg

  • Number to word conversion tool

    RenameColumns(Split(WholeNumberVar.Value, ""), "Result", "Char") the function renamecolumn have some invalid argument

  • vvvvvv Profile Picture vvvvvv 2
    Posted at
    Number to word conversion tool

    Halo, this is really nice. But when it comes to my app, it is not giving correct result whenever I try putting 20+ digits. Need help

  • jufguu Profile Picture jufguu 131
    Posted at
    Number to word conversion tool

    I want convert cents values also in the text. How can I update this code?

     

  • tbeerman6646 Profile Picture tbeerman6646 4
    Posted at
    Number to word conversion tool

    Is the issue only with the "3" or is it a problem with "40" being "4," "50" being "5," etc.?

  • simmyjer16 Profile Picture simmyjer16 18
    Posted at
    Number to word conversion tool

    @AmgadAhmed / @Adam-Artelia 

     

    I need your help 😕  It's showing as "three" instead of "thirty"

    Can you help identify what's wrong with my code? I just copy pasted it

    simmyjer16_0-1692202344991.png

    Set(varWholeNumber, First(Split(varMKTAvailGrandTotal,".")));If(!IsBlank(Find(".",varMKTAvailGrandTotal)),Set(varDecimalNumber,Last(Split(varMKTAvailGrandTotal,"."))),"");

    Clear(expandedForm);

    // Create a table that separates each digit to include its Value and Position. Make a placeholder for its Place and Period.
    ForAll(RenameColumns(Split(varWholeNumber.Value,""),"Value","Char"),
    Collect(expandedForm,
    {
    Value: Value(Char),
    Position:
    // Determine the position of each character as a difference between the length of the number and how many digits have already been collected.
    Len(varWholeNumber.Value)-CountRows(expandedForm),
    Place: 0,
    Period: 0
    }
    )
    );

    // Update the Place and Period using the Position.
    ForAll(RenameColumns(expandedForm,"Position","Pos"),
    Patch(expandedForm,LookUp(expandedForm,Pos=Position),
    {
    Place:
    // Determine if a given column is a one, ten, or hundred based on its position.
    Switch(true,
    Mod(Pos-1,3)=0,1,
    Mod(Pos+1,3)=0,10,
    100
    ),
    Period:
    // Determine what Period a digit belongs to based on its position.
    RoundUp(Pos/3,0)-1
    }
    )
    );Clear(expandedForm_Decimal);

    // Create a table that separates each digit to include its Value and Position. Make a placeholder for its Place and Period.
    ForAll(RenameColumns(Split(varDecimalNumber.Value,""),"Value","Char"),
    Collect(expandedForm_Decimal,
    {
    Value: Value(Char),
    Position:
    // Determine the position of each character as a difference between the length of the number and how many digits have already been collected.
    Len(varDecimalNumber.Value)-CountRows(expandedForm_Decimal),
    Place: 0,
    Period: 0
    }
    )
    );

    // Update the Place and Period using the Position.
    ForAll(RenameColumns(expandedForm_Decimal,"Position","Pos"),
    Patch(expandedForm_Decimal,LookUp(expandedForm_Decimal,Pos=Position),
    {
    Place:
    // Determine if a given column is a one, ten, or hundred based on its position.
    Switch(true,
    Mod(Pos-1,3)=0,1,
    Mod(Pos+1,3)=0,10,
    100
    ),
    Period:
    // Determine what Period a digit belongs to based on its position.
    RoundUp(Pos/3,0)-1
    }
    )
    );

     

    //Text to read as words
    Set(varAmountInWords,
    If(IsBlank(Find(".",varMKTAvailGrandTotal)),
    Concatenate(
    Concat(
    GroupBy(expandedForm,"Period","PeriodGroup"),

    // Read the hundred in the period.
    LookUp(PlaceValue_1,Value(Dig)=LookUp(PeriodGroup,Value(Place)=100).Value,Word & " ") &

    // For 10-19, read the tens and ones together, otherwise separately.
    If(Value(LookUp(PeriodGroup,Value(Place)=10).Value)=1,
    LookUp(PlaceValue_1,Value(Dig)=Value(Concat(Filter(PeriodGroup,Value(Place)<>100),Text(Value))),Word & " "),
    Concat(Filter(PeriodGroup,Value(Place)<>100),LookUp(PlaceValue_1,Value(Dig)=Value(Value) && Value(Col)=Value(Place),Word & " "))
    ) &

    // Read the period.
    Coalesce(LookUp(Period_1,Value(Group)=Value(Period),Name & " "),"")),"Pounds"),
    Concatenate(
    Concat(
    GroupBy(expandedForm,"Period","PeriodGroup"),

    // Read the hundred in the period.
    LookUp(PlaceValue_1,Value(Dig)=Value(LookUp(PeriodGroup,Value(Place)=100).Value),Word & " ") &

    // For 10-19, read the tens and ones together, otherwise separately.
    If(Value(LookUp(PeriodGroup,Value(Place)=10).Value)=1,
    LookUp(PlaceValue_1,Value(Dig)=Value(Concat(Filter(PeriodGroup,Value(Place)<>100),Text(Value))),Word & " "),
    Concat(Filter(PeriodGroup,Value(Place)<>100),LookUp(PlaceValue_1,Value(Dig)=Value(Value) && Value(Col)=Value(Place),Word & " "))
    ) &

    // Read the period.
    Coalesce(LookUp(Period_1,Value(Group)=Value(Period),Name & ", "),"")
    ),Concatenate("Pounds & ",Concat(
    GroupBy(expandedForm_Decimal,"Period","PeriodGroup"),


    // Read the period.
    Coalesce(LookUp(Period_1,Value(Group)=Value(Period),Name & " "),""))),
    Concatenate(
    Concat(
    GroupBy(expandedForm_Decimal,"Period","PeriodGroup"),

    // Read the hundred in the period.
    LookUp(PlaceValue_1,Value(Dig)=Value(LookUp(PeriodGroup,Value(Place)=100).Value),Word) &

    // For 10-19, read the tens and ones together, otherwise separately.
    If(Value(LookUp(PeriodGroup,Value(Place)=10).Value)=1,
    LookUp(PlaceValue_1,Value(Dig)=Value(Concat(Filter(PeriodGroup,Value(Place)<>100),Text(Value))),Word & " "),
    Concat(Filter(PeriodGroup,Value(Place)<>100),LookUp(PlaceValue_1,Value(Dig)=Value(Value) && Value(Col)=Value(Place),Word & " "))
    ) &

    // Read the period.
    Coalesce(LookUp(Period_1,Value(Group)=Value(Period),Name & ", "),"")
    ),"Pence"))));

  • efraimmoreira33 Profile Picture efraimmoreira33
    Posted at
    Number to word conversion tool

    Very good!

    How would I do, in the cents part, instead of displaying the number, display it in full writing?

    Thanks!

  • AmgadAhmed Profile Picture AmgadAhmed 2
    Posted at
    Number to word conversion tool

    I took the existing codes and stored the output in a variable with the ability to specify the type of currency

    thanks @darogael and @Adam-Artelia 

    Text input chose between USD or another currency Lbl_Cur.Text

    output stored in variable called NumWord

    Onchange of DataCardValue124.Text

     

    Set(Varcurrency ,If(Lbl_Cur.Text="USD"," Dollars "," Yemeni Rial "));
    Set(VarcurrencyDiv,If(Lbl_Cur.Text="USD"," Cents "," Fils "));
    
    Set(WholeNumberVar, First(Split(DataCardValue124.Text,".")));If(!IsBlank(Find(".",DataCardValue124.Text)),Set(DecimalNumberVar,Last(Split(DataCardValue124.Text,"."))),"");
    
    Clear(expandedForm);
    
    // Create a table that separates each digit to include its Value and Position. Make a placeholder for its Place and Period.
    ForAll(RenameColumns(Split(WholeNumberVar.Result,""),"Result","Char"),
    Collect(expandedForm,
    {
    Value: Value(Char),
    Position:
    // Determine the position of each character as a difference between the length of the number and how many digits have already been collected.
    Len(WholeNumberVar.Result)-CountRows(expandedForm),
    Place: 0,
    Period: 0
    }
    )
    );
    
    // Update the Place and Period using the Position.
    ForAll(RenameColumns(expandedForm,"Position","Pos"),
    Patch(expandedForm,LookUp(expandedForm,Pos=Position),
    {
    Place:
    // Determine if a given column is a one, ten, or hundred based on its position.
    Switch(true,
    Mod(Pos-1,3)=0,1,
    Mod(Pos+1,3)=0,10,
    100
    ),
    Period:
    // Determine what Period a digit belongs to based on its position.
    RoundUp(Pos/3,0)-1
    }
    )
    );Clear(expandedForm_Decimal);
    
    // Create a table that separates each digit to include its Value and Position. Make a placeholder for its Place and Period.
    ForAll(RenameColumns(Split(DecimalNumberVar.Result,""),"Result","Char"),
    Collect(expandedForm_Decimal,
    {
    Value: Value(Char),
    Position:
    // Determine the position of each character as a difference between the length of the number and how many digits have already been collected.
    Len(DecimalNumberVar.Result)-CountRows(expandedForm_Decimal),
    Place: 0,
    Period: 0
    }
    )
    );
    
    // Update the Place and Period using the Position.
    ForAll(RenameColumns(expandedForm_Decimal,"Position","Pos"),
    Patch(expandedForm_Decimal,LookUp(expandedForm_Decimal,Pos=Position),
    {
    Place:
    // Determine if a given column is a one, ten, or hundred based on its position.
    Switch(true,
    Mod(Pos-1,3)=0,1,
    Mod(Pos+1,3)=0,10,
    100
    ),
    Period:
    // Determine what Period a digit belongs to based on its position.
    RoundUp(Pos/3,0)-1
    }
    )
    );
    
    //end of the main code
    
    Set(NumberTowords,
    
    If(IsBlank(Find(".",DataCardValue124.Text)),
    Concatenate(
    Concat(
    GroupBy(expandedForm,"Period","PeriodGroup"),
    
    // 1 Read the hundred in the period.
    LookUp(PlaceValue_1,Digit=LookUp(PeriodGroup,Place=100).Value,Word & " ") &
    // 2 For 10-19, read the tens and ones together, otherwise separately.
    If(LookUp(PeriodGroup,Place=10).Value=1,
    LookUp(PlaceValue_1,Digit=Value(Concat(Filter(PeriodGroup,Place<>100),Text(Value))),Word & " "),
    Concat(Filter(PeriodGroup,Place<>100),LookUp(PlaceValue_1,Digit=Value && Column=Place,Word & " "))
    ) &
    
    // 3 Read the period.
    Coalesce(LookUp(Period_1,Group=Period,Name & ","),"")),Varcurrency),
    Concatenate(
    Concat(
    GroupBy(expandedForm,"Period","PeriodGroup"),
    
    // 4 Read the hundred in the period.
    LookUp(PlaceValue_1,Digit=LookUp(PeriodGroup,Place=100).Value,Word & " ") &
    
    // 5 For 10-19, read the tens and ones together, otherwise separately.
    If(LookUp(PeriodGroup,Place=10).Value=1,
    LookUp(PlaceValue_1,Digit=Value(Concat(Filter(PeriodGroup,Place<>100),Text(Value))),Word & " "),
    Concat(Filter(PeriodGroup,Place<>100),LookUp(PlaceValue_1,Digit=Value && Column=Place,Word & " "))
    ) &
    
    // 6 Read the period.
    Coalesce(LookUp(Period_1,Group=Period,Name & ","),"")
    ),Concatenate(Varcurrency," & ",
    
    Concat(
    GroupBy(expandedForm_Decimal,"Period","PeriodGroup"),
    
    
    // 2 Read the period.
    Coalesce(LookUp(Period_1,Group=Period,Name & " "),""))),
    Concatenate(
    Concat(
    GroupBy(expandedForm_Decimal,"Period","PeriodGroup"),
    
    // 3 Read the hundred in the period.
    LookUp(PlaceValue_1,Digit=LookUp(PeriodGroup,Place=100).Value,Word) &
    
    // 4 For 10-19, read the tens and ones together, otherwise separately.
    If(LookUp(PeriodGroup,Place=10).Value=1,
    LookUp(PlaceValue_1,Digit=Value(Concat(Filter(PeriodGroup,Place<>100),Text(Value))),Word & " "),
    Concat(Filter(PeriodGroup,Place<>100),LookUp(PlaceValue_1,Digit=Value && Column=Place,Word & " "))
    ) &
    
    // 5 Read the period.
    Coalesce(LookUp(Period_1,Group=Period,Name & ", "),"")
    ),VarcurrencyDiv)))
    
    
    );
    
    //to remove extra ", million" & ", billion" & ...
    Set(NumWord,
    Substitute(Substitute(Substitute(Substitute(Substitute(NumberTowords,",thousand,",""),",million",""),",billion",""),",trillion",""),",quadrillion","") );
    

     

     

    yer.PNG

     

     

    USD.PNG