Amount to word business stating writing? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
ivill
Posts: 124
Joined: 13 May 2016, 02:23

Amount to word business stating writing?

03 Sep 2017, 20:07

Hello all, how do i supposed to convert amount numbers to words with CENT expression, looking around the internet but none ahk script could do this (few scripts actually, but longer digits not supported, cents not supported)
here is an example
52,031.04 >>> FIFTY TWO THOUSAND AND THIRTY ONE AND CENTS FOUR

i know it can be done in Microsoft excel with vba, but i prefer the ahk way...
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Amount to word business stating writing?

03 Sep 2017, 20:33

Try this for a start, and fine-tune as needed: (replace "Euros" with "Yen" or "Rupees", capitalize as you want, ...)

Code: Select all

Input = 52,031.04



StringReplace, Input, Input, `,,, All
If Pos := InStr(Input, ".") {
    Euros := SubStr(Input, 1, Pos - 1)
    Cents := SubStr(Input, Pos + 1)
    Result := Spell(Euros) " Euros and " Spell(Cents) " Cents"
} Else Result := Spell(Input) " Euros"
MsgBox, %Result%
ExitApp



;-------------------------------------------------------------------------------
Spell(n) { ; recursive function to spell out the name of a max 36 digit integer
;-------------------------------------------------------------------------------
    ; credit to AHK forum user Laszlo
    ;---------------------------------------------------------------------------
    Static p1 := "thousand", p2 := "million", p3 := "billion", p4 := "trillion"
        , p5 := "quadrillion", p6 := "quintillion", p7 := "sextillion"
        , p8 := "septillion", p9 := "octillion", p10 := "nonillion"
        , p11 := "decillion"

        , t2 := "twenty", t3 := "thirty", t4 := "forty", t5 := "fifty"
        , t6 := "sixty", t7 := "seventy", t8 := "eighty", t9 := "ninety"

        , o0 := "zero", o1 := "one", o2 := "two", o3 := "three", o4 := "four"
        , o5 := "five", o6 := "six", o7 := "seven", o8 := "eight", o9 := "nine"
        , o10 := "ten", o11 := "eleven", o12 := "twelve", o13 := "thirteen"
        , o14 := "fourteen", o15 := "fifteen", o16 := "sixteen"
        , o17 := "seventeen", o18 := "eighteen", o19 := "nineteen"

    n := RegExReplace(n, "^0+(\d)", "$1") ; remove surplus leading 0s from n

    If (d := (StrLen(n) - 1) // 3) > 11 ; # of digit groups of 3
        Return, "Number too big"

    If d ; more than 3 digits
        Return, Spell(SubStr(n, 1, -3 * d)) " " p%d%
            ; avoid the transformation of s to a number
            . ((s := SubStr(n, 1 - 3 * d)) ? ", " Spell(s "") : "")

    i := SubStr(n, 1, 1)
    If (n > 99) ; 3 digits
        Return, o%i% " hundred" ((s := SubStr(n, 2)) ? " and " Spell(s) : "")

    If (n > 19) ; n = 20..99
        Return, t%i% ((o := SubStr(n, 2)) ? "-" o%o% : "")

    Return, o%n% ; n = 0..19
}

I hope that helps to get you started.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Amount to word business stating writing?

03 Sep 2017, 21:00

I wrote this a long time ago: Crazy Scripting : NTOW-INR 45L [ Number to Word Expander ]
The post is broken.
Just copy/paste the function NTOW_IN() and try it as follows:

Example call:

Code: Select all

Amt$ := NTOW_IN( "52,031.04", 0, "and Cent" )
Amt$ := RegExReplace( Amt$,"(^ +| +(?= )| +$)" ) ; Remove redundant spaces in sentence
NTOW() runs as is in all AutoHotkey 1.1 versions.
Let me know. I might rewrite it using AutoHotkey 1.1 advanced features like Arrays and Format().
My Scripts and Functions: V1  V2
User avatar
ivill
Posts: 124
Joined: 13 May 2016, 02:23

Re: Amount to word business stating writing?

04 Sep 2017, 21:08

wolf_II wrote:Try this for a start, and fine-tune as needed: (replace "Euros" with "Yen" or "Rupees", capitalize as you want, ...)

Code: Select all

Input = 52,031.04



StringReplace, Input, Input, `,,, All
If Pos := InStr(Input, ".") {
    Euros := SubStr(Input, 1, Pos - 1)
    Cents := SubStr(Input, Pos + 1)
    Result := Spell(Euros) " Euros and " Spell(Cents) " Cents"
} Else Result := Spell(Input) " Euros"
MsgBox, %Result%
ExitApp



;-------------------------------------------------------------------------------
Spell(n) { ; recursive function to spell out the name of a max 36 digit integer
;-------------------------------------------------------------------------------
    ; credit to AHK forum user Laszlo
    ;---------------------------------------------------------------------------
    Static p1 := "thousand", p2 := "million", p3 := "billion", p4 := "trillion"
        , p5 := "quadrillion", p6 := "quintillion", p7 := "sextillion"
        , p8 := "septillion", p9 := "octillion", p10 := "nonillion"
        , p11 := "decillion"

        , t2 := "twenty", t3 := "thirty", t4 := "forty", t5 := "fifty"
        , t6 := "sixty", t7 := "seventy", t8 := "eighty", t9 := "ninety"

        , o0 := "zero", o1 := "one", o2 := "two", o3 := "three", o4 := "four"
        , o5 := "five", o6 := "six", o7 := "seven", o8 := "eight", o9 := "nine"
        , o10 := "ten", o11 := "eleven", o12 := "twelve", o13 := "thirteen"
        , o14 := "fourteen", o15 := "fifteen", o16 := "sixteen"
        , o17 := "seventeen", o18 := "eighteen", o19 := "nineteen"

    n := RegExReplace(n, "^0+(\d)", "$1") ; remove surplus leading 0s from n

    If (d := (StrLen(n) - 1) // 3) > 11 ; # of digit groups of 3
        Return, "Number too big"

    If d ; more than 3 digits
        Return, Spell(SubStr(n, 1, -3 * d)) " " p%d%
            ; avoid the transformation of s to a number
            . ((s := SubStr(n, 1 - 3 * d)) ? ", " Spell(s "") : "")

    i := SubStr(n, 1, 1)
    If (n > 99) ; 3 digits
        Return, o%i% " hundred" ((s := SubStr(n, 2)) ? " and " Spell(s) : "")

    If (n > 19) ; n = 20..99
        Return, t%i% ((o := SubStr(n, 2)) ? "-" o%o% : "")

    Return, o%n% ; n = 0..19
}

I hope that helps to get you started.
Thanks for you kindly help, it works
User avatar
ivill
Posts: 124
Joined: 13 May 2016, 02:23

Re: Amount to word business stating writing?

04 Sep 2017, 21:11

SKAN wrote:I wrote this a long time ago: Crazy Scripting : NTOW-INR 45L [ Number to Word Expander ]
The post is broken.
Just copy/paste the function NTOW_IN() and try it as follows:

Example call:

Code: Select all

Amt$ := NTOW_IN( "52,031.04", 0, "and Cent" )
Amt$ := RegExReplace( Amt$,"(^ +| +(?= )| +$)" ) ; Remove redundant spaces in sentence
NTOW() runs as is in all AutoHotkey 1.1 versions.
Let me know. I might rewrite it using AutoHotkey 1.1 advanced features like Arrays and Format().
thanks for your kindly reply, it works, i made some changes from your script, to english dollar expression, would be great to see your new version in the future.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Amount to word business stating writing?

04 Sep 2017, 23:54

I did a script for this which I thought I'd share.

Code: Select all

q::
vNum := "123456789123456789123456789123456789.123"
MsgBox, % JEE_NumToWord(vNum)
;one hundred and twenty-three decillion, four hundred and fifty-six nonillion, seven hundred and eighty-nine octillion, one hundred and twenty-three septillion, four hundred and fifty-six sextillion, seven hundred and eighty-nine quintillion, one hundred and twenty-three quadrillion, four hundred and fifty-six trillion, seven hundred and eighty-nine billion, one hundred and twenty-three million, four hundred and fifty-six thousand, seven hundred and eighty-nine, point one two three

;explaining vDoTrimFrac (trim trailing zeros)
vNum := "1.200"
MsgBox, % JEE_NumToWord(vNum) ;one, point two
MsgBox, % JEE_NumToWord(vNum, 0) ;one, point two zero zero

;explaining vAddExtraAnd (truer to spoken English e.g. 'One Thousand and One Nights')
vNum := "1001"
MsgBox, % JEE_NumToWord(vNum, 1, 0) ;one thousand, one
MsgBox, % JEE_NumToWord(vNum, 1, 1) ;one thousand, and one
return

;==================================================

;JEE_NumSpell
;JEE_SpellNum
JEE_NumToWord(vNum, vDoTrimFrac:=1, vAddExtraAnd:=0)
{
	if !vNum
		return "zero"

	oArrayX := StrSplit("thousand,million,billion,trillion,quadrillion,quintillion,sextillion,septillion,octillion,nonillion,decillion", ",")
	(oArrayU := StrSplit("zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen", ",")).RemoveAt(0)
	oArrayT := StrSplit("ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety", ",")

	vNum := StrReplace(vNum, "-", "", vCount)
	if vCount
		vOutput := "minus "
	vNum := StrReplace(vNum, ",")
	vNum1 := LTrim(StrSplit(vNum, ".")[1], "0")
	if vDoTrimFrac
		vNum2 := RTrim(StrSplit(vNum, ".")[2], "0")
	else
		vNum2 := StrSplit(vNum, ".")[2]

	if ((vLen := StrLen(vNum1)) > 36)
		return
	if (Mod(vLen, 3) = 1)
		vNum1 := "00" vNum1
	else if (Mod(vLen, 3) = 2)
		vNum1 := "0" vNum1

	vMag := Ceil(vLen/3)-1
	Loop, % Ceil(vLen/3)
	{
		oTemp := StrSplit(SubStr(vNum1, (A_Index*3)-2, 3))
		vTemp := (oTemp.2 * 10) + oTemp.3
		if oTemp.1
			vOutput .= oArrayU[oTemp.1] " hundred" (vTemp?" and ":"")
		else if !vMag && (vLen > 3) && vAddExtraAnd
			vOutput .= "and "

		if (vTemp >= 20)
			vOutput .= oArrayT[oTemp.2] (oTemp.3?"-" oArrayU[oTemp.3]:"")
		else if vTemp
			vOutput .= oArrayU[vTemp]
		vOutput .= " " oArrayX[vMag] ", "
		vMag--
	}

	vOutput := RTrim(vOutput, ", ")
	if !vNum2
		return vOutput
	if (vOutput = "")
		vOutput := "zero"
	vOutput .= ", point"
	Loop, Parse, vNum2
		vOutput .= " " oArrayU[A_LoopField]
	return RTrim(vOutput)
}

;==================================================
Btw a useful link that gives slightly different results to my function:
spell 1001 - Wolfram|Alpha
http://www.wolframalpha.com/input/?i=spell+1001

Also, it's worth noting that there may be differences in UK/US English for 'spelling' numbers, I believe this may be one difference: 'one hundred four' (US) v. 'one hundred and four' (UK), my function uses the latter.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

NTOW_US() - Number to words expander - US version  Topic is solved

09 Sep 2017, 12:41

@ ivill

Further to your query via PM, NTOW_US() is a quick re-write of NTOW_IN().
Please test it and let me know if anything needs to be amended.

Note: The number passed to NTOW_US() may contain only 0 to 9 and a decimal point. Negative numbers shouldn't be passed.
You may cleanup your input number with Num := RegExReplace( Num, "[^0-9.]" )

Code: Select all

NTOW_US( Num, Recursive:=False) { ; By SKAN | 09-Sep-2009 | goo.gl\????? 
Static Nums := {L0:"",L01:"ONE",L02:"TWO",L03:"THREE",L04:"FOUR",L05:"FIVE",L06:"SIX",L07:"SEVEN"
   , L08:"EIGHT",L09:"NINE",L10:"TEN",L11:"ELEVEN",L12:"TWELVE",L13:"THIRTEEN",L14:"FOURTEEN"
   , L15:"FIFTEEN",L16:"SIXTEEN",L17:"SEVENTEEN",L18:"EIGHTEEN",L19:"NINETEEN",L20:"TWENTY"
   , L30:"THIRTY",L40:"FORTY",L50:"FIFTY",L60:"SIXTY",L70:"SEVENTY",L80:"EIGHTY",L90:"NINETY"
   , G1:"",G2:"THOUSAND",G3:"MILLION",G4:"BILLION",G5:"TRILLION",G6:"QUADRILLION",G7:"QUINTILLION"}
Local fNum, aNum, lNum, N11, N21, N31, N22, Word := "", Words := "" 

  If (Recursive)
  {
      N11  := SubStr(Num,1,1)
      N21  := SubStr(Num,2,1) 
      N31  := SubStr(Num,3,1)
      N22  := SubStr(Num,2,2)
      N11 := ( N11 ? ( N11>1 ? Nums["L0" N11] . " HUNDRED" : "HUNDRED" ) : "" )
      N22 := ( N22<=20 ? Nums["L" N22] : Nums["L" . N21 . "0"] . " " . Nums["L0" N31] )
      Return Trim(N11 . " " . N22, A_Space)    
  }

  VarSetCapacity( fNum,258,0 )
  DllCall( "GetNumberFormat", "UInt",0x0409, "UInt",0, "Str",Num, "UInt",0, "Str",fNum, "Int",128 )

  aNum := StrSplit( fNum, [",","."] )
  lNum := aNum.Length() + 1
  While ( lNum-- > 1 )
  {
      If ! aNum[lNum]
         Continue
         
      aNum[lNum] := Format( "{:03}", aNum[lNum] )
      Word  := %A_ThisFunc%( aNum[lNum], True ) . ( A_Index>2 ? " " . Nums["G" A_Index-1] : "" ) 
      Word  := ( A_Index=1 ? "CENTS " . Word : Word )
      Words := ( Words="" ? "AND " : "" ) . Word . " " . Words
  }

  If ( SubStr( Words,1,4) = "AND " )
       Words := SubStr(Words,5) 

Return RTrim(Words," ")
}
Example call:

Code: Select all

AHK_MAX_UINT64 := 2**63-1 ; 9223372036854775807
MsgBox % NTOW_US( AHK_MAX_UINT64 )

/*
Result:

NINE QUINTILLION TWO HUNDRED TWENTY THREE QUADRILLION THREE HUNDRED SEVENTY TWO TRILLION 
THIRTY SIX BILLION EIGHT HUNDRED FIFTY FOUR MILLION SEVEN HUNDRED SEVENTY FIVE THOUSAND 
AND EIGHT HUNDRED SEVEN
*/
PS: I've marked this topic as unsolved. Please remark it as solved when you have a working solution.
My Scripts and Functions: V1  V2
User avatar
ivill
Posts: 124
Joined: 13 May 2016, 02:23

Re: NTOW_US() - Number to words expander - US version

13 Sep 2017, 08:04

SKAN wrote:@ ivill

Further to your query via PM, NTOW_US() is a quick re-write of NTOW_IN().
Please test it and let me know if anything needs to be amended.

Note: The number passed to NTOW_US() may contain only 0 to 9 and a decimal point. Negative numbers shouldn't be passed.
You may cleanup your input number with Num := RegExReplace( Num, "[^0-9.]" )

Code: Select all

NTOW_US( Num, Recursive:=False) { ; By SKAN | 09-Sep-2009 | goo.gl\????? 
Static Nums := {L0:"",L01:"ONE",L02:"TWO",L03:"THREE",L04:"FOUR",L05:"FIVE",L06:"SIX",L07:"SEVEN"
   , L08:"EIGHT",L09:"NINE",L10:"TEN",L11:"ELEVEN",L12:"TWELVE",L13:"THIRTEEN",L14:"FOURTEEN"
   , L15:"FIFTEEN",L16:"SIXTEEN",L17:"SEVENTEEN",L18:"EIGHTEEN",L19:"NINETEEN",L20:"TWENTY"
   , L30:"THIRTY",L40:"FORTY",L50:"FIFTY",L60:"SIXTY",L70:"SEVENTY",L80:"EIGHTY",L90:"NINETY"
   , G1:"",G2:"THOUSAND",G3:"MILLION",G4:"BILLION",G5:"TRILLION",G6:"QUADRILLION",G7:"QUINTILLION"}
Local fNum, aNum, lNum, N11, N21, N31, N22, Word := "", Words := "" 

  If (Recursive)
  {
      N11  := SubStr(Num,1,1)
      N21  := SubStr(Num,2,1) 
      N31  := SubStr(Num,3,1)
      N22  := SubStr(Num,2,2)
      N11 := ( N11 ? ( N11>1 ? Nums["L0" N11] . " HUNDRED" : "HUNDRED" ) : "" )
      N22 := ( N22<=20 ? Nums["L" N22] : Nums["L" . N21 . "0"] . " " . Nums["L0" N31] )
      Return Trim(N11 . " " . N22, A_Space)    
  }

  VarSetCapacity( fNum,258,0 )
  DllCall( "GetNumberFormat", "UInt",0x0409, "UInt",0, "Str",Num, "UInt",0, "Str",fNum, "Int",128 )

  aNum := StrSplit( fNum, [",","."] )
  lNum := aNum.Length() + 1
  While ( lNum-- > 1 )
  {
      If ! aNum[lNum]
         Continue
         
      aNum[lNum] := Format( "{:03}", aNum[lNum] )
      Word  := %A_ThisFunc%( aNum[lNum], True ) . ( A_Index>2 ? " " . Nums["G" A_Index-1] : "" ) 
      Word  := ( A_Index=1 ? "CENTS " . Word : Word )
      Words := ( Words="" ? "AND " : "" ) . Word . " " . Words
  }

  If ( SubStr( Words,1,4) = "AND " )
       Words := SubStr(Words,5) 

Return RTrim(Words," ")
}
Example call:

Code: Select all

AHK_MAX_UINT64 := 2**63-1 ; 9223372036854775807
MsgBox % NTOW_US( AHK_MAX_UINT64 )

/*
Result:

NINE QUINTILLION TWO HUNDRED TWENTY THREE QUADRILLION THREE HUNDRED SEVENTY TWO TRILLION 
THIRTY SIX BILLION EIGHT HUNDRED FIFTY FOUR MILLION SEVEN HUNDRED SEVENTY FIVE THOUSAND 
AND EIGHT HUNDRED SEVEN
*/
PS: I've marked this topic as unsolved. Please remark it as solved when yor have a working solution.
Thanks @SKAN, this solution works without any doubt

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], peter_ahk and 347 guests