Number to Letters

Hi, by suggestions of mattias, i post this code, as an example, or as a nice subroutine thata makes the translation of a number to letters, i hope be useful, or at least as an nice example 8)

P.D. it’s in spanish, but you can translate it.

DEFINE DATA
PARAMETER
01 NUMERO00 (N9.2)
01 REDEFINE NUMERO00
02 NUM01 (N1) 02 NUM02 (N1)
02 NUM03 (N1) 02 NUM04 (N1)
02 NUM05 (N1) 02 NUM06 (N1)
02 NUM07 (N1) 02 NUM08 (N1)
02 NUM09 (N1) 02 NUM10 (A2)
01 REDEFINE NUMERO00
02 NUMA1 (N1) 02 NUMA2 (N2)
02 NUMA3 (N1) 02 NUMA4 (N2)
02 NUMA5 (N1) 02 NUMA6 (N2)
02 NUMA7 (A2)
01 REDEFINE NUMERO00
02 NUMB1 (N1) 02 NUMB2 (N1)
02 NUMB3 (N1) 02 NUMB4 (N6)
02 NUMB5 (N2)
01 REDEFINE NUMERO00
02 NUMC1 (N9) 02 NUMC2 (N2)
01 NUMERO01 (A131)
01 REDEFINE NUMERO01
02 NUMERO02 (A54)
02 NUMERO03 (A77)
01 REDEFINE NUMERO01
02 NUMERO04 (A1/1:131)
LOCAL
01 TABLA01 (A6/1:9) INIT (V)
<‘UNO’,‘DOS’,‘TRES’,‘CUATRO’,‘CINCO’,‘SEIS’,‘SIETE’,‘OCHO’,‘NUEVE’>
01 TABLA02 (A7/10:20) INIT (V)
<‘DIEZ’,‘ONCE’,‘DOCE’,‘TRECE’,‘CATORCE’,‘QUINCE’, , , , ,‘VEINTE’>
01 TABLA03 (A9/2:9) INIT (V)
<‘VEINTI’,‘TREINTA’,‘CUARENTA’,‘CINCUENTA’,‘SESENTA’,‘SETENTA’,
‘OCHENTA’,‘NOVENTA’>
01 TABLA04 (A13/1:9) INIT (V)
<‘CIENTO’,‘DOSCIENTOS’,‘TRESCIENTOS’,‘CUATROCIENTOS’,‘QUINIENTOS’,
‘SEISCIENTOS’,‘SETECIENTOS’,‘OCHOCIENTOS’,
‘NOVECIENTOS’>
01 TABLA05 (A11/1:14) INIT (V)
<‘/100’,‘CON’,‘CON’,‘DIECI’,‘VEINTI’,‘Y’,‘CIEN’,‘MIL’,
‘MILLONES’,‘MILLONES’,‘MILLON’,‘MILLON’,‘CERO’,‘UNO’>
01 NUMERO05 (A131)
01 REDEFINE NUMERO05
02 NUMERO06 (A1/1:131)
01 LETRAS (A15)
01 I (N3)
01 J (N3)
01 CONT (N4)
01 CONT1 (N4)
01 LIMITE (N4)
01 NUMAC (N2)
01 NUMAD (N2)
01 NUMAE (N2)
01 NUMDEC (A6)
01 NUMC1-A (A11)
01 #ASTERISCOS (A20)
01 #CONT (N3)
01 #I (N3)
*
END-DEFINE
*
COMPRESS NUM10 TABLA05 (1) TO NUMERO01 LEAVING NO SPACE
IF NUMERO00 GE 1 AND NUMERO00 LE 1.99
COMPRESS TABLA05 (2) NUMERO01 TO NUMERO01
ELSE
COMPRESS TABLA05 (3) NUMERO01 TO NUMERO01
END-IF
*
IF NUMERO00 > 1.99

  • … (9)
    IF NUM09 > 0 AND NOT(NUMA6 GE 10 AND NUMA6 LE 15)
    COMPRESS TABLA01 (NUM09) NUMERO01 TO NUMERO01
    END-IF
  • … (9) (8)
    IF NUMA6 GE 10 AND NUMA6 LE 15 OR NUMA6 = 20
    COMPRESS TABLA02 (NUMA6) NUMERO01 TO NUMERO01
    END-IF
    MOVE NUMA6 TO NUMAC
    MOVE NUM08 TO NUMAD
    MOVE NUM09 TO NUMAE
    PERFORM COMPLETA
    RESET NUMAC NUMAD NUMAE
  • … (7)
    IF NUM07 > 0
    MOVE TABLA04 (NUM07) TO LETRAS
    IF NUM07 = 1 AND NUMA6 = 0
    MOVE TABLA05 (7) TO LETRAS
    END-IF
    COMPRESS LETRAS NUMERO01 TO NUMERO01
    END-IF
  • … (6)
    IF (NUM06 > 0 AND (NUM07 > 0 OR NUMA6 > 0)) OR
    NUM05 > 0 OR NUM04 > 0 OR NUM06 > 0
    IF NUM06 > 0
    MOVE TABLA01 (NUM06) TO LETRAS
    END-IF
    IF ((NUM05 > 0 OR NUM04 > 0) AND NUM06 = 0)
    OR (NUMA4 GE 10 AND NUMA4 LE 15) OR NUMA4 = 20
    OR (NUMERO00 LE 1999.99)
    RESET LETRAS
    END-IF
    COMPRESS LETRAS TABLA05 (8) NUMERO01 TO NUMERO01
    END-IF
  • … (6) (5)
    IF NUMA4 GE 10 AND NUMA4 LE 15 OR NUMA4 = 20
    COMPRESS TABLA02 (NUMA4) NUMERO01 TO NUMERO01
    END-IF
  • MOVE NUMA4 TO NUMAC
    MOVE NUM05 TO NUMAD
    MOVE NUM06 TO NUMAE
    PERFORM COMPLETA
    RESET NUMAC NUMAD NUMAE
  • … (4)
    IF NUM04 > 0
    MOVE TABLA04 (NUM04) TO LETRAS
    IF NUM04 = 1 AND NUMA4 = 0
    MOVE TABLA05 (7) TO LETRAS
    END-IF
    COMPRESS LETRAS NUMERO01 TO NUMERO01
    END-IF
  • … (3)
    IF NUM03 > 0 OR NUM02 > 0 OR NUM01 > 0
    IF NUM03 > 0
    MOVE TABLA01 (NUM03) TO LETRAS
    END-IF
    IF ((NUM02 > 0 OR NUM01 > 0) AND NUM03 = 0)
    OR (NUMA2 GE 10 AND NUMA2 LE 15) OR NUMA2 = 20
    RESET LETRAS
    END-IF
    IF (NUM03 > 1 OR NUM03 = 0 OR NUM02 > 0 OR NUM01 > 0) AND NUMB4 > 0
    COMPRESS LETRAS TABLA05 (9) NUMERO01 TO NUMERO01
    END-IF
    IF (NUM03 > 1 OR NUM03 = 0 OR NUM02 > 0 OR NUM01 > 0) AND NUMB4 = 0
    COMPRESS LETRAS TABLA05 (10) NUMERO01 TO NUMERO01
    END-IF
    IF NUM03 = 1 AND NUM02 = 0 AND NUM01 = 0 AND NUMA3 = 0
    AND NUMA4 = 0 AND NUMA5 = 0 AND NUMA6 = 0
    COMPRESS LETRAS TABLA05 (11) NUMERO01 TO NUMERO01
    ELSE
    IF NUM03 = 1 AND NUM02 = 0 AND NUM01 = 0
    COMPRESS LETRAS TABLA05 (12) NUMERO01 TO NUMERO01
    END-IF
    END-IF
    END-IF
  • … (2)
    IF NUMA2 GE 10 AND NUMA2 LE 15 OR NUMA2 = 20
    COMPRESS TABLA02 (NUMA2) NUMERO01 TO NUMERO01
    END-IF
    MOVE NUMA2 TO NUMAC
    MOVE NUM02 TO NUMAD
    MOVE NUM03 TO NUMAE
    PERFORM COMPLETA
    RESET NUMAC NUMAD NUMAE
  • … (1)
    IF NUM01 > 0
    MOVE TABLA04 (NUM01) TO LETRAS
    IF NUM01 = 1 AND NUMA2 = 0
    MOVE TABLA05 (7) TO LETRAS
    END-IF
    COMPRESS LETRAS NUMERO01 TO NUMERO01
    END-IF

END-IF
*
IF NUMERO00 GE 0 AND NUMERO00 LE 0.99
COMPRESS TABLA05 (13) NUMERO01 TO NUMERO01
END-IF
IF NUMERO00 GE 1 AND NUMERO00 LE 1.99
COMPRESS TABLA05 (14) NUMERO01 TO NUMERO01
END-IF
*
FOR I 1 131

  • ADD 1 TO CONT
    IF NUMERO04 (I) = ’ ’ AND NUMERO04 (I + 1) = ’ ’
    ESCAPE BOTTOM IMMEDIATE
    END-IF
    ADD 1 TO CONT
    END-FOR

IF NUMERO03 NE ’ ’
MOVE 94 TO LIMITE
ELSE
MOVE 54 TO LIMITE
END-IF
RESET #CONT #ASTERISCOS

COMPUTE LIMITE = 90
COMPUTE #CONT = (LIMITE - CONT - 2) / 2
IF #CONT < 0 THEN
RESET numero01
ELSE
COMPUTE #CONT = 2
MOVE ALL ‘*’ TO #ASTERISCOS UNTIL #CONT
COMPRESS #ASTERISCOS numero01 #ASTERISCOS TO numero01
END-IF
*
DEFINE SUBROUTINE COMPLETA
IF NUMAC GE 16 AND NUMAC LE 19
COMPRESS TABLA05 (4) NUMERO01 TO NUMERO01 LEAVING NO SPACE
END-IF
IF NUMAC GT 20 AND NUMAC LE 29
COMPRESS TABLA05 (5) NUMERO01 TO NUMERO01 LEAVING NO SPACE
END-IF
IF NUMAD > 2
IF NUMAE > 0
MOVE TABLA05 (6) TO LETRAS
ELSE
RESET LETRAS
END-IF
IF NUMAD > 2
COMPRESS TABLA03 (NUMAD) LETRAS NUMERO01 TO NUMERO01
END-IF
END-IF
END-SUBROUTINE
*
END

Hi, My Spanish is not so hot - but I have written a Cheque Text convertor subprogram along the same lines

[code]


  • Program : CHEQTEXT *
  • Author : Axl *
  • Date : 2004/07/13 *
  • Function : Provide the Text representation of a *
  •         Monetary value                               *
    

DEFINE DATA
PARAMETER
01 #AMOUNT (N18.2)
01 REDEFINE #AMOUNT
02 #FIXED (N18)
02 REDEFINE #FIXED
03 #VALUE (N3/1:6)
02 #CENTS (N0.2)
01 #TEXT (A250)
01 #CURRENCY (A20)
LOCAL
01 #GROUPS (A11/1:6) INIT
(05) <‘Thousand’> (04) <‘Million’> (03) <‘Billion’>
(02) <‘Trillion’> (01) <‘Quadrillion’>
01 #I (I1)
01 #UNITS (A15/1:20) INIT
(01) <‘One’> (02) <‘Two’> (03) <‘Three’>
(04) <‘Four’> (05) <‘Five’> (06) <‘Six’>
(07) <‘Seven’> (08) <‘Eight’> (09) <‘Nine’>
(10) <‘Ten’> (11) <‘Eleven’> (12) <‘Twelve’>
(13) <‘Thirteen’> (14) <‘Fourteen’> (15) <‘Fifteen’>
(16) <‘Sixteen’> (17) <‘Seventeen’> (18) <‘Eighteen’>
(19) <‘Ninteen’>
01 #TENS (A15/1:10) INIT
(01) <‘Twenty’> (02) <‘Thirty’> (03) <‘Forty’>
(04) <‘Fifty’> (05) <‘Sixty’> (06) <‘Seventy’>
(07) <‘Eighty’> (08) <‘Ninty’>
01 #TEMP (N3)
01 REDEFINE #TEMP
02 #TEMP-H (N1)
02 #TEMP-TU (N2)
02 REDEFINE #TEMP-TU
03 #TEMP-T (N1)
03 #TEMP-U (N1)
01 #TEMP-DESC (A50)
END-DEFINE
*
RESET #TEXT
/* Process the Integer Value first
IF #FIXED NE 0 THEN
FOR #I = 1 TO 6
#TEMP := #VALUE(#I)
IF #TEMP NE 0 THEN
PERFORM GET-VALUE
COMPRESS #TEXT

Axl, I like the code, but it has some bugs, for example, 111.00 doesn’t work. I’d also like it to handle zero, so I tinkered a bit and this is what I get:


DEFINE DATA
PARAMETER
1 #AMOUNT   (N18.2)
1 REDEFINE #AMOUNT
  2 #FIXED (N18)
  2 REDEFINE #FIXED
    3 #VALUE (N3/1:6)
  2 #CENTS (N0.2)
1 #TEXT     (A250)
1 #CURRENCY (A20)
LOCAL
1 #GROUPS   (A11/1:6) INIT
   (05) <'Thousand'> (04) <'Million'> (03) <'Billion'>
   (02) <'Trillion'> (01) <'Quadrillion'>
1 #I (I1)
1 #UNITS    (A15/0:19) INIT                 (00) <'Zero'>
   (01) <'One'>        (02) <'Two'>         (03) <'Three'>
   (04) <'Four'>       (05) <'Five'>        (06) <'Six'>
   (07) <'Seven'>      (08) <'Eight'>       (09) <'Nine'>
   (10) <'Ten'>        (11) <'Eleven'>      (12) <'Twelve'>
   (13) <'Thirteen'>   (14) <'Fourteen'>    (15) <'Fifteen'>
   (16) <'Sixteen'>    (17) <'Seventeen'>   (18) <'Eighteen'>
   (19) <'Nineteen'>
1 #TENS (A15/1:10) INIT
   (01) <'Twenty'>     (02) <'Thirty'>      (03) <'Forty'>
   (04) <'Fifty'>      (05) <'Sixty'>       (06) <'Seventy'>
   (07) <'Eighty'>     (08) <'Ninety'>
1 #TEMP (N3)
1 REDEFINE #TEMP
  2 #TEMP-H (N1)
  2 #TEMP-TU (N2)
  2 REDEFINE #TEMP-TU
    3 #TEMP-T (N1)
    3 #TEMP-U (N1)
1 #TEMP-DESC (A50)
END-DEFINE
*
RESET #TEXT
*
/* Process the Integer Value first
IF #FIXED NE 0
  FOR #I = 1 TO 6
    #TEMP := #VALUE(#I)
    IF #TEMP NE 0 THEN
      PERFORM GET-VALUE
      COMPRESS #TEXT #TEMP-DESC #GROUPS(#I) INTO #TEXT
    END-IF
  END-FOR
  COMPRESS #TEXT #CURRENCY INTO #TEXT
ELSE
   MOVE 0 TO #TEMP
   PERFORM GET-VALUE
   COMPRESS 'Zero' #CURRENCY INTO #TEXT
END-IF
*
/* Process the Decimal Value last
#TEMP := #CENTS * 100
PERFORM GET-VALUE
*
COMPRESS #TEXT 'and' #TEMP-DESC 'Cents' INTO #TEXT 
*
MOVE LEFT #TEXT TO #TEXT
*******************************************************************
DEFINE SUBROUTINE GET-VALUE
IF #TEMP-TU = 0 THRU 19
   #TEMP-DESC := #UNITS(#TEMP-TU)
ELSE
   IF #TEMP-U = 0 THEN
      #TEMP-DESC := #TENS(#TEMP-T - 1)
   ELSE
      COMPRESS #TENS(#TEMP-T - 1) #UNITS(#TEMP-U) INTO #TEMP-DESC 
   END-IF
END-IF
IF #TEMP-H > 0 THEN
   IF #TEMP-TU NE 0 THEN
      COMPRESS #UNITS(#TEMP-H) 'Hundred and' #TEMP-DESC INTO #TEMP-DESC 
   ELSE
      COMPRESS #UNITS(#TEMP-H) 'Hundred' INTO #TEMP-DESC  
   END-IF
END-IF
END-SUBROUTINE /* Get-Value
*
END

Cheers, knew I had it backed up somewhere but wasn’t too sure of how well it worked.

If anbody needs it in german - here is my proposal :

[code]

0010 * cv-n-txt - Konvertiere Numeric N9 → A(Dynamic) Zahl als Text
0020 * -------------------------------------------------------------
0030 *
0040 * A.Grenz 10.09.2008
0050 *
0060 define data
0070 parameter
0080 1 #d9 (N9) by value /* in
0090 1 redefine #d9
0100 2 #d93 (n3/1:3) /* In 3er-P