Microsoft KB Archive/129921

{| = How to Convert Numbers to Their English Language Equivalent =
 * width="100%"|

ID: Q129921

The information in this article applies to:


 * Microsoft FoxPro for Windows, versions 2.5, 2.5a, 2.5b, 2.6, 2.6a
 * Microsoft FoxPro for MS-DOS, versions 2.0, 2.5, 2.5a, 2.5b, 2.6, 2.6a
 * Microsoft FoxPro for Macintosh, versions 2.5b, 2.5c, 2.6a

SUMMARY
This article shows by example how to display a numeric value in its English language equivalent. For example, in a program that prints checks, you can use this technique to print the value $123.45 on the check as:

One Hundred Twenty Three Dollars and Forty Five Cents

MORE INFORMATION
The following code example takes the total number of digits to the left of the decimal point of a given number and breaks them into groups of three that include a ones place, a teens place, and a hundreds place.

For example, in the number 123,456.00, the 1 and the 4 are in the hundreds place and the 2 and the 5 are in the teens place of their respective groups of three. Understanding this principle is the key to understanding the code in this article.

To demonstrate the following code example, open or switch to Microsoft FoxPro and open an empty or new program file (PRG). Enter the following code:


 * X defines the number to be converted. This may be any value less * than or equal to 9,999,999,999.00 and greater than or equal to 0. * This upper limit is imposed by FoxPro as any larger numbers are * expressed in scientific notation. X = 1234567812.77


 * Determine the string equivalent of the integer portion of X: Z = LTRIM(STR(INT(X)))


 * Determine how many places are to the left of the decimal point: W = LEN(Z)


 * Determine how many groups of 3 appear to the left of the decimal point: Y = INT((LEN(Z) - 1) / 3)


 * Determine how many places to the left of the left-most group of 3: REMAIN = LEN(Z) - (Y * 3)


 * Initialize MYTOTAL to null. MYTOTAL is a character variable used * to hold the text equivalent of X. MYTOTAL = ""


 * Initialize PLACEHOLDER. PLACEHOLDER is a numeric variable used to * track the position (to the left of the decimal point) of the * current number being converted. PLACEHOLDER = 0


 * Initialize two variables that determine the initial of scale of X: BILLION = .F. MILLION = .F.


 * Initialize a flag variable for teens so as not to combine the ones value * with the returning text string: TEENS = .F. NEWVAR = ""


 * Enter a loop that converts each number contained in X (starting with the * left-most) to its character equivalent. W (originally the number of * places to the left of the decimal point in X) is decremented by one each * time a number within X is converted. DO WHILE W > 0

DO CASE * If REMAIN is 1 then the current number under conversion is in         * the 'ones place' of the current group of three. CASE REMAIN = 1 * A number is going to be converted, so decrease string * length by one: W = W - 1 PLACEHOLDER = PLACEHOLDER+1 * Set CURRENTNUM to the current number to be converted: CURRENTNUM = SUBSTR(Z,PLACEHOLDER,1) * Call procedure to convert CURRENTNUM to its text * equivalent: DO TRANS with CURRENTNUM * Determine the scale of CURRENTNUM based on current * value of W:              DO CASE CASE W = 9 SCALE = "Billion " * Determine contents of the billion group of                        * three. NEWVAR = SUBSTR(Z,1,REMAIN) BILLION = .T.                   CASE W = 6 SCALE = "Million " * Determine the contents of the million group of                        * three. If BILLION is false, this is the * left-most group. IF BILLION = .F.                             NEWVAR = SUBSTR(Z,1,REMAIN) ELSE NEWVAR = SUBSTR(Z,REMAIN + 1, 3) ENDIF MILLION = .T.                   CASE W = 3 SCALE = "Thousand " * Determine the contents of the thousands group * of three. If MILLION is false, this is the * left-most group. IF MILLION = .F.                             NEWVAR = SUBSTR(Z,1,REMAIN) ELSE NEWVAR = SUBSTR(Z,REMAIN + 4, 3) ENDIF CASE W = 0 SCALE = "" ENDCASE * Add the returned value (CURRENTNUM) to MYTOTAL: MYTOTAL = MYTOTAL + CURRENTNUM * If the last group of three (determined above) is full of              * zeros, add the scale description. (Billion, Million              * Thousand, and so on.): IF NEWVAR<>"000" MYTOTAL = MYTOTAL + SCALE ENDIF * Set current number position to the "hundreds" place: REMAIN = 3 * If REMAIN is 2, the current number under conversion is in         * the teens place of the current group of three. CASE REMAIN = 2 * Set NEWVAR to 000 because the current number * is in the teens place, which will never have a scale tag * attached to it (Billion, Million, and so on): NEWVAR = "000" * A number is going to be converted, so decrease string * length by one: W = W - 1 PLACEHOLDER = PLACEHOLDER+1 * Set CURRENTNUM to the current number to be converted: CURRENTNUM = SUBSTR(Z,PLACEHOLDER,1) * Call procedure to convert CURRENTNUM to its text * equivalent: DO TRANS2 with CURRENTNUM * Add the returned value (CURRENTNUM) to MYTOTAL: MYTOTAL = MYTOTAL + CURRENTNUM * Set current number position to the ones place: REMAIN = 1 * If REMAIN is 3, the current number under conversion is in         * the hundreds place of the current group of three. CASE REMAIN =  3 * Set NEWVAR to 000 because the current number * is in the hundreds place, which will never have a scale * tag attached to it (Billion, Million, and so on.). NEWVAR = "000" * A number is going to be converted, so decrease string * length by one: W = W - 1 PLACEHOLDER = PLACEHOLDER + 1 * This is in the 'hundreds place, so set unit to Hundred. * This is used in procedure TRANS. UNIT = "Hundred " * Set CURRENTNUM to the current number to be converted: CURRENTNUM = SUBSTR(Z,PLACEHOLDER,1) * Call procedure to convert CURRENTNUM to its text * equivalent: DO TRANS with CURRENTNUM * Add the returned value (CURRENTNUM) to MYTOTAL: MYTOTAL = MYTOTAL + CURRENTNUM * Set current number position to the teens place: REMAIN = 2 ENDCASE ENDDO PLACEHOLDER = 1 * Reinitialize REMAIN to calculate the cents portion of X: REMAIN = 1 * Determine the integer value of X: INTVAL = INT(X) * Check if the integer portion of X is 0: IF INTVAL <> 0 * Use the above value to calculate the decimal portion of X and * convert it to its character equivalent: Z = ALLTRIM(STR(MOD(X,INTVAL)*100)) ELSE * The integer portion of X is zero, so add Zero to MYTOTAL * and set Z equal to the cents portion of X:    Z = ALLTRIM(STR(X * 100)) MYTOTAL = "Zero " ENDIF * Determine if the cents have a teens place: IF LEN(Z)=2 * Set Y1 to the teens place value of the cents figure: Y1 = LEFT(Z,1) * Set Y3 equal to Y1. This is used later to determine whether Y1 was * equal to a 1. If it is, then TRANS2 calculates the ones place. Y3 = Y1    * Call procedure to convert teens place of cents figure to its * text equivalent: DO TRANS2 with Y1 ELSE * The teens place of the cents figure is 0, so set Y1 to null: Y1 = "" * Set Y3 equal to Y1. This is used later to determine whether Y1 was * equal to a 1. If it is, TRANS2 will calculate the ones place. Y3 = Y1 ENDIF * Set Y2 to the ones place value of the cents figure: Y2 = RIGHT(Z,1) * If Y1 and Y2 are null then there are no cents: IF Y2 = "0" AND EMPTY(Y1) Y2 = "No " ELSE * If Y3 is not a 1, determine the text equivalent of    * the ones place of the cents figure: IF Y3 <> "1" * Call procedure to convert ones place of cents figure to its * text equivalent: DO TRANS with Y2    ELSE * If Y3 is a 1, then procedure TRANS2 has already determined the * ones place value. Y2="" ENDIF ENDIF
 * Check for "One dollor" and or "One Cent" for correct return string: IF MYTOTAL == "One "

IF EMPTY(Y1) .AND. Y2 == "One " MYTOTAL = MYTOTAL + "Dollar" + " and " + Y2 + "Cent" ELSE MYTOTAL = MYTOTAL + "Dollar" + " and " + Y1 + Y2 + "Cents" ENDIF ELSE IF EMPTY(Y1) .AND. Y2 == "One " MYTOTAL = MYTOTAL + "Dollars" + " and " + Y2 + "Cent" ELSE MYTOTAL = MYTOTAL + "Dollars" + " and " + Y1 + Y2 + "Cents" ENDIF ENDIF
 * Call a wait window that will display the converted value of X:

WAIT WINDOW MYTOTAL


 * Procedure TRANS, used to convert numbers in the ones and hundreds * place to their text equivalent: PROCEDURE TRANS PARAMETERS CURRENTNUM DO CASE

CASE VAL(CURRENTNUM) = 9 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "Nine " ENDIF ELSE CURRENTNUM = "Nine " + UNIT ENDIF CASE VAL(CURRENTNUM) = 8 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "Eight " ENDIF ELSE CURRENTNUM = "Eight " + UNIT ENDIF CASE VAL(CURRENTNUM) = 7 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "Seven " ENDIF ELSE CURRENTNUM = "Seven " + UNIT ENDIF CASE VAL(CURRENTNUM) = 6 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "Six " ENDIF ELSE CURRENTNUM = "Six " + UNIT ENDIF CASE VAL(CURRENTNUM) = 5 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "Five " ENDIF ELSE CURRENTNUM = "Five " + UNIT ENDIF CASE VAL(CURRENTNUM) = 4 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "Four " ENDIF ELSE CURRENTNUM = "Four " + UNIT ENDIF CASE VAL(CURRENTNUM) = 3 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "Three " ENDIF ELSE CURRENTNUM = "Three " + UNIT ENDIF CASE VAL(CURRENTNUM) = 2 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "Two " ENDIF ELSE CURRENTNUM = "Two " + UNIT ENDIF CASE VAL(CURRENTNUM) = 1 IF REMAIN = 1 IF TEENS CURRENTNUM = "" ELSE CURRENTNUM = "One " ENDIF ELSE CURRENTNUM = "One " + UNIT ENDIF CASE VAL(CURRENTNUM) = 0 CURRENTNUM = "" ENDCASE TEENS = .F. RETURN CURRENTNUM
 * Procedure TRANS2, used to convert numbers in the teens place to their * text equivalent: PROCEDURE TRANS2 PARAMETERS CURRENTNUM DO CASE

CASE VAL(CURRENTNUM) = 9 CURRENTNUM = "Ninety " CASE VAL(CURRENTNUM) = 8 CURRENTNUM = "Eighty " CASE VAL(CURRENTNUM) = 7 CURRENTNUM = "Seventy " CASE VAL(CURRENTNUM) = 6 CURRENTNUM = "Sixty " CASE VAL(CURRENTNUM) = 5 CURRENTNUM = "Fifty " CASE VAL(CURRENTNUM) = 4 CURRENTNUM = "Forty " CASE VAL(CURRENTNUM) = 3 CURRENTNUM = "Thirty " CASE VAL(CURRENTNUM) = 2 CURRENTNUM = "Twenty " CASE VAL(CURRENTNUM) = 1 CURRENTNUM = SUBSTR(Z,PLACEHOLDER,2) DO CASE CASE CURRENTNUM = "19" CURRENTNUM = "Nineteen " CASE CURRENTNUM = "18" CURRENTNUM = "Eighteen " CASE CURRENTNUM = "17" CURRENTNUM = "Seventeen " CASE CURRENTNUM = "16" CURRENTNUM = "Sixteen " CASE CURRENTNUM = "15" CURRENTNUM = "Fifteen " CASE CURRENTNUM = "14" CURRENTNUM = "Fourteen " CASE CURRENTNUM = "13" CURRENTNUM = "Thirteen " CASE CURRENTNUM = "12" CURRENTNUM = "Twelve " CASE CURRENTNUM = "11" CURRENTNUM = "Eleven " CASE CURRENTNUM = "10" CURRENTNUM = "Ten " ENDCASE * Set teens flag to true to avoid adding the ones number to the * returning text string. TEENS = .T.    CASE VAL(CURRENTNUM) = 0 CURRENTNUM = "" ENDCASE RETURN CURRENTNUM Additional reference words: FoxWin FoxMac FoxDos 2.00 2.50 2.50a 2.50b 2.50c 2.60 2.60a KBCategory: kbprg kbcode KBSubcategory: FxprgGeneral
 * }