Formatting Numbers with Commas

This post will describe how to reformat large numbers by adding commas to them for readability.
Examples of this are reformatting “10000” to “10,000”, “1000000” to “1,000,000”, etc.

This will be done by describing the blocks used in the Insert Commas Screen of this app, which takes a user-inputted number and returns it with the desired format.
It can be easily adapted to suit apps which return the output of a sum.
If you want to format a number which has been calculated by your app and had no user input, you can jump straight to ‘Function - format number’ below.

The app has been designed using a lot of functions.
This should make understanding how it works a little easier to follow.

The Screen

The Layout Screen for this app contains:

A Text Input Box (with numeric KeyBoardType)

A Button

A Label

The user will be able to enter a number into the Text Input Box, click the Button, and see their reformatted number as the Label.

Blocks

Variables

formatcommasB1

First, initialise the following variables:

Temp, part and rest will be strings of text. They can be initialised with the empty Text block.

validDecimal will be a true/false value. This can be initialised with the null block.

length and commaNumber will be numbers. length has been initialised to 0, and commaNumber has been initialised to 3. These will both be reset before they are used, so you can initialise both to 0 if you want to.

Functions

formatcommasB2

As mentioned earlier, this app uses functions to make following the process easier.

When Button1 is clicked, the function ‘set Label’ is carried out
.
This aligns with the description we have of the app.

Function - Set Label

Within the set Label function, we have three elements:

The function cleanup, which clears away any formatting errors the user may have made.

The function validate decimal, which makes sure the user has entered either a whole number (1) or a decimal (1.1), but not something with an invalid amount of decimal points (1.1.1).

An if block, which we will explore later.

Function - cleanup

The cleanup function does three things:

Sets the variable temp to have the value of the user input.

Removes commas from temp by replacing them with the empty Text string.

Removes zeros from the beginning of temp with a while loop. This while loop says that as long as the first character of temp is a zero, the text of temp will be set to start at its second character, ie the first character will be removed.

The comma removal is important to the functioning of the app.

If you don’t want zeros at the beginning of the number removed, you can remove the while loop.

Function - validate decimal

validate decimal uses an if block to determine if there is a valid amount of decimal points (0 or 1) in temp. It stores this answer by setting the variable validDecimal to true or false.

This is done by matching the location of the first and last occurence of the character ‘.’ in the text.

If there isn’t a decimal point in temp, the first and last position of ‘.’ will be 0. validDecimal will be set to true.

If there is only one ‘.’ in temp, the first and last position of ‘.’ will match. validDecimal will be set to true.

If there is more than one ‘.’ in temp, the first and last position of ‘.’ will not match. validDecimal will be set to false.

Now that we understand the cleanup and validate decimal functions, let’s revisit the if block from the function set Label.

formatcommasB2-2

The variable validDecimal has been set to true or false by the function validate decimal.

If the amount of decimal points is not valid, the Label is set to an error message saying that the inputted number was invalid.

Otherwise, if validDecimal is true, the function format number is carried out.

Function - Format Number

formatcommasB5

Commas are only added to the part of a number which comes before a decimal point: you can rewrite “123456.00” as “123,456.00”, but you cannot rewrite “1.234567” as “1.234,567”. With this in mind, we look at the function format number.

format number does three things:

separate temp: will split temp into two Text strings called part and rest, with part being the ‘whole’ number that comes before the decimal point and ‘rest’ being whatever comes after the decimal point.

format commas (of part)

Set temp to be the newly reformatted part joined back together with rest.

Function - separate temp

If temp contains a decimal point, the variable part will be set to whatever comes before it and rest will be set to the decimal point and whatever numbers follow it.

Eg. if temp is “1234.56”, part will be set to “1234” and rest will be set to “.56”, including the decimal point.

If temp doesn’t contain a decimal point (ie. it is a whole number), then part will be set to this whole number and rest will be set to the empty text string.

Function - format commas

We want to insert commas into numbers of 1,000 and above.
We want to do this by inserting a comma between every three digits, starting from the end of the number.

Eg. in the number 7,654,321, if we count 1 as the first digit and 7 as the seventh digit, we want to insert a comma between the third and fourth digit, and between the 6th and 7th digit.

Keeping this in mind, we will look at how the function format commas works.

The first things format commas does is set the variable length to equal the length of part, then set the variable commaNumber to 3. commaNumber will be the location of the next comma due to be inserted into the string.

A while loop is used to add commas to the number as follows:

While the length of part is greater than commaNumber, part will be rewritten with a comma in between the character at commaNumber and the character after it.

Adding a comma will make the length of part longer, so we re-assert that the variable length is the length of part, and we add 4 to commaNumber. We add 4 and not 3 because the commaNumber has to accommodate both the next three digits and the additional comma.

This while loop will be demonstrated with an example.

Say that part = “1234567”

length = 7

commaNumber = 3

length > commaNumber (7 > 3)

part becomes join of:

“1234” = Characters 1 to 4 of part (4 = length - commaNumber = 7 - 3)

“,”

“567” = Characters 5 to 7 of part (5 = length - commaNumber + 1 = 7 - 3 + 1; 7 = length of part)

part is now “1234,567”

length is now 8

commaNumber is now 7 (3 + 4)

length > commaNumber (8 > 7)

part becomes join of:

“1” = Characters 1 to 1 of part (4 = length - commaNumber = 8 - 7)

“,”

“234,567” = Characters 2 to 8 of part (5 = length - commaNumber + 1 = 7 - 3 + 1; 7 = length of part)

part is now “1,234,567”

length is now 9

commaNumber is now 11 (7 + 4)

The while loop ends as length is no longer greater than commaNumber.

“1234567” has been reformatted as “1,234,567”. This is correct!

Now we have completed the format commas function, two things will happen:
part and rest will be recombined and stored as temp in the format number function.
Label1.Text will be set to our newly reformatted number temp in the set Label function.

And that’s that!

Notes:

You can add a currency symbol in the “from Label1 set Text to temp” block in the set Label function using a join block.

The sample app linked above also has Screens which demonstrate rounding a number according to user input. You can find an explanation of this process in my previous tutorial here.

5 Likes

Very good teaching.:smiley:

I tried to make it on the Classic Platform but it was a bit difficult, it seems that can’t do it because the blocks are different.:sweat_smile:
Can someone give me some advice?
Thank

Hi there,

Classic has a ‘replace all’ block in the Text drawer of blocks.

Instead of getting letter #1, you can use the ‘segment text’ block and get a segment that starts at #1 and is 1 character long.

You can use the same ‘segment text’ block instead of the ‘get substring’ block that I use. The length would then be ([length of app temp] -1).

Since Classic doesn’t have ‘first/last occurrence of’ blocks, you’d need get the location of the first decimal point, segment the text at this point (getting the string that starts just after the decimal point and extends to the end of the string), then check if there are any decimal points in the string after the decimal point.

Classic has a ‘contains’ block that returns a true/false value.

Are there any other blocks that you can’t find in Classic?

2 Likes

This extension should help you

2 Likes


Does anyone know how to change it?

However, there are restrictions, only 15 strings, if it exceeds 15, the back will be 0.

Thank you so much, Jane. I have tried your method and it worked quite well. Your tutorial have helped me a bunch! Thank you again.

Jib

1 Like