# HOW TO CONVERT NUMBERS TO WORDS

### Question

•

Nedd some help with code is not working so far....

Public Class Form1

Dim BigOnes(9) As String

Dim Smallones(19) As String

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim bln, bln2 As Boolean

'Text1.Text = Format(Val(Text1.Text), " ######.##")

'get the number to be 6 digits and two decimal places

Dim Dollars, cents As String

Dim words As String

Dollars = Text1.Text.Substring(0, 6)

cents = Text1.Text.Substring(7, 2)

words = ""

'Check to see if the incoming numbers is not too large

If CDbl(Dollars) > 999999 Then

Text2.Text = "Dollar Amount is too Large"

Exit Sub

End If

Dim chunk As String

'separate dollars into chucnk

If CDbl(Dollars) = 0 Then

words = "zero"

Else

'first to the thosands

chunk = Dollars.Substring(0, 3)

If CDbl(chunk) > 0 Then

bln = True

GoTo parseChunk

one:

bln = False

words = words & "Thousand"

End If

'do the rest of the dollars

chunk = Dollars.Substring(Dollars.Length - 3, 3)

If CDbl(chunk) > 0 Then

bln2 = True

GoTo parsechunk

two:

bln2 = False

End If

End If

'concatenate the cents and display

If CDbl(cents) = 0 Then cents = "NO"

words = words & " and" & cents & "/100"

Text2.Text = words

Exit Sub

Parsechunk:

Dim digits, leftdigit, rightdigit As String

digits = Mid(chunk, 1, 1)

If CDbl(digits) > 0 Then

words = words & " " & Smallones(CInt(CInt(digits) & "Hundred"))

End If

If CDbl(digits) > 19 Then

leftdigit = Mid(chunk, 2, 1)

rightdigit = Mid((chunk), 3, 1)

words = words & " " & BigOnes(CInt(leftdigit))

If CDbl(rightdigit) > 0 Then

words = words & " " & Smallones(CInt(rightdigit))

End If

Else

If CDbl(digits) > 0 Then

words = words & " " & Smallones(CInt(digits))

End If

End If

If bln Then GoTo one

If bln2 Then GoTo two

Text2.Text = words

End Sub

'Format the incoming number to guarantee six digits to the left of the decimal point and two the right and then separate the dollars from the cents

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

BigOnes(1) = "Ten"

BigOnes(2) = "Twenty"

BigOnes(3) = "thirty"

BigOnes(4) = "forty"

BigOnes(5) = "fifty"

BigOnes(6) = "Sixty"

BigOnes(7) = "Seventy"

BigOnes(8) = "Eighty"

BigOnes(9) = "Ninety"

Smallones(1) = " One"

Smallones(2) = " Two "

Smallones(3) = " Three"

Smallones(4) = " Four"

Smallones(5) = " Five"

Smallones(6) = " Six"

Smallones(7) = " Seven"

Smallones(8) = " Eight"

Smallones(9) = " Nine"

Smallones(10) = " Ten"

Smallones(11) = " Eleven"

Smallones(12) = " Twelve"

Smallones(13) = " Thirteen"

Smallones(14) = " Fourteen"

Smallones(15) = "Fifteen"

Smallones(16) = " Sixteen"

Smallones(17) = " Seventeen"

Smallones(18) = " Eighteen"

Smallones(19) = "Nineteen"

End Sub

End Class

Saturday, November 03, 2007 11:04 PM

• Panaboy, I found your project to be an interesting challenge so I wrote my own version of it.  I sincerely hope this was not a class exercise because then I will have given it all away.  However, I will suggest that you avoid using some of the conventions of VB6 when working with .NET.  Do not use Goto anymore - it is consider bad practice in object-oriented design (not to mention annoying to follow).  Instead note that I used a private helper function that returns a value for each hundreds "chunk".  This allows the code to be able to expand to values much greater than your static example.  I took it to 999 quadrillion but you can take it any amount higher as long as you know what the heck to call such numbers (Of course at some point you'll reach a value higher than all the money in the world... but hey, don't let that stop you!)

Also note that my function takes in a string value and at no point requires a conversion of the entire value into a numeric type (it does convert bits of the value into integers though).  To do this I needed to scrub the value first and be sure that there are only digits and optionally one decimal and/or minus sign).  I also remove commas (thousands separator) and a dollar sign.  This scrubbing probably should be done before the function call -- especially if you expect to encounter even more erratic values (like cents, pounds, euros signs).

So here it is.  try it out and try to break it.  I did some testing but I'm sure it could use some minor adjustments.

(I just have a form with a button and two textboxes (the second one needs to be really long or multi-line)

Code Block

Public Class Form1

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

Text2.Text = ""

Try

Text2.Text = ConvertMoneyToText(Text1.Text)

Return

Catch ex As Exception

Text2.Text = "Error: " & ex.Message

End Try

End Sub

Public Function ConvertMoneyToText(ByVal value As String) As String

'Overload: Takes a string value that translates as a decimal value of up to one pentillion (?) dollars.

'Note: Removing the comma for European currency will remove the decimal pointer.

value = value.Replace(",", "").Replace("\$", "")

Dim decimalCount As Int32 = 0

For x As Int32 = 0 To value.Length - 1

If value(x).ToString = "." Then

decimalCount += 1

If decimalCount > 1 Then Throw New ArgumentException("Only monetary values are accepted")

End If

If Not (Char.IsDigit(value(x)) Or value(x).ToString = ".") And Not (x = 0 And value(x).ToString = "-") Then

Throw New ArgumentException("Only monetary values are accepted")

End If

Next

Dim returnValue As String = ""

Dim parts() As String = value.Split(".")

parts(1) = parts(1).Substring(0, 2).ToCharArray 'Truncates -- doesn't round.

Dim IsNegative As Boolean = parts(0).Contains("-")

If parts(0).Replace("-", "").Length > 18 Then

Throw New ArgumentException("Maximum value is \$999,999,999,999,999,999.99")

End If

If IsNegative Then

parts(0) = parts(0).Replace("-", "")

returnValue &= "Minus "

End If

'If you know the names of what is beyond quadrillion and feel the urge to do the

' rediculous just follow the pattern below.

If parts(0).Length > 15 Then

returnValue &= HundredsText(parts(0).PadLeft(18, "0").Substring(3, 3)) & "Trillion "

returnValue &= HundredsText(parts(0).PadLeft(18, "0").Substring(6, 3)) & "Billion "

returnValue &= HundredsText(parts(0).PadLeft(18, "0").Substring(9, 3)) & "Million "

returnValue &= HundredsText(parts(0).PadLeft(18, "0").Substring(12, 3)) & "Thousand "

ElseIf parts(0).Length > 12 Then

returnValue &= HundredsText(parts(0).PadLeft(15, "0").Substring(0, 3)) & "Trillion "

returnValue &= HundredsText(parts(0).PadLeft(15, "0").Substring(3, 3)) & "Billion "

returnValue &= HundredsText(parts(0).PadLeft(15, "0").Substring(6, 3)) & "Million "

returnValue &= HundredsText(parts(0).PadLeft(15, "0").Substring(9, 3)) & "Thousand "

ElseIf parts(0).Length > 9 Then

returnValue &= HundredsText(parts(0).PadLeft(12, "0").Substring(0, 3)) & "Billion "

returnValue &= HundredsText(parts(0).PadLeft(12, "0").Substring(3, 3)) & "Million "

returnValue &= HundredsText(parts(0).PadLeft(12, "0").Substring(6, 3)) & "Thousand "

ElseIf parts(0).Length > 6 Then

returnValue &= HundredsText(parts(0).PadLeft(9, "0").Substring(0, 3)) & "Million "

returnValue &= HundredsText(parts(0).PadLeft(9, "0").Substring(3, 3)) & "Thousand "

ElseIf parts(0).Length > 3 Then

returnValue &= HundredsText(parts(0).PadLeft(6, "0").Substring(0, 3)) & "Thousand "

End If

Dim hundreds As String = parts(0).PadLeft(3, "0")

hundreds = hundreds.Substring(hundreds.Length - 3, 3)

If CInt(hundreds) <> 0 Then

If CInt(hundreds) < 100 Then returnValue &= "and "

returnValue &= HundredsText(hundreds) & "Dollar"

If CInt(hundreds) <> 1 Then returnValue &= "s"

If CInt(parts(1)) <> 0 Then returnValue &= " and "

End If

If parts.Length = 2 Then

If CInt(parts(1)) <> 0 Then

returnValue &= "Cent"

If CInt(parts(1)) <> 1 Then returnValue &= "s"

End If

End If

Return returnValue

End Function

Private Function HundredsText(ByVal value As String) As String

Dim Tens As String() = {"Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}

Dim Ones As String() = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}

Dim returnValue As String = ""

Dim IsSingleDigit As Boolean = True

If CInt(value(0).ToString) <> 0 Then

returnValue &= Ones(CInt(value(0).ToString) - 1) & " Hundred "

IsSingleDigit = False

End If

If CInt(value(1).ToString) > 1 Then

returnValue &= Tens(CInt(value(1).ToString) - 1) & " "

If CInt(value(2).ToString) <> 0 Then

returnValue &= Ones(CInt(value(2).ToString) - 1) & " "

End If

ElseIf CInt(value(1).ToString) = 1 Then

returnValue &= Ones(CInt(value(1).ToString & value(2).ToString) - 1) & " "

Else

If CInt(value(2).ToString) <> 0 Then

If Not IsSingleDigit Then

returnValue &= "and "

End If

returnValue &= Ones(CInt(value(2).ToString) - 1) & " "

End If

End If

Return returnValue

End Function

End Class

Sunday, November 04, 2007 3:09 AM

### All replies

• Panaboy, I found your project to be an interesting challenge so I wrote my own version of it.  I sincerely hope this was not a class exercise because then I will have given it all away.  However, I will suggest that you avoid using some of the conventions of VB6 when working with .NET.  Do not use Goto anymore - it is consider bad practice in object-oriented design (not to mention annoying to follow).  Instead note that I used a private helper function that returns a value for each hundreds "chunk".  This allows the code to be able to expand to values much greater than your static example.  I took it to 999 quadrillion but you can take it any amount higher as long as you know what the heck to call such numbers (Of course at some point you'll reach a value higher than all the money in the world... but hey, don't let that stop you!)

Also note that my function takes in a string value and at no point requires a conversion of the entire value into a numeric type (it does convert bits of the value into integers though).  To do this I needed to scrub the value first and be sure that there are only digits and optionally one decimal and/or minus sign).  I also remove commas (thousands separator) and a dollar sign.  This scrubbing probably should be done before the function call -- especially if you expect to encounter even more erratic values (like cents, pounds, euros signs).

So here it is.  try it out and try to break it.  I did some testing but I'm sure it could use some minor adjustments.

(I just have a form with a button and two textboxes (the second one needs to be really long or multi-line)

Code Block

Public Class Form1

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

Text2.Text = ""

Try

Text2.Text = ConvertMoneyToText(Text1.Text)

Return

Catch ex As Exception

Text2.Text = "Error: " & ex.Message

End Try

End Sub

Public Function ConvertMoneyToText(ByVal value As String) As String

'Overload: Takes a string value that translates as a decimal value of up to one pentillion (?) dollars.

'Note: Removing the comma for European currency will remove the decimal pointer.

value = value.Replace(",", "").Replace("\$", "")

Dim decimalCount As Int32 = 0

For x As Int32 = 0 To value.Length - 1

If value(x).ToString = "." Then

decimalCount += 1

If decimalCount > 1 Then Throw New ArgumentException("Only monetary values are accepted")

End If

If Not (Char.IsDigit(value(x)) Or value(x).ToString = ".") And Not (x = 0 And value(x).ToString = "-") Then

Throw New ArgumentException("Only monetary values are accepted")

End If

Next

Dim returnValue As String = ""

Dim parts() As String = value.Split(".")

parts(1) = parts(1).Substring(0, 2).ToCharArray 'Truncates -- doesn't round.

Dim IsNegative As Boolean = parts(0).Contains("-")

If parts(0).Replace("-", "").Length > 18 Then

Throw New ArgumentException("Maximum value is \$999,999,999,999,999,999.99")

End If

If IsNegative Then

parts(0) = parts(0).Replace("-", "")

returnValue &= "Minus "

End If

'If you know the names of what is beyond quadrillion and feel the urge to do the

' rediculous just follow the pattern below.

If parts(0).Length > 15 Then

returnValue &= HundredsText(parts(0).PadLeft(18, "0").Substring(3, 3)) & "Trillion "

returnValue &= HundredsText(parts(0).PadLeft(18, "0").Substring(6, 3)) & "Billion "

returnValue &= HundredsText(parts(0).PadLeft(18, "0").Substring(9, 3)) & "Million "

returnValue &= HundredsText(parts(0).PadLeft(18, "0").Substring(12, 3)) & "Thousand "

ElseIf parts(0).Length > 12 Then

returnValue &= HundredsText(parts(0).PadLeft(15, "0").Substring(0, 3)) & "Trillion "

returnValue &= HundredsText(parts(0).PadLeft(15, "0").Substring(3, 3)) & "Billion "

returnValue &= HundredsText(parts(0).PadLeft(15, "0").Substring(6, 3)) & "Million "

returnValue &= HundredsText(parts(0).PadLeft(15, "0").Substring(9, 3)) & "Thousand "

ElseIf parts(0).Length > 9 Then

returnValue &= HundredsText(parts(0).PadLeft(12, "0").Substring(0, 3)) & "Billion "

returnValue &= HundredsText(parts(0).PadLeft(12, "0").Substring(3, 3)) & "Million "

returnValue &= HundredsText(parts(0).PadLeft(12, "0").Substring(6, 3)) & "Thousand "

ElseIf parts(0).Length > 6 Then

returnValue &= HundredsText(parts(0).PadLeft(9, "0").Substring(0, 3)) & "Million "

returnValue &= HundredsText(parts(0).PadLeft(9, "0").Substring(3, 3)) & "Thousand "

ElseIf parts(0).Length > 3 Then

returnValue &= HundredsText(parts(0).PadLeft(6, "0").Substring(0, 3)) & "Thousand "

End If

Dim hundreds As String = parts(0).PadLeft(3, "0")

hundreds = hundreds.Substring(hundreds.Length - 3, 3)

If CInt(hundreds) <> 0 Then

If CInt(hundreds) < 100 Then returnValue &= "and "

returnValue &= HundredsText(hundreds) & "Dollar"

If CInt(hundreds) <> 1 Then returnValue &= "s"

If CInt(parts(1)) <> 0 Then returnValue &= " and "

End If

If parts.Length = 2 Then

If CInt(parts(1)) <> 0 Then

returnValue &= "Cent"

If CInt(parts(1)) <> 1 Then returnValue &= "s"

End If

End If

Return returnValue

End Function

Private Function HundredsText(ByVal value As String) As String

Dim Tens As String() = {"Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}

Dim Ones As String() = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}

Dim returnValue As String = ""

Dim IsSingleDigit As Boolean = True

If CInt(value(0).ToString) <> 0 Then

returnValue &= Ones(CInt(value(0).ToString) - 1) & " Hundred "

IsSingleDigit = False

End If

If CInt(value(1).ToString) > 1 Then

returnValue &= Tens(CInt(value(1).ToString) - 1) & " "

If CInt(value(2).ToString) <> 0 Then

returnValue &= Ones(CInt(value(2).ToString) - 1) & " "

End If

ElseIf CInt(value(1).ToString) = 1 Then

returnValue &= Ones(CInt(value(1).ToString & value(2).ToString) - 1) & " "

Else

If CInt(value(2).ToString) <> 0 Then

If Not IsSingleDigit Then

returnValue &= "and "

End If

returnValue &= Ones(CInt(value(2).ToString) - 1) & " "

End If

End If

Return returnValue

End Function

End Class

Sunday, November 04, 2007 3:09 AM
• Thanks a lot for your reply. this is part of my final project on college, you really help,me , gracias

Sunday, November 04, 2007 7:04 PM
• Oh... Now I feel guilty.

Oh well,  I hope you ace it.  Buena suerte!

Monday, November 05, 2007 1:21 PM
• I came across this thread again and dusted off the code -- found a few bugs that are now fixed (couldn't handle single digit, leading zeroes were not ignored, and just cents now is prefaced by "No Dollars and"....

Wednesday, October 08, 2008 7:36 PM
• Dig-Boy said:

Oh... Now I feel guilty.

Nice going, DB!

Man, I wish my finals looked like this...
Thanks,
Corey Furman
Code Slabs
______________________________________________________