w w w . P r o v a t o S y s . c o m
M i c h a e l   C a t a l a n i
9 0 1 . 5 8 1 . 8 7 9 1

 

               


Converting Numeric Fields To Their Corresponding Word Phrase
The Number_s Service Program contains a function that converts a numeric field to a string of words which represent the number. For example, the function would take in a field such as 9431 and convert it to " nine thousand four hundred thirty one." 

Function Example
Let's say we want to return the word phrase of the number 19450.

WordPhrase = Number_NumberToWords( 19450 );
The value of WordPhrase would equal " nineteen thousand four hundred fifty"

This function also works with numbers for up to 5 decimal places.

WordPhrase = Number_NumberToWords( 19450.44051 );
The value of WordPhrase would equal " nineteen thousand four hundred fifty point four four zero five one"

You can also specify to comma delimit the word phrase. This is so the phrase can be inserted into a text that is grammatically correct. Also, if the word phrase is passed to a text to speech engine, the commas will cause the engine to pause after each segment, which results in a more natural speaking pattern.

WordPhrase = Number_NumberToWords( 4528876 );
The value of WordPhrase would equal " four million, five hundred twenty eight thousand, eight hundred seventy six"

Program Example
Here's a quick program example which utilizes the service program to display the number conversions. some of the information available about an object. I named this program NumberR. The following screen shows what the example program looks like:

 

The following is the rpg source for the  ObjectR program:

		
		
     h dftactgrp(*no) bnddir('CF')
     fNumberd   cf   e             workstn

      /copy *libl/qrpglesrc,Number_p

      /free

        dow NOT *inlr;
          exfmt numberda;
          if *in03 = *on;
            *inlr = *on;
          else;
            wordphrase = Number_NumberToWords( Number : YesNo );
          endif;
        enddo;                                                                         

 

The following is the DDS for the NumberD display file which is used by the NumberR program:

		
		
     A*%%TS  SD  20090216  103647  QPGMR       REL-V6R1M0  5761-WDS
     A*%%EC
     A                                      DSPSIZ(24 80 *DS3)
     A                                      CF03(03)
     A          R SCREEN01
     A*%%TS  SD  20090216  103647  QPGMR       REL-V6R1M0  5761-WDS
     A                                  5  2'Object Name...:'
     A                                      COLOR(BLU)
     A                                  6  2'Object Library:'
     A                                      COLOR(BLU)
     A                                  7  2'Object Type...:'
     A                                      COLOR(BLU)
     A            OBJECT        10A  B  5 18COLOR(WHT)
     A            LIBRARY       10A  B  6 18COLOR(WHT)
     A            TYPE          10A  B  7 18COLOR(WHT)
     A                                 23  2'F3-Exit'
     A                                      COLOR(WHT)
     A                                  1  2DATE
     A                                      EDTCDE(Y)
     A                                      COLOR(PNK)
     A                                  2  2TIME
     A                                      COLOR(PNK)
     A                                  1 70USER
     A                                      COLOR(PNK)
     A                                  1 28'Object Information'
     A                                      COLOR(BLU)
     A                                  9  2'Object Exists.:'
     A                                      COLOR(BLU)
     A                                 11  2'Owner.........:'
     A                                      COLOR(BLU)
     A                                 10  2'Library.......:'
     A                                      COLOR(BLU)
     A                                  6 30'(You may specify *LIBL)'
     A                                      COLOR(PNK)
     A                                 12  2'Asp Location..:'
     A                                      COLOR(BLU)
     A                                 13  2'Object Size...:'
     A                                      COLOR(BLU)
     A                                 14  2'Description...:'
     A                                      COLOR(BLU)
     A            EXIST          3A  O  9 19
     A            OBJLIB        10A  O 10 19
     A            OWNER         10A  O 11 19
     A            ASP            3Y 0O 12 19EDTCDE(Z)
     A            SIZE          12Y 0O 13 19EDTCDE(2)
     A            DESC          50A  O 14 19                                                                                                                    

 

The Number_s Service Program
The Number_s service program contains two functions.  The first is Number_NumberToCharacter.  This function is used by the function you will ultimately be using, Number_NumberToWords.  The Number_NumberToCharacter function is also utilized by the currency function Currency_CurrencyToWords.  The currency service program is listed separately on our program code page.

The following code sections should be copied into the appropriate file and members. I use a library named "CF", for "custom functions", for all of my service programs which contain functions which can be accessed across the system.  So within my CF library, I have a source file QRPGLESRC and QSRVSRC.  The following members below then need to be created in their respective files in the library.

Number_p  Prototype Source
The following source code should be placed in a source file member called Number_p.    These are the prototypes for the Service Program. 

		
		
     d Number_NumberToCharacter...
     d                 pr           256a   varying
     d
     d  Number                       15p 0 const
     d  CommaDelimit                  1a   const options(*nopass)
     d

     d Number_NumberToWords...
     d                 pr           256a   varying
     d
     d  Number                       20p 5 const
     d  CommaDelimit                  1a   const options(*nopass)
     d                                                                                                                          


 Number_s Binder Source
The following source should be copied into a member called Object_s in QSRVSRC. This is the binder language for the service program functions.

		
      		
             STRPGMEXP  PGMLVL(*CURRENT)
             EXPORT     SYMBOL(NUMBER_NUMBERTOWORDS)
             EXPORT     SYMBOL(NUMBER_NUMBERTOCHARACTER)
             ENDPGMEXP                                                                          
                               

 
Number_s Service Program Source
The following source should be copied into a member called Number_s in QRPGLESRC. This is the procedure interface and service program source.

 
 

		
        		
     h nomain

      /copy *libl/qrpglesrc,number_p

      * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      *
      * NumberToCharacter - Returns character representation of a whole number
      *
      *  Parameters - 15p 0  A Number field
      *                1a    optional Y - Comma Delimit N-No Comma Delimit
      *                      default is no comma delimit
      *
      *  Returns    - 256a varying  character field
      *
      * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

     p Number_NumberToCharacter...
     p                 b                   export
     d Number_NumberToCharacter...
     d                 pi           256a   varying
     d  Number                       15p 0 const
     d  CommaDelimit                  1a   const options(*nopass)

     d  WorkingNumber  s             15p 0
     d  ThreeDigits    s              3p 0
     d  ArrayIndex     s              3p 0
     d  StartingPosition...
     d                 s              3p 0
     d  NumberString   s            256a   varying
     d                 ds
     d  Single                      190a   inz('one       +
     d                                          two       +
     d                                          three     +
     d                                          four      +
     d                                          five      +
     d                                          six       +
     d                                          seven     +
     d                                          eight     +
     d                                          nine      +
     d                                          ten       +
     d                                          eleven    +
     d                                          twelve    +
     d                                          thirteen  +
     d                                          fourteen  +
     d                                          fifteen   +
     d                                          sixteen   +
     d                                          seventeen +
     d                                          eighteen  +
     d                                          nineteen  ' )

     d  SingleArray                  10a   overlay(Single) dim(19)

     d                 ds
     d  Tens                         90a   inz('blank     +
     d                                          twenty    +
     d                                          thirty    +
     d                                          forty     +
     d                                          fifty     +
     d                                          sixty     +
     d                                          seventy   +
     d                                          eighty    +
     d                                          ninety    ')

     d  TensArray                    10a   overlay(Tens) dim(9)

      /free

         WorkingNumber = Number;

         // strip 3 digits at a time and process
         StartingPosition = 1;

         dow StartingPosition < 14;
           ThreeDigits = %int( %subst(   %editc( WorkingNumber : 'X' )
                                       : StartingPosition
                                       :3)
                                         );

           if ThreeDigits > 0;
             exsr ProcessDigits;
           endif;

           StartingPosition += 3;

         enddo;

         return ( NumberString );

        // * * * * * * * * * * * * * * * * * * * * * * * * * * *
        // P r o c e s s D i g i t s    S U B R O U T I N E
        // * * * * * * * * * * * * * * * * * * * * * * * * * * *

        begsr ProcessDigits;

          if ThreeDigits >= 100;
            NumberString = NumberString +
                   %trim(SingleArray(%int( %subst(%char(ThreeDigits):1:1 ))))+
                           ' hundred ';

            ThreeDigits = ThreeDigits - (%int(%subst(%char(ThreeDigits):1:1))
                                         *100);
          endif;

          if ThreeDigits <> 0;
            if ThreeDigits <  20;
              NumberString = NumberString +
                             %trim(SingleArray( ThreeDigits )) + ' ';
            else;
              ArrayIndex   = %int( %subst( %char( ThreeDigits ) : 1 : 1 ));
              NumberString = NumberString +
                             %trim( TensArray( ArrayIndex ))+ ' ';
              ArrayIndex   = %int( %subst( %char( ThreeDigits ): 2 : 1 ));

              if ArrayIndex > 0;
                NumberString = NumberString +
                               %trim(SingleArray(ArrayIndex))+
                               ' ';
              endif;
            endif;
          endif;

          select;
           when StartingPosition = 1;
             NumberString = NumberString + 'trillion';
             exsr AddComma;
           when StartingPosition = 4;
             NumberString = NumberString + 'billion';
             exsr AddComma;
           when StartingPosition = 7;
             NumberString = NumberString + 'million';
             exsr AddComma;
           when StartingPosition = 10;
             NumberString = NumberString + 'thousand';
             exsr AddComma;
          endsl;

        endsr;


        // * * * * * * * * * * * * * * * * * * * * * * * * * * *
        // A d d C o m m a   S U B R O U T I N E
        // * * * * * * * * * * * * * * * * * * * * * * * * * * *

        begsr AddComma;
          if %parms > 1 and CommaDelimit = 'Y';
            NumberString = NumberString + ',';
          endif;
          NumberString = NumberString + ' ';
        endsr;

      /end-free
     p                 e


      * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      *
      * NumberToWords - Returns a word phrase for a number
      *
      *  Parameters - 20p 5  A Number field
      *                1a    optional Y - Comma Delimit N-No Comma Delimit
      *                      default is no comma delimit
      *
      *  Returns    - 256a varying  character field
      *
      * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

     p Number_NumberToWords...
     p                 b                   export
     d Number_NumberToWords...
     d                 pi           256a   varying
     d  Number                       20p 5 const
     d  CommaDelimit                  1a   const options(*nopass)

     d  NumberString...
     d                 s            256a   varying
     d  Whole          s             15p 0
     d  Decimal        s              5p 0
     d  DecimalString  s              5a
     d  Digit          s              1p 0
     d  ForLoop        s              1p 0
     d  Looper         s              1p 0
      /copy *libl/qrpglesrc,number_p
      /free

        // separate the whole number from the decimal portion
         Whole = %dec( Number : 15 : 0 );
         Decimal = ( Number - Whole ) * 100000;

        // Process the whole number portion of the number
         if Whole = 0;
           NumberString = 'zero ';
         else;
           NumberString = Number_NumberToCharacter( Whole : CommaDelimit );
         endif;

        // Process the decimal portion of the number

         if decimal > 0;
           NumberString = NumberString + 'point ';
           DecimalString = %editc( Decimal : 'X' );

           Select;
             when %subst( DecimalString : 5 : 1 ) <> '0';
               ForLoop = 5;
             when %subst( DecimalString : 4 : 1 ) <> '0';
               ForLoop = 4;
             when %subst( DecimalString : 3 : 1 ) <> '0';
               ForLoop = 3;
             when %subst( DecimalString : 2 : 1 ) <> '0';
               ForLoop = 2;
             other;
               ForLoop = 1;
           endsl;

           For Looper = 1 to ForLoop;
             Digit = %dec( %subst( DecimalString : Looper : 1 ) : 1 : 0 );
             if digit > 0;
               NumberString = NumberString +
                              Number_NumberToCharacter( Digit : CommaDelimit );
             else;
               NumberString = NumberString + 'zero ';
             endif;
           endfor;
         endif;

         return NumberString;

      /end-free
     p                 e                                                                                           

 

Once the members have been copied, we need to create the module and service program. I will show the following commands using the CF library name, but you need to substitute the library you are using if it is different.

CRTRPGMOD MODULE(CF/NUMBER_S) SRCFILE(CF/QRPGLESRC) DBGVIEW(*ALL)

CRTSRVPGM SRVPGM(CF/NUMBER_S) SRCFILE(CF/QSRVSRC)

Now I need to add the service program to my binding directory.  If I didn't have a binding directory set up yet, I would do so by issuing the command:

CRTBNDDIR BNDDIR(CF/CF)

The above command would then create a binding directory in my CF library. 

Next, I would need to add this service program to the binding directory:

ADDBNDDIRE BNDDIR(CF/CF) OBJ((CF/NUMBER_S))

You should now be all set to begin using these functions.  There are only 2 steps to take in order to use these functions in your program:

1) Make sure you specify the binding directory in your control (H) spec:

   ie:  H  bnddir( 'CF' )

2) Use the /copy directive in order to copy in the prototypes for the functions:

  ie :  /copy  *libl / qrpglesrcl, Number_p

 

End of document