Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Is there a function that converts numeric value to words? 1

Status
Not open for further replies.

kimsue

Programmer
Mar 5, 2002
52
US
I have never had the need to print words for numbers, but I need to print checks now. I want to print

One thousand four hundred fifty two and 22/100

or something similar

for a numeric value of 1452.22

Is there a Foxpro function that does this? I can't seem to find one. Thanks for any help.
 

There is no FoxPro function to do that, but a few years ago there were a thread or two on the topic that contained UDFs to do just that. Try the search function.

Also, check out FAQs - they could have made it there.

Please come back to this thread with whatever you find/don't find. I might have somewhere links to similar topics on other sites.
 
Here it is:

A Number to word convertion Utility
faq184-2848

Rob
 
Kimsue,
I was bored in a meeting that I was sitting in today, and came up with this set of 3 routines to do what you need:

Code:
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *

FUNCTION NUMTOTEXT
PARAMETERS nValue

SET TALK OFF
SET EXACT ON
*
cTextNumber = ''
cValue = RIGHT(SPACE(15)+ALLTRIM(STR(nValue,12,2)),15) && ENSURES AN INTEGER WILL HAVE .00 ON END
*
FOR nBuildString = 1 TO 5
	nPassValue = SUBSTR(cValue,nBuildString*3-2,3)
	cFixThree = FIXTHREE(nPassValue)
*	
	DO CASE
		CASE nBuildString = 1
			IF NOT EMPTY(nPassValue)
				cTextNumber = cTextNumber + ' ' + cFixThree + ' BILLION'
			ENDIF
		CASE nBuildString = 2
			IF NOT EMPTY(nPassValue)
				cTextNumber = cTextNumber + ' ' + cFixThree + ' MILLION'
			ENDIF
		CASE nBuildString = 3
			IF NOT EMPTY(nPassValue)
				cTextNumber = cTextNumber + ' ' + cFixThree + ' THOUSAND'
			ENDIF
		CASE nBuildString = 4
			IF NOT EMPTY(nPassValue)
				cTextNumber = cTextNumber + ' ' + cFixThree
			ENDIF
		CASE nBuildString = 5
			cTextNumber = cTextNumber + ' AND '+RIGHT(cValue,2)+'/100'
	ENDCASE
ENDFOR

RETURN cTextNumber

* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *

FUNCTION FIXTHREE
PARAMETERS cThreeDigits

cReturnVal = ''
IF VAL(cThreeDigits) = 0
	cReturnVal = ''
	RETURN cReturnVal
ENDIF
*
IF VAL(LEFT(cThreeDigits,1)) # 0
	cReturnVal = NUMBERNAME(LEFT(cThreeDigits,1)) + ' HUNDRED'
ENDIF
*
IF VAL(SUBSTR(cThreeDigits,2,1)) > 1
	cReturnVal = cReturnVal + ' ' + NUMBERNAME(SUBSTR(cThreeDigits,2,1)+'0')
ENDIF
*
IF VAL(SUBSTR(cThreeDigits,2,1)) > 0 AND VAL(SUBSTR(cThreeDigits,2,1)) < 2
	IF VAL(RIGHT(cThreeDigits,2)) # 0
		cReturnVal = cReturnVal + ' ' + NUMBERNAME(ALLTRIM(STR(VAL(RIGHT(cThreeDigits,2)))))
	ENDIF
ELSE
	IF VAL(RIGHT(cThreeDigits,1)) # 0
		cReturnVal = cReturnVal + ' ' + NUMBERNAME(RIGHT(cThreeDigits,1))
	ENDIF
ENDIF

RETURN cReturnVal

* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *

FUNCTION NUMBERNAME
PARAMETERS cDigit

DO CASE
	CASE cDigit = ''
		RETURN ''
	CASE cDigit = '0'
		RETURN 'ZERO'
	CASE cDigit = '1'
		RETURN 'ONE'
	CASE cDigit = '2'
		RETURN 'TWO'
	CASE cDigit = '3'
		RETURN 'THREE'
	CASE cDigit = '4'
		RETURN 'FOUR'
	CASE cDigit = '5'
		RETURN 'FIVE'
	CASE cDigit = '6'
		RETURN 'SIX'
	CASE cDigit = '7'
		RETURN 'SEVEN'
	CASE cDigit = '8'
		RETURN 'EIGHT'
	CASE cDigit = '9'
		RETURN 'NINE'
	CASE cDigit = '10'
		RETURN 'TEN'
	CASE cDigit = '11'
		RETURN 'ELEVIN'
	CASE cDIGIT = '12'
		RETURN 'TWELVE'
	CASE cDigit = '13'
		RETURN 'THIRTEEN'
	CASE cDigit = '14'
		RETURN 'FOURTEEN'
	CASE cDigit = '15'
		RETURN 'FIFTEEN'
	CASE cDigit = '16'
		RETURN 'SIXTEEN'
	CASE cDigit = '17'
		RETURN 'SEVENTEEN'
	CASE cDigit = '18'
		RETURN 'EIGHTEEN'
	CASE cDigit = '19'
		RETURN 'NINTEEN'
	CASE cDigit = '20'
		RETURN 'TWENTY'
	CASE cDIGIT = '30'
		RETURN 'THIRTY'
	CASE cDigit = '40'
		RETURN 'FORTY'
	CASE cDigit = '50'
		RETURN 'FIFTY'
	CASE cDigit = '60'
		RETURN 'SIXTY'
	CASE cDigit = '70'
		RETURN 'SEVENTY'
	CASE cDigit = '80'
		RETURN 'EIGHTY'
	CASE cDigit = '90'
		RETURN 'NINTY'
ENDCASE

Let me know if you need any of it explained.


Best Regards,
Scott

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Ah, discovered a minor bug. Replace the preivous line with this one:

Code:
cValue = RIGHT(SPACE(15)+ALLTRIM(STR(nValue,15,2)),15) && ENSURES AN INTEGER WILL HAVE .00 ON END

Don't know how that 12 got in there! But this works up to 999,999,999,999.99, and if you're printing checks bigger than that, please send some to me! ;)

You can easily modify this to go to trillians, there should be enough of an example here for you to fix it that up!


Best Regards,
Scott

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Mike,
Hehe... thanks... I am a Yank, who has lived in Australia for the past 8 years, and who now lives in Tokyo, and doesn't speak a word of Japanese... the meeting I was in today was conducted entierly in Japanese, of which I understood about 10%, so might as well do something with one's brain during this period... especially since I'm trying to "Reinvigorate" my VFP capabilities. Was kind of fun. Having looked at the FAQ, I like what I've come up with... a similar solution, that is implemented a little more eligantly... I think I can do better.


Best Regards,
Scott

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Thanks, Scott. It seems like a logical function that would enhance Visual Foxpro:)
 
Kim,
Thanks... it's such a funny one because when you asked the question I thought "There has to be one..." then I went looking. Then I started thinking and I was amazed at how what I thought should be SO simple is actually a bit complex. I can't help thinking I can't make this function better. It felt like an "OK first attempt". Will give it a bit more thought and see if I can't make it a bit more elegant.
Thanks for the star! Much appreciated.


Best Regards,
Scott

"Everything should be made as simple as possible, and no simpler."[hammer]
 

Scott,

Your situation reminds me of a guy I used to know. He was a high-up executive at IBM at the time. He had to visit the company's Tokyo office, and while there he was invited to make a speech to the assembled workers.

He asked his contact if the audience would understand him. He was told it would be OK, provided he spoke clearly and not too fast.

Well, he was a very witty guy, and always filled his speeches with very funny jokes. When he delivered it to his Japanese audience, he was dismayed that he didn't raise a single laugh. He was greeted with deadpan silence and straight faces.

When he sat down, the local managing director got up, and started reading some notes to the audience in Japanese. The workers were soon chuckling, then laughing out loud, and finally applauding enthusiastically. My friend didn't want to appear impolite, so he applauded as well.

Later, his contact took him to one side and told him he shouldn't have clapped so enthusiastically. When asked why, he said to my friend, "it is considered impolite to applaud yourself; the director was reading the translation of your speech."

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Mike,
That's a hoot... have been in several of those situations... my Jenglish is improving. :)



Best Regards,
Scott

"Everything should be made as simple as possible, and no simpler."[hammer]
 

Soctt,

Jenglish? I never came across that one before. I'll remember it.

It's interesting that you are an American in Tokyo. You know, for some reason, I thought you were Scottish. Maybe because of your name.

I also assumed you were in the same time zone as us here in Europe. Or do you work nights? (Or work days and do Tek Tips at night?)

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Kimsue,
Hope you are still watching this space... since I was unhappy with my solution yesterday, I have a new one now, which is more elegant, and I think is "Worthy" of being a good Fox Function. It works accuratly up to 99,999,999,999,999.99 afterwhich Fox goes off the reservation, and starts doing funky things with your values. (Yes, this is over 99 Trillion, so I figure should be safe for use even in the largest of governments.)

You could put in a test value for a passed in value greater than that if you really want to. But anyway, here is my new & improved solution:

Code:
FUNCTION NUMTOTEXT
PARAMETERS nValue

SET TALK OFF
SET EXACT ON
*
cTextNumber = ''
cValue = RIGHT(SPACE(18)+ALLTRIM(STR(nValue,18,2)),18) && ENSURES AN INTEGER WILL HAVE .00 ON END
*
nSubStrPos = LEN(cValue)-2
FOR nBuildString = 1 TO CEILING(LEN(ALLTRIM(cValue))/3)
	cPassValue = SUBSTR(cValue,nSubStrPos,3)
*
	cFixThree = FIXTHREE(cPassValue)
	cTextNumber = cFixThree + ' ' + NUMBERNAME(ALLTRIM(STR(nBuildString))+'A') + ' ' + cTextNumber
*
	nSubStrPos = nSubStrPos - 3
ENDFOR

RETURN cTextNumber

* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *

FUNCTION FIXTHREE
PARAMETERS cThreeDigits

cReturnVal = ''
*
IF AT('.',cThreeDigits) > 0
	RETURN cReturnVal
ENDIF
*
IF VAL(LEFT(cThreeDigits,1)) # 0
	cReturnVal = NUMBERNAME(LEFT(cThreeDigits,1)) + ' HUNDRED'
ENDIF
*
IF VAL(SUBSTR(cThreeDigits,2,1)) > 1
	cReturnVal = cReturnVal + ' ' + NUMBERNAME(SUBSTR(cThreeDigits,2,1)+'0')
ENDIF
*
IF VAL(SUBSTR(cThreeDigits,2,1)) > 0 AND VAL(SUBSTR(cThreeDigits,2,1)) < 2
	IF VAL(RIGHT(cThreeDigits,2)) # 0
		cReturnVal = cReturnVal + ' ' + NUMBERNAME(ALLTRIM(STR(VAL(RIGHT(cThreeDigits,2)))))
	ENDIF
ELSE
	IF VAL(RIGHT(cThreeDigits,1)) # 0
		cReturnVal = cReturnVal + ' ' + NUMBERNAME(RIGHT(cThreeDigits,1))
	ENDIF
ENDIF
*
IF VAL(cThreeDigits) = 0
	RETURN NUMBERNAME('0')
ENDIF
*
RETURN cReturnVal

* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *

FUNCTION NUMBERNAME
PARAMETERS cDigit

DO CASE
	CASE cDigit = ''
		RETURN ''
	CASE cDigit = '0'
		RETURN 'ZERO'
	CASE cDigit = '1'
		RETURN 'ONE'
	CASE cDigit = '2'
		RETURN 'TWO'
	CASE cDigit = '3'
		RETURN 'THREE'
	CASE cDigit = '4'
		RETURN 'FOUR'
	CASE cDigit = '5'
		RETURN 'FIVE'
	CASE cDigit = '6'
		RETURN 'SIX'
	CASE cDigit = '7'
		RETURN 'SEVEN'
	CASE cDigit = '8'
		RETURN 'EIGHT'
	CASE cDigit = '9'
		RETURN 'NINE'
	CASE cDigit = '10'
		RETURN 'TEN'
	CASE cDigit = '11'
		RETURN 'ELEVIN'
	CASE cDIGIT = '12'
		RETURN 'TWELVE'
	CASE cDigit = '13'
		RETURN 'THIRTEEN'
	CASE cDigit = '14'
		RETURN 'FOURTEEN'
	CASE cDigit = '15'
		RETURN 'FIFTEEN'
	CASE cDigit = '16'
		RETURN 'SIXTEEN'
	CASE cDigit = '17'
		RETURN 'SEVENTEEN'
	CASE cDigit = '18'
		RETURN 'EIGHTEEN'
	CASE cDigit = '19'
		RETURN 'NINTEEN'
	CASE cDigit = '20'
		RETURN 'TWENTY'
	CASE cDIGIT = '30'
		RETURN 'THIRTY'
	CASE cDigit = '40'
		RETURN 'FORTY'
	CASE cDigit = '50'
		RETURN 'FIFTY'
	CASE cDigit = '60'
		RETURN 'SIXTY'
	CASE cDigit = '70'
		RETURN 'SEVENTY'
	CASE cDigit = '80'
		RETURN 'EIGHTY'
	CASE cDigit = '90'
		RETURN 'NINTY'
	CASE cDigit = '6A'
		RETURN 'TRILLION'
	CASE cDigit = '5A'
		RETURN 'BILLION'
	CASE cDigit = '4A'
		RETURN 'MILLION'
	CASE cDigit = '3A'
		RETURN 'THOUSAND'
	CASE cDigit = '2A'
		RETURN ''
	CASE cDigit = '1A'
		RETURN 'AND '+RIGHT(cPassValue,2)+'/100'
ENDCASE


Best Regards,
Scott

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Oh, just one other note... the other thing I like about the new solution is it accuratly represnets : 0.23 as: ZERO AND 23/100 instead of just AND 23/100. (That and as mentioned, it now works up to the Trillions, which is reasonably the highest level of accuracy Fox can deal with numerically anyway.)

Cheers!



Best Regards,
Scott

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Hi,

Pitty you dont speak Dutch and pitty you dont need it but I have a numeric time to words (22:45 = quarter to eleven ) function on the shelf.
So if you'r interested just give a shout and I'll tell you the time in Dutch.

Jockey2
 
@Jockey2

If you want to share your time to words function why not start a NEW thread for it?

Rob.
Also Dutch...
 

Kimsue,

This is a bit short:

Code:
lparameter n_amount

public ones,teen,tens

ones = 'ONE  TWO  THREEFOUR FIVE SIX  SEVENEIGHTNINE TEN  '
teen = 'ELEVEN   TWELVE   THIRTEEN FOURTEEN FIFTEEN  SIXTEEN  SEVENTEENEIGHTEEN NINETEEN '
tens = '       TWENTY THIRTY FOURTY FIFTY  SIXTY  SEVENTYEIGHTY NINETY '

c_string = transform(n_amount,"999,999,999,999,999.99")

&& work in bits: trillions,billions,millions,thousands,hundreds,cents

STORE "" TO tril,bill,mill,thou,hund,cens

if val(substr(c_string,01,3)) != 0 then
   o_string = substr(c_string,1,3)
   tril     = Get_Words(o_string) + "TRILLION "
endif
if val(substr(c_string,05,3)) != 0 then
   o_string = substr(c_string,5,3)
   bill     = Get_Words(o_string) + "BILLION "
endif
if val(substr(c_string,09,3)) != 0 then
   o_string = substr(c_string,9,3)
   mill     = Get_Words(o_string) + "MILLION "
endif
if val(substr(c_string,13,3)) != 0 then
   o_string = substr(c_string,13,3)
   thou     = Get_Words(o_string) + " THOUSAND "
endif
if val(substr(c_string,17,3)) != 0 then
   o_string = substr(c_string,17,3)
   hund     = Get_Words(o_string)
endif
hund =  hund + "Shillings"
if val(right(c_string,2)) != 0 then
   o_string = " " + right(c_string,2)
   cens     = Get_Words(o_string) + " CENTS"
   cens     = iif(n_amount>0," AND ","") + CENS
endif
cens = cens + " only"
return proper(tril + bill + mill + thou + hund + cens)
*** "("+alltrim(c_string)+") " + 

*** && convert to words
function get_words(_string)

x1 = ""
x2 = ""

if val(left(_string,1)) != 0 then
   y = val(left(_string,1))
   x1 = allt(substr(ones,(5*y)-4,5)) + " HUNDRED " + iif(val(substr(_string,2,2)) != 0,"AND ","") 
endif
if val(substr(_string,2,1)) != 0 then
   y = val(substr(_string,2,1))
   if y = 1 .and. val(substr(_string,3,1)) != 0 then
      x2 = allt(substr(teen,(9*val(substr(_string,3,1)))-8,9)) + " "
   endif
   if y = 1 .and. val(substr(_string,3,1)) = 0 then
      x2 = iif(x1!=""," AND TEN "," TEN ")
   endif
   if y > 1 then
      x2 = allt(substr(tens,(7*y)-6,7))
   endif
   if y > 1 and val(substr(_string,3,1)) != 0 then
      y1 = val(substr(_string,3,1))
      x2 = x2 + "-" + allt(substr(ones,(5*y1)-4,5)) + " "
   endif
endif
if val(substr(_string,2,1)) = 0 and val(substr(_string,3,1)) != 0 then
   y = val(substr(_string,3,1))
   x2 = x2 + allt(substr(ones,(5*y)-4,5)) +" "
endif

return x1 + x2
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top