Showing posts with label free form RPG. Show all posts
Showing posts with label free form RPG. Show all posts

Tuesday, November 4, 2008

Convert amount to words in RPG ILE

I have had a situation where the amount had to be converted into words so that it can be printed on checks. A little googling got me to this solution. I had to convert it to the free form version for my use. There might be other/better versions out there, but this worked for me. You can find the original version (if the link is still active) here

      //  =============================================================
      //  =  Service program... NbrToWords / CvtNbrToWords           
      //  =  Description....... Service program to convert a number   
      //  =                     to words                                                          
      //  =  Amount needs to be converted into words for printing on  
      //  =  checks.                                                  
      //  =                                                          
      //  =  CrtRPGMod  Module( Your library/NbrToWords )       +             
      //  =             SrcFile( Your library/YourSrcFile )                  
      //  =                                                           
      //  =  CrtSrvPgm  SrvPgm( Your library/NbrToWords )       +            
      //  =             Export( *All )                  +            
      //  =             ActGrp( *Caller )                            
      //  =============================================================

     H NoMain

      //  -------------------------------------------------------------
      //  -  Procedure prototypes                                     -
      //  -------------------------------------------------------------

     D CvtNbrToWords   Pr           200A
     D  Number                       15S 0 Value

      //  -------------------------------------------------------------
      //  -  Global variables                                         -
      //  -------------------------------------------------------------

     D MaxGrps         C                   5

     D Words           S             13    Dim(99)
     D                                     CtData

     D Grps            S              8    Dim(MaxGrps)
     D                                     CtData

      //  =============================================================
      //  =  Procedure:   CvtNbrToWords                               
      //  =  Description: Convert number to words                     
      //  =============================================================

     P CvtNbrToWords   B                   Export

      //  -------------------------------------------------------------
      //  -  Procedure interface                                      -
      //  -------------------------------------------------------------

     D CvtNbrToWords   Pi           200A
     D  Nbr                          15S 0 Value

      //  -------------------------------------------------------------
      //  -  Variable declarations                                  
      //  -------------------------------------------------------------

     D AlphaNbr        S             15

     D WorkFld         DS
     D  Work3                         3
     D  Work2                         2    Overlay( Work3 : 2 )
     D  Work1                         1    Overlay( Work3 : 1 )

     D Count           S              5I 0
     D Pos             S              5I 0
     D Idx             S              5I 0

     D RtnWords        S            200A   Inz

      //  -------------------------------------------------------------
      //  -  Convert number to words - logic                          -
      //  -------------------------------------------------------------

      /Free

           Select;

           When Nbr = *Zero;
             RtnWords = 'zero';

           Other;
             If Nbr < *Zero;
               RtnWords = 'negative';
               Nbr = Nbr * -1;
             EndIf;

             EvalR AlphaNbr = %EditC(Nbr:'X');

             DoW Count <>
               Count += 1;
               Pos = (Count * 3) - 2;
               Work3 = %Subst(AlphaNbr : Pos : 3);

               If Work3 <> '000';

                 If Work1 <> '0';
                   Clear Idx;
                   Idx = %Int(Work1);
                   RtnWords = %TrimR(RtnWords) + ' ' +
                              %TrimR(Words(Idx)) +  ' hundred';
                 EndIf;

                 If Work2 <> '00';
                   Clear Idx;
                   Idx = %Int(Work2);
                   RtnWords = %TrimR(RtnWords) + ' ' + %TrimR(Words(Idx));
                 EndIf;

                 RtnWords = %TrimR(RtnWords) + ' ' + %TrimR(Grps(Count));

               EndIf;
             EndDo;

           EndSl;

           RtnWords = %Trim(RtnWords);

           Return RtnWords;

      /End-Free

     P CvtNbrToWords   E

** CtData Words
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen
fifteen
sixteen
seventeen
eighteen
nineteen
twenty
twenty-one
twenty-two
twenty-three
twenty-four
twenty-five
twenty-six
twenty-seven
twenty-eight
twenty-nine
thirty
thirty-one
thirty-two
thirty-three
thirty-four
thirty-five
thirty-six
thirty-seven
thirty-eight
thirty-nine
forty
forty-one
forty-two
forty-three
forty-four
forty-five
forty-six
forty-seven
forty-eight
forty-nine
fifty
fifty-one
fifty-two
fifty-three
fifty-four
fifty-five
fifty-six
fifty-seven
fifty-eight
fifty-nine
sixty
sixty-one
sixty-two
sixty-three
sixty-four
sixty-five
sixty-six
sixty-seven
sixty-eight
sixty-nine
seventy
seventy-one
seventy-two
seventy-three
seventy-four
seventy-five
seventy-six
seventy-seven
seventy-eight
seventy-nine
eighty
eighty-one
eighty-two
eighty-three
eighty-four
eighty-five
eighty-six
eighty-seven
eighty-eight
eighty-nine
ninety
ninety-one
ninety-two
ninety-three
ninety-four
ninety-five
ninety-six
ninety-seven
ninety-eight
ninety-nine
** CtData Grps
trillion
billion
million
thousand
                                                 

Monday, August 6, 2007

Determining if two numbers are evenly divisible or not

Recently, I have had to validate a couple of entry fields to ensure that the value entered in one field is evenly divisible by the value entered in the other field. The built in function %Rem() worked perfectly for me.

If %Rem(Numerator:Denominator) > 0
// reminder exists, fields not divisible
.......raise error condition - let user know that value is not a multiple
EndIf;

This function returns the reminder from the division operation of its factors -(Numerator/Denominator).

Friday, July 13, 2007

Using Monitor to trap errors

In good old RPG, what would we do if we wanted to check if the value in an alpha variable is integer or not?

Well, we would have defined a constant that has all integers or characters as the value (like '0123456789' for integers, I will not even try to demo the alpha equivalent) and then use the CheckR Opcode or the %CheckR BIF (built in function) to determine if the variable has any matches or not.

With the advent of Free RPG and the Monitor OpCode, there is a better way to do this. Here is how we can handle the error (using free form RPG) if the value in an alpha field is not integer:

Monitor;
CustInt = %Int(%Trim(Cust));
OsCust = %EditC(CustInt:'X'); // Customer number
On-Error; // If value is non-integer
OsCust = Cust;
EndMon;

The vlaue in the variable Cust should always be numeric, but sometimes, it turns out that it can be alpha too. When that happens, as the statement [CustInt = %Int(%Trim(Cust)); ] throwing an error condition is within the [Monitor - EndMon] block, the system flags an error condition and control skips to the statement following the "On-Error" statement. In my case, I just move the value in Cust as is to the OsCust field (which is also alpha)! The "On-Error" statement is executed only when an error condition exists within the Monitor block.

If the value is numeric, I make sure that it is padded with leading zeros (that is where the %EditC comes in handy) before moving it into the target alpha field.

Friday, June 15, 2007

Removing leading zeroes from a non zero character variable

I have a character variable which accepts numeric data. If this data is non-zero, we will have to take out any leading zeroes and then pass the resulting data to an SQL statement for further processing. This is how I acheived it using free form RPG.

InUpc is the character variable.

If %Trim(InUpc) <> *Zeros; // if data is non-zero
DoW %SubSt(%Trim(InUpc):1:1) = '0'; // take out first digit if it is zero
InUpc = %SubSt(%Trim(InUpc):2);
EndDo;
EndIf;

Wednesday, June 13, 2007

Recursion example - RPG, i5

Here is an example of recursion using a procedure in RPG:


P CrtDataQ B Export

D CrtDataQ Pi

D DtaQNam 10A Const
D KeyLen 10i 0 Const
D DtaQLen 10i 0 Const Options(*NoPass)
D LibName 10A Const Options(*NoPass)
D CmdStr S 300A Inz Varying
D Library S 10A Inz('QTEMP')
D DtaQLn S 10i 0 Inz(256)

/Free
// set default values for DtaQLen and LibName...
Select;
When %Parms() = 3;
DtaQLn = DtaQLen;
When %Parms() = 4;
DtaQLn = DtaQLen;
Library = LibName;
EndSl;
CmdStr = 'CRTDTAQ DTAQ(' + %Trim(Library) + '/' + %Trim(DtaQNam) + ') MAXLEN(' + %Trim(%Char(DtaQLn)) + ') SEQ (*KEYED) KEYLEN(' + %Trim(%Char(KeyLen)) + ')';

// Monitor for the possiblity of Data queue already present
// If data queue is already present, delete it and then create.
Monitor;
ExcClCmd(CmdStr:%Len(CmdStr));
On-Error;
DltDataQ(DtaQNam);
CrtDataQ(DtaQNam:KeyLen:DtaQLn:Library); // recursion example
EndMon;

/End-Free

P CrtDataQ E

Convert date into numeric format - RPG free

StrDt is a date field into which a date is being updated. PlHBeg is a julian date in the form yyyyddd.

The code block - %SubSt(%Char(PlHBeg - 1900000):2) gets us the Julian date that is recognized by i5.

StrDt = %Date(%SubSt(%Char(PlHBeg - 1900000):2):*Jul0);

PxHBeg is an 8 digit numeric field into which we are trying to feed a date in Iso (yyyymmdd) format. We use the built in function SubDt to extract each portion of the date and with some basic calculations, we have the date converted to numeric form.

PxHBeg = %SubDt(StrDt:*Y) * 10000 + %SubDt(StrDt:*M) * 100
+ %SubDt(StrDt:*D);

Calculating Time difference using Free form RPG

This is how I calculate the difference between two times in minutes...

TimeDiff = %Int(%Diff(%Time(CurTime:*Hms):%Time(OrdTime:*Hms):*mn));

where Curtime and OrdTime are numeric and *mn denotes that we need the difference in minutes to be put in the TimeDiff field.