fx
XLnCAD
Excel · Python in Excel & VBA
Turn numbers into words, right inside a cell.
A number in, the spelled-out words out — for English amounts and Indian Rupees. Grab the code below and paste it into Excel. Try it first:
B
3
C
3
One Thousand Two Hundred Thirty-Four Point Five Six
Live preview — the same logic as the code below.
For the Python code
Microsoft 365 Excel with Python in Excel. Enter it in a cell with =PY() and pull the number in using xl("B3").
For the VBA code
Any Excel with macros. Paste into a module (Alt+F11), save as .xlsm, then use =InWords(B3).
The code — copy what you need
Python
def InWords(n):
s = str(n).strip()
try:
float(s) # validate it's a number
except:
return ""
ones = ["Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine",
"Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen",
"Seventeen","Eighteen","Nineteen"]
tens = ["","","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"]
def three(num):
if num == 0:
return ""
if num < 20:
return ones[num]
if num < 100:
return tens[num // 10] + ("-" + ones[num % 10] if num % 10 else "")
return ones[num // 100] + " Hundred" + (" " + three(num % 100) if num % 100 else "")
def whole(num):
if num == 0:
return "Zero"
out = []
for value, name in [(10**12,"Trillion"), (10**9,"Billion"), (10**6,"Million"), (1000,"Thousand")]:
if num >= value:
out.append(three(num // value) + " " + name)
num %= value
if num:
out.append(three(num))
return " ".join(out)
negative = s.startswith("-")
s = s.lstrip("-+")
if "." in s:
int_part, dec_part = s.split(".", 1)
else:
int_part, dec_part = s, ""
int_part = int_part or "0"
words = whole(int(int_part))
if dec_part:
words += " Point " + " ".join(ones[int(d)] for d in dec_part)
return ("Minus " if negative else "") + words
InWords(xl("B3"))
Python
def InRupees(n):
s = str(n).strip()
try:
float(s) # validate it's a number
except:
return ""
ones = ["Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine",
"Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen",
"Seventeen","Eighteen","Nineteen"]
tens = ["","","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"]
def three(num):
if num == 0:
return ""
if num < 20:
return ones[num]
if num < 100:
return tens[num // 10] + ("-" + ones[num % 10] if num % 10 else "")
return ones[num // 100] + " Hundred" + (" " + three(num % 100) if num % 100 else "")
def indian(num):
if num == 0:
return "Zero"
crore = num // 10**7
num %= 10**7
lakh = num // 10**5
num %= 10**5
thousand = num // 1000
hundred = num % 1000
parts = []
if crore:
parts.append(indian(crore) + " Crore") # recursive: handles beyond 99 crore
if lakh:
parts.append(three(lakh) + " Lakh")
if thousand:
parts.append(three(thousand) + " Thousand")
if hundred:
parts.append(three(hundred))
return " ".join(parts)
negative = s.startswith("-")
s = s.lstrip("-+")
int_part, _, dec_part = s.partition(".")
int_part = int_part or "0"
# Paise = first two decimal places, rounded on the third digit
dec_part = (dec_part + "000")[:3]
paise = int(dec_part[:2])
if int(dec_part[2]) >= 5:
paise += 1
rupees = int(int_part)
if paise == 100: # e.g. 99.999 rounds up
rupees += 1
paise = 0
words = "Rupees " + indian(rupees)
if paise:
words += " and " + three(paise) + " Paise"
words += " Only"
return ("Minus " if negative else "") + words
InRupees(xl("B3"))
VBA
' ================= International words: =InWords(B3) =================
Function InWords(ByVal n As Variant) As String
Dim s As String
s = Trim(CStr(n))
If Not IsNumeric(s) Then
InWords = ""
Exit Function
End If
Dim negative As Boolean
negative = (Left(s, 1) = "-")
Do While Len(s) > 0 And (Left(s, 1) = "-" Or Left(s, 1) = "+")
s = Mid(s, 2)
Loop
Dim intPart As String, decPart As String
Dim dotPos As Long
dotPos = InStr(s, ".")
If dotPos > 0 Then
intPart = Left(s, dotPos - 1)
decPart = Mid(s, dotPos + 1)
Else
intPart = s
decPart = ""
End If
If Len(intPart) = 0 Then intPart = "0"
Dim result As String
result = WholeToWords(intPart)
' Read each digit after the decimal point individually
If Len(decPart) > 0 Then
Dim onesArr As Variant
onesArr = Array("Zero", "One", "Two", "Three", "Four", "Five", _
"Six", "Seven", "Eight", "Nine")
Dim i As Long, d As Integer
result = result & " Point"
For i = 1 To Len(decPart)
d = CInt(Mid(decPart, i, 1))
result = result & " " & onesArr(d)
Next i
End If
If negative Then result = "Minus " & result
InWords = result
End Function
' ================= Indian Rupees: =InRupees(B3) =================
Function InRupees(ByVal n As Variant) As String
Dim s As String
s = Trim(CStr(n))
If Not IsNumeric(s) Then
InRupees = ""
Exit Function
End If
Dim negative As Boolean
negative = (Left(s, 1) = "-")
Do While Len(s) > 0 And (Left(s, 1) = "-" Or Left(s, 1) = "+")
s = Mid(s, 2)
Loop
Dim intPart As String, decPart As String
Dim dotPos As Long
dotPos = InStr(s, ".")
If dotPos > 0 Then
intPart = Left(s, dotPos - 1)
decPart = Mid(s, dotPos + 1)
Else
intPart = s
decPart = ""
End If
If Len(intPart) = 0 Then intPart = "0"
' Paise = first two decimals, rounded using the third digit
decPart = Left(decPart & "000", 3)
Dim paise As Integer
paise = CInt(Left(decPart, 2))
If CInt(Mid(decPart, 3, 1)) >= 5 Then paise = paise + 1
If paise = 100 Then ' e.g. 99.999 rounds up
paise = 0
intPart = CStr(CDec(intPart) + 1)
End If
Dim words As String
words = "Rupees " & IndianToWords(intPart)
If paise > 0 Then
words = words & " and " & ThreeToWords(paise) & " Paise"
End If
words = words & " Only"
If negative Then words = "Minus " & words
InRupees = words
End Function
' ================= Helpers (shared by both functions) =================
Private Function WholeToWords(ByVal digits As String) As String
Do While Len(digits) > 1 And Left(digits, 1) = "0"
digits = Mid(digits, 2)
Loop
If digits = "0" Then
WholeToWords = "Zero"
Exit Function
End If
Do While (Len(digits) Mod 3) <> 0
digits = "0" & digits
Loop
Dim scales As Variant
scales = Array("", "Thousand", "Million", "Billion", "Trillion", _
"Quadrillion", "Quintillion")
Dim groupCount As Long
groupCount = Len(digits) \ 3
Dim out As String, g As Long, grpVal As Integer
Dim grpWords As String, scaleIndex As Long
out = ""
For g = 1 To groupCount
grpVal = CInt(Mid(digits, (g - 1) * 3 + 1, 3))
scaleIndex = groupCount - g
If grpVal > 0 Then
grpWords = ThreeToWords(grpVal)
If scaleIndex > 0 And scaleIndex <= UBound(scales) Then
grpWords = grpWords & " " & scales(scaleIndex)
End If
If Len(out) > 0 Then out = out & " "
out = out & grpWords
End If
Next g
WholeToWords = out
End Function
Private Function IndianToWords(ByVal digits As String) As String
Do While Len(digits) > 1 And Left(digits, 1) = "0"
digits = Mid(digits, 2)
Loop
If digits = "0" Then
IndianToWords = "Zero"
Exit Function
End If
Dim hundred As Integer, thousand As Integer, lakh As Integer
Dim L As Long
' Last 3 digits -> hundreds group
L = Len(digits)
If L >= 3 Then
hundred = CInt(Right(digits, 3))
digits = Left(digits, L - 3)
Else
hundred = CInt(digits)
digits = ""
End If
' Next 2 digits -> thousands
thousand = 0: lakh = 0
If Len(digits) > 0 Then
L = Len(digits)
If L >= 2 Then
thousand = CInt(Right(digits, 2))
digits = Left(digits, L - 2)
Else
thousand = CInt(digits)
digits = ""
End If
End If
' Next 2 digits -> lakhs
If Len(digits) > 0 Then
L = Len(digits)
If L >= 2 Then
lakh = CInt(Right(digits, 2))
digits = Left(digits, L - 2)
Else
lakh = CInt(digits)
digits = ""
End If
End If
' Anything left is the crore count -> spell it the same way
Dim parts As String
parts = ""
If Len(digits) > 0 Then
Dim cp As String
cp = digits
Do While Len(cp) > 1 And Left(cp, 1) = "0"
cp = Mid(cp, 2)
Loop
If cp <> "0" And cp <> "" Then
parts = IndianToWords(cp) & " Crore"
End If
End If
If lakh > 0 Then parts = Trim(parts & " " & ThreeToWords(lakh) & " Lakh")
If thousand > 0 Then parts = Trim(parts & " " & ThreeToWords(thousand) & " Thousand")
If hundred > 0 Then parts = Trim(parts & " " & ThreeToWords(hundred))
IndianToWords = Trim(parts)
End Function
Private Function ThreeToWords(ByVal num As Integer) As String
Dim ones As Variant, tens As Variant
ones = Array("Zero", "One", "Two", "Three", "Four", "Five", "Six", _
"Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", _
"Thirteen", "Fourteen", "Fifteen", "Sixteen", _
"Seventeen", "Eighteen", "Nineteen")
tens = Array("", "", "Twenty", "Thirty", "Forty", "Fifty", _
"Sixty", "Seventy", "Eighty", "Ninety")
Dim r As String
r = ""
If num >= 100 Then
r = ones(num \ 100) & " Hundred"
num = num Mod 100
If num > 0 Then r = r & " "
End If
If num > 0 Then
If num < 20 Then
r = r & ones(num)
Else
r = r & tens(num \ 10)
If (num Mod 10) > 0 Then
r = r & "-" & ones(num Mod 10)
End If
End If
End If
ThreeToWords = r
End Function
XLnCAD/Excel tutorials by Ajay Anand
/Free to use — a credit or link back is appreciated.