Friday, October 30, 2009

Excel Number Format : Indian Style Comma Separation

Yesterday I got a comment asking for custom number format for Indian style comma separation. While I responded to question by providing the custom number format I knew that the answer does not handle the complete range of numbers and can not be applied in all the cases. This forced me to look around for a solution that can be applied for all kind of numbers.

Just for the information of people who are not aware of Indian Style of comma separation, I have produced table below which explains Indian style formatting for various numbers. The basic rule is that first comma separation happens at 3 digits i.e. 1000 then it happens after every 2 digits. Check out table below for better understanding.


Number
Formatted As
10
10.00
100
100.00
1000
1,000.00
10000
10,000.00
100000
1,00,000.00
1000000
10,00,000.00
10000000
1,00,00,000.00
100000000
10,00,00,000.00
1000000000
1,00,00,00,000.00
10000000000
10,00,00,00,000.00
100000000000
1,00,00,00,00,000.00

Soon I realised that there is no single custom format available for handling all kind of number length and we need separate format for it depending upon the number of digits. Doing this manually and accuratly every time is very difficult. This leaves only one option to automate this through a macro. I got a Macro code for doing this and modified and tested that for long numbers.

IndiaStyleCommaSeparation

I am sharing the macro code with you. You will need to select the numbers and run macro to format them as per India style comma sepration.


Sub IndianNumberFormat()
For Each c In Selection
Select Case Abs(c.Value)
Case Is < 100000
c.Cells.NumberFormat = "##,##0.00"
Case Is < 10000000
c.Cells.NumberFormat = "#\,##\,##0.00"
Case Is < 1000000000
c.Cells.NumberFormat = "#\,##\,##\,##0.00"
Case Is < 1000000000
c.Cells.NumberFormat = "#\,##\,##\,##0.00"
Case Is < 100000000000#
c.Cells.NumberFormat = "#\,##\,##\,##\,##0.00"
Case Else
c.Cells.NumberFormat = "#\,##\,##\,##\,##\,##0.00"
End Select
Next c
End Sub


For easy application of this code you need to save it as a excel addin or add it to your personal macro book. Adding a custom toolbar for this code will make it easy to apply. You can chage the number of decimal places by changing the number of zeros at the end of custom number format given above.

15 comments:

Jon Peltier said...

You can cut your routine in half. Change the For-Each to

For Each c In Selection.Cells

and remove everything from If to Else, plus End If.

Yogesh Gupta said...

Hello Jon - Thanks for your inputs, I am updating the post above.

sam said...

For Positive Numbers

Sub Ind_Num_Fmt()
For Each Cellval In Selection
Cellval.NumberFormat = "[>=10000000]##\,##\,##\,##0.00;[>=100000]##\,##\,##0.00;##,##0.00"
Next
End Sub

Sam

Yogesh Gupta said...

Hi Sam

Thanks for your input. However this can handle only positive numbers upto 100 Millions.

That is why I have said that no single format can handle all kind of number lenght. This is the reason for using case statement to choose different format based on value.

Thanks

Frederick said...

You can get rid of that entire Select..Case block and replace it with a single (albeit long) statement...

Sub IndianNumberFormat()
For Each C In Selection
C.NumberFormat = Trim(Replace(Format(String( _
Len(Int(C.Value)) - 1, "#"), _
" @@\\,@@\\,@@\\,@@\\,@@\\,@@\\,@@0"), _
" \,", "")) & ".00"
Next C
End Sub

The above code should be able to handle up to a 15-digit positive or negative number.

Rick Rothstein (MVP - Excel)

Frederick said...

By the way, instead of using a manually implemented macro, we can make this functionality automatic by using worksheet event code. Just right click the tab at the bottom of the worksheet that is to have this functionality, select View Code from the popup menu that appears and then copy/paste the following into the code window that appears...

Private Sub Worksheet_Change(ByVal Target As Range)
Dim R As Range
Set R = Range("A:A,C3:E10")
If Not Intersect(Target, R) Is Nothing Then
With Target
.NumberFormat = Trim(Replace(Format(String( _
Len(Int(.Value)) - 1, "#"), _
" @@\\,@@\\,@@\\,@@\\,@@\\,@@\\,@@0"), _
" \,", "")) & ".00"
End With
End If
End Sub

Just change the Range address in the Set statement to cover the range of cells you want to have this functionality. My sample above is set to apply the Indian Number Format to all of Column A plus just the cells in range C3:E10. After entering any number within this range of cells, it will be reformatted into the Indian style for a number.

Yogesh Gupta said...

Hello Rick

Thanks for your inputs. I am really amazed with your single line code to handle Indian Style comma separation for upto 15 digits number.

These are great inputs and have really added value to my post.

Thanks

Frederick said...

You are quite welcome... I am glad that you liked my offerings. As for that single line of code solution... well, one-liners are kind of a "thing" with me. Before becoming an Excel MVP, I was a MVP for Visual Basic where I built up a reputation for writing one-liners. Google used to be able to show well over 1000 of them via a simple search (although I think I have written posted several thousand one-liners across the 9/10 years I have been volunteering answering newsgroup questions), but they changed something in their search engine a couple of years ago and now it is hard to find links to them. Anyway, this one-liner contains the same "challenge" for you and your readers that all my past posted ones did... try to figure out how and/or why it works.[grin]

Rick Rothstein (MVP - Excel)

Yogesh Gupta said...

Hello Rick

I like the "challange" and let me explain the alog of your one liner for that let me break your code into various parts as it is doing mutiple line processing in single line due to its length.

1. Most inner part of your one liner is building up string of # based on cell value. If value is 10 it is #. Incase it is 1000 string is ##. It is actually lengh of the int - 1.

2. Formating this sting of # into " @@\\,@@\\,@@\\,@@\\,@@\\,@@\\,@@0" . This builds indian style comma separation number format. However there are some " \," if the length of the int is less than 14.
3. Replacing the " \," with ""
4. Trim the string built after replace as it leaves space in the begining.
5. Finaly adding ".00" for decimal points

Now the entire string is ready as per Indian style comma separation format.

I hope I have understood your code. Let me know if I have missed something.


Regards

Augusto said...
This post has been removed by the author.
Augusto said...

I'm totally amazed. How could I miss till now that indian punctuation is so different?
Even the one liner to replace it is awesome!

Thank you for sharing

http://bit.ly/iUhlP

Yogesh Gupta said...

Hi Augusto

Thanks for your appreciative comments. This one liner is contributed by Rick Rothstein (MVP - Excel)

Rick is very active on various forums and you can notice his contribution at various places on the net. When ever you serach any VBA help, you may get a code contributed by him.

By this note I want to say Thanks to Rick, he has really added value to this post.

Thanks
Yogesh Gupta

Frederick said...

Hi Yogesh,

Although I said it in one of my earlier messages in this thread, I just wanted to say again that you are quite welcome and that I am glad you found my contribution of value.

Vijay said...

Hi,

for negative values one liner printed like this -,11,40,773 which needs to be corrected. Also it should retain original decimal values format, color and parenthesis for negative values. Can someone make the changes please.

Thanks

Yogesh Gupta said...

Hi Vijay

As pointed out by you one liner had some issue with the negative numbers. I have corrected this, following code should be able to handle it correctly.

Sub IndianNumberFormat()
For Each C In Selection
C.NumberFormat = Trim(Replace(Format(String( _
Len(Int(Abs(C.Value))) - 1, "#"), _
" @@\\,@@\\,@@\\,@@\\,@@\\,@@\\,@@0"), _
" \,", "")) & ".00"
Next C
End Sub

However I am not sure about rest of the items pointed out by you.

Thanks
Yogesh Gupta

Post a Comment