|
|
|

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
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