Writing reports and presentation subfiles is not often on the average programmer’s list of favorite things to do. These projects can be tedious and time-consuming. The specifications for these jobs usually change when the user sees the results of the request because, for some reason, users often expect you to program what they want and not what they ask for. Unless ESP runs in your bloodline, you probably have been caught in this scenario yourself.
The AS/400 offers many ways to format data when you are outputting a single data element. Edit codes and edit words are great formatting tools for single fields. The challenge comes when you need to embed the data element within a string of variable text. With the advent of new data types and built-in functions (BIFs) over the last several years, formatting individual data elements has become easier. But what if your legacy system is still RPG III? To help remove some of the tedium involved in formatting dates, times, and numeric data for presentation, we have designed an RPG IV program that you can call from your RPG III programs.
Times and Dates and Amounts! Oh My!
Figure 1 shows a small window that illustrates how our utility works. As seen in Figures 2, 3, and 4, respectively, this sample program allows you to key an input date, input time, or input amount along with an output description code and press Enter. The result is that the formatted data will be displayed at the bottom of the window. If the code you key is not valid with the type of input you keyed, an error message will be displayed. You can download the source code for the display file that defines this window (FMT014DS) and the RPG IV program that drives it (FMT014RG) from the Midrange Computing Web site at www.midrangecomputing.com/mc/.
Figure 2 shows the output description code for dates. Our utility supports several of the more popular date data type formats as well as a few of our own that we added. As seen in Figure 3, time fields are usually output in far less exciting flavors. Numeric output is often needed in a wide variety of formats, so we chose to have our little utility support the numeric edit codes supported by IBM output specifications or DDS files. Figure 4 shows the codes and sample output. And, just for kicks, we allowed you to add a floating dollar sign to the numeric output.
From Soup to Nuts
Let’s discuss how the code works. As seen in Figure 5, the FMT015RG program accepts five fields as input. These five input fields are described in a single, externally described data structure named FORMATDS and may be seen in Figure 6. (For the uninitiated, an externally described data structure is simply a physical file that holds no data but is used to describe a block or grouping of data—parameters, in this case). If you look at the code in the FMT014RG program, you will see how we used the externally described data structure to call the FMT015RG program. The FMT015RG program reformatted the data and passed the results back in the parameters described by the externally described data structure.
If program FMT015RG determines that a date was sent, it checks the date for validity. The program expects the date to be passed as six digits in the mmddyy format. For example, September 30, 1999 would be passed as 093099. If the date is deemed invalid, an error message is issued and control is returned to the calling program. On the other hand, if the date is deemed valid, the program reformats the date depending upon the output description code passed to the program (valid codes are shown in Figure 2). Once again, invalid format codes will result in an error and control will be passed back to the calling program. If both the date and output description codes are valid, the data will be appropriately formatted and control will be passed to the calling program. If you look at the code, you will see that utilizing the move operation and date data type performs much of the formatting task. When the program must determine the day of the week, it does so by subtracting a base date (defined in the definition specifications) from the input date. The result of that operation is divided by seven (the number of days in the week), and the remainder is used as a single-digit index field for our compile time array named days.
If an input time is passed, the utility essentially works just as it would with an input date. There are only two flavors of time fields supported, and they are described in Figure
3. Once again, the program uses the time data type to perform its formatting functions. In the case of a numeric input field, we used the %EDITC (Edit Code) BIF to apply the edit code to the numeric input field. When the floating dollar sign is requested, the program uses the EVAL (Evaluate) with the %TRIM parameter to remove leading and trailing blanks and concatenate the dollar sign to the desired output. Once the output is properly formatted, the value is returned to the calling program.
By using the tool we’ve shown you, you’ll find that formatting data from RPG III programs is now easier than ever. In fact, CL programs can call FMT015RG, as well. Just like any job, using the right tool can make you more productive and enhance your value to your employer.
Finale
Figure 1: This demonstration program illustrates how FMT015RG edits dates, times, and numbers.
Format Format Example
Parameter Numeric Month, Day, Year *MDY 12/31/99 Numeric Day, Month, Year *DMY 31/12/99 Numeric Year, Month, Day *YMD 99/12/31 Alphanumeric Month, Day, Year *AMDY December 31, 1999 Alphanumeric Month, Day, Year *ALF Friday, December 31, 1999 (including the day of the week)
Day of the Week *DOW Friday
Figure 2: FMT015RG supports a variety of date formats and can be expanded to support more.
Format Format Parameter Example International Organization *ISO 16:24:32 for Standardization (ISO)
IBM USA Standard *USA 04:24 PM
Figure 3: FMT015RG currently edits time in two common formats.
Code Commas Print Zero Sign Other Sample
Balance? 1 Yes Yes None 9,999.99 2 Yes No None 9,999.99
3 No Yes None 9999.99
4 No No None 9999.99
A Yes Yes CR 9,999.99CR B Yes No CR 9,999.99CR
C No Yes CR 9999.99CR D No No CR 9999.99CR
J Yes Yes - 9,999.99-
K Yes No - 9,999.99-
L No Yes - 9999.99-
M No No - 9999.99-
X Remove plus sign 00099999
Y Date field edit 9/99/99
Z Zero Suppress 999999
Figure 4: FMT015RG edits numbers and can prefix a currency symbol to the edited string.
*===============================================================
* To compile:
*
* CRTBNDRPG PGM(XXX/FMT015RG) SRCFILE(XXX/QRPGLESRC)
*
*===============================================================
d Months s 11 dim(12) ctdata perrcd(6)
d Days s 9 dim(7) ctdata perrcd(7)
*
d Parameters e ds extname(FormatDS)
d EditCode 1 Overlay(OutputDesc:1)
d Currency 1 Overlay(OutputDesc:2)
*
d ds inz
d WorkDate 1 10d datfmt(*iso)
d WorkDay 9 10
d WorkMonth 6 7
d WorkIndex 6 7 0
d WorkYear 1 4
*
d BaseDate s d inz(d’1901-01-04’)
d Index s 3 0 inz
d TempField s 7 0 inz
d WorkTime s t timfmt(*hms)
c *entry plist
c parm Parameters
* If an input date is specified, validate the date
b01 c If InputDate > 0 c *mdy test(d) InputDate 68
b02 c If *in68 c Eval OutputData = ‘Invalid Input Date’
x02 c Else
c *mdy Move InputDate WorkDate
b03 c Select c When OutPutDesc = ‘*MDY’
c *mdy Movel WorkDate OutputData
c When OutPutDesc = ‘*DMY’
c *dmy Movel WorkDate OutputData
c When OutPutDesc = ‘*YMD’
c *ymd Movel WorkDate OutputData
c When OutPutDesc = ‘*AMDY’
c Move WorkMonth Index
c Eval OutputData = %Trim(months(WorkIndex)) +
c ‘ ‘ + Workday + ‘, ‘ + WorkYear
c When OutPutDesc = ‘*ALF’
c Exsr DowSr
c Eval OutputData = %Trim(days(Index)) +
c ‘, ‘ + %Trim(months(WorkIndex)) +
c ‘ ‘ + Workday + ‘, ‘ + WorkYear
c When OutPutDesc = ‘*DOW’
c Exsr DowSr
c Eval OutputData = %Trim(days(Index))
c Other
c Eval OutputData = ‘Invalid Description’
e03 c EndSl
e02 c EndIf c Return
e01 c Endif
* If an input time is specified, validate the time
b01 c If InputTime > 0 c *hms test(t) InputTime 68
b02 c If *in68 c Eval OutputData = ‘Invalid Input Time’
x02 c Else
c *hms Move InputTime WorkTime
b03 c Select c When OutPutDesc = ‘*HMS’
c *hms Movel WorkTime OutputData
c When OutPutDesc = ‘*USA’
c *usa Movel WorkTime OutputData
c Other
c Eval OutputData = ‘Invalid Description’
e03 c EndSl
e02 c EndIf c Return
e01 c Endif
* If an input amount is specified, validate the edit code
b01 c If InputNbr 0
b02 c Select c When EditCode = ‘1’
c Eval OutputData = %EditC(InputNbr : ‘1’)
c When EditCode = ‘2’
c Eval OutputData = %EditC(InputNbr : ‘2’)
* ... similar code omitted for codes 3, 4, A-D, J-Q, X, and Y
* ... for publication; duplicate above lines and modify
c When EditCode = ‘Z’
c Eval OutputData = %EditC(InputNbr : ‘Z’)
c Other
c Eval OutputData = ‘Invalid Edit Code’
e02 c EndSl
* Apply a floating dollar sign, if applicable...
b02 c If Currency = ‘$’ c Eval OutputData = ‘$’ + %Trim(OutputData)
x02 c Else
c Eval OutputData = %Trim(OutputData)
e02 c EndIf c Return
e01 c Endif
c eval *inlr = *on
*** calculate day of the week from month/day/year ****************
csr Dowsr begsr
* Day is Friday when index = 1, Saturday when the index is 2, etc..
c WorkDate SubDur Basedate Tempfield:*D
c Div 7 Tempfield
c mvr Index
c add 1 Index
csr endsr
*
** Months
January February March April May June
July August September October November December
** Days
Friday Saturday Sunday Monday Tuesday WednesdayThursday
*===============================================================
* To compile:
*
* CRTPF FILE(XXX/FORMATDS) SRCFILE(XXX/QDDSSRC) MBR(*NONE)
*
*===============================================================
A R FORMATDS TEXT(‘Format Data Structure’)
A INPUTDATE 6S 0 TEXT(‘Input Date’)
A INPUTTIME 6S 0 TEXT(‘Input Time’)
A INPUTNBR 9S 2 TEXT(‘Input Number’)
A OUTPUTDESC 5A TEXT(‘Description of Output’)
A OUTPUTDATA 50A TEXT(‘Output Data’)
LATEST COMMENTS
MC Press Online