Professional programmers appreciate the importance of standards in developing programs that are readable, understandable, and maintainable. The issue of programming style goes beyond any one language, but the introduction of the RPG IV syntax demands that we reexamine standards of RPG style. With that in mind, here are some simple rules of thumb you can use to ensure that bad code doesn't happen to good RPG software construction.

Use comments to clarify - not echo - your code.Comments that merely repeat the code add to a program's bulk, but not to its value. In general, you should use comments for just three purposes:to provide a brief program or procedure summaryto give a title to a subroutine, procedure, or other section of codeto explain a technique that isn't readily apparent by reading the source

Always include a brief summary at the beginning of a program or procedure.This prologue should include the following information:a program or procedure titlea brief description of the program's or procedure's purposea chronology of changes that includes the date, programmer name, and purpose of each changea summary of indicator usagea description of the procedure interface (the return value and parameters)an example of how to call the procedure

Use consistent "marker line" comments to divide major sections of code.For example, you should definitely section off with lines of dashes or asterisks the declarations, the main procedure, each subroutine, and any subprocedures. Identify each section for easy reference.

Use blank lines to group related source lines and make them stand out.In general, you should use completely blank lines instead of blank comment lines to group lines of code, unless you're building a block of comments. Use only one blank line, though; multiple consecutive blank lines make your program hard to read.

Avoid right-hand "end-line" comments in columns 81-100.Right-hand comments tend simply to echo the code, can be lost during program maintenance, and can easily become "out of synch" with the line they comment. If a source line is important enough to warrant a comment, it's important enough to warrant a comment on a separate line. If the comment merely repeats the code, eliminate it entirely.

Declarations

With RPG IV, we finally have an area of the program source in which to declare all variables and constants associated with the program. The D-specs organize all your declarations in one place.

Declare all variables within D-specs.Except for key lists and parameter lists, don't declare variables in C-specs - not even using *LIKE DEFN. Define key lists and parameter lists in the first C-specs of the program, before any executable calculations.

Whenever a literal has a specific meaning, declare it as a named constant in the D-specs.This practice helps document your code and makes it easier to maintain. One obvious exception to this rule is the allowable use of 0 and 1 when they make perfect sense in the context of a statement. For example, if you're going to initialize an accumulator field or increment a counter, it's fine to use a hard-coded 0 or 1 in the source.

Indent data item names to improve readability and document data structures.Unlike many other RPG entries, the name of a defined item need not be left-justified in the D-specs; take advantage of this feature to help document your code:D ErrMsgDSDS DSD ErrPrefix 3D ErrMsgID 4D ErrMajor 2 OVERLAY(ErrMsgID:1)D ErrMinor 2 OVERLAY(ErrMsgID:3)

Use length notation instead of positional notation in data structure declarations.D-specs let you code fields either with specific from and to positions or simply with the length of the field. To avoid confusion and to better document the field, use length notation consistently. For example, codeD RtnCode DSD PackedNbr 15P 5instead ofD RtnCode DSD PackedNbr 1 8P 5

Use positional notation only when the actual position in a data structure is important.For example, when coding the program status data structure, the file information data structure, or the return data structure from an API, you'd use positional notation if your program ignores certain positions leading up to a field or between fields. Using positional notation is preferable to using unnecessary "filler" variables with length notation:D APIRtn DSD PackedNbr 145 152P 5In this example, to better document the variable, consider overlaying the positionally declared variable with another variable declared with length notation:D APIRtn DSD Pos145 145 152D PackNbr 15P 5OVERLAY(Pos145)

When defining overlapping fields, use the OVERLAY keyword instead of positional notation.Keyword OVERLAY explicitly ties the declaration of a "child" variable to that of its "parent." Not only does OVERLAY document this relationship, but if the parent moves elsewhere within the program code, the child will follow.

If your program uses compile-time arrays, use the **CTDATA form to identify the compile-time data.This form effectively documents the identity of the compile-time data, tying the data at the end of the program to the array declaration in the D-specs. The **CTDATA syntax also helps you avoid errors by eliminating the need to code compile-time data in the same order in which you declare multiple arrays.

Naming Conventions

Perhaps the most important aspect of programming style deals with the names you give to data items (e.g., variables, named constants) and routines.When naming an item, be sure the name fully and accurately describes the item.The name should be unambiguous, easy to read, and obvious. Although you should exploit RPG IV's allowance for long names, don't make your names too long to be useful. Name lengths of 10 to 14 characters are usually sufficient, and longer names may not be practical in many specifications. When naming a data item, describe the item; when naming a subroutine or procedure, use a verb/object syntax (similar to a CL command) to describe the process. Maintain a dictionary of names, verbs, and objects, and use the dictionary to standardize your naming conventions.

When coding an RPG symbolic name, use mixed case to clarify the named item's meaning and use.RPG IV lets you type your source code in upper- and lowercase characters. Use this feature to clarify named data. For RPG-reserved words and operations, use all uppercase characters.

Avoid using special characters (e.g., @, #, $) when naming items.Although RPG IV allows an underscore (_) within a name, you can easily avoid using this "noise" character if you use mixed case intelligently.Indicators

Historically, indicators have been an identifying characteristic of the RPG syntax, but with RPG IV they are fast becoming relics of an earlier era. To be sure, some operations still require indicators, and indicators remain the only practical means of communicating conditions to DDS-defined displays. But reducing a program's use of indicators may well be the single most important thing you can do to improve the program's readability.

Use indicators as sparingly as possible; go out of your way to eliminate them.In general, the only indicators present in a program should be resulting indicators for opcodes that absolutely require them (e.g., CHAIN before V4R2) or indicators used to communicate conditions such as display attributes to DDS-defined display files.

If you must use indicators, name them.V4R2 supports a Boolean data type (N) that serves the same purpose as an indicator. You can use the INDDS keyword with a display-file specification to associate a data structure with the indicators for a display or printer file; you can then assign meaningful names to the indicators.

Use an array-overlay technique to name indicators before V4R2.Using RPG IV's pointer support, you can overlay the *IN internal indicator array with a data structure. Then you can specify meaningful subfield names for the indicators. This technique lessens your program's dependence on numeric indicators. For example:D IndicatorPtr * INZ(%ADDR(*IN))D DS BASED(IndicatorPtr)D F03Key 3 3D F05Key 5 5D CustNotFnd 50 50D SflClr 91 91D SflDsp 92 92D SflDspCtl 93 93C IF F03Key = *ONC EVAL *INLR = *ONC RETURNC ENDIFUse the EVAL opcode with *Inxx and *ON or *OFF to set the state of indicators.Do not use SETON or SETOFF, and never use MOVEA to manipulate multiple indicators at once.

Use indicators only in close proximity to the point where your program sets their condition.For example, it's bad practice to have indicator 71 detect end- of-file in a READ operation and not reference *IN71 until several pages later. If it's not possible to keep the related actions (setting and testing the indicator) together, move the indicator value to a meaningful variable instead.

Don't use conditioning indicators - ever.If a program must conditionally execute or avoid a block of source, explicitly code the condition with a structured comparison opcode, such as IF. If you're working with old S/36 code, get rid of the blocks of conditioning indicators in the source.

4.6 Include a description of any indicators you use.It's especially important to document indicators whose purpose isn't obvious by reading the program, such as indicators used to communicate with display or printer files or the U1-U8 external indicators, if you must use them.

Structured Programming Techniques

Give those who follow you a fighting chance to understand how your program works by implementing structured programming techniques at all times.

Don't use GOTO, CABxx, or COMP.Instead, substitute a structured alternative, such as nested IF statements, or status variables to skip code or to direct a program to a specific location. To compare two values, use the structured opcodes IF, ELSE, and ENDIF. To perform loops, use DO, DOU, and DOW with ENDDO. Never code your loops by comparing and branching with COMP (or even IF) and GOTO. Employ ITER to repeat a loop iteration, and use LEAVE for premature exits from loops.

Don't use obsolete IFxx, DOUxx, DOWxx, or WHxx opcodes.The newer forms of these opcodes - IF, DOU, DOW, and WHEN - support free-format expressions, making those alternatives more readable. In general, if an opcode offers a free-format alternative, use it.

Perform multipath comparisons with SELECT/WHEN/OTHER/ENDSL.Deeply nested IFxx/ELSE/ENDIF code blocks are hard to read and result in an unwieldy accumulation of ENDIFs at the end of the group. Don't use the obsolete CASxx opcode; instead, use the more versatile SELECT/WHEN/OTHER/ENDSL construction.

Always qualify END opcodes.Use ENDIF, ENDDO, ENDSL, or ENDCS as applicable. This practice can be a great help in deciphering complex blocks of source.

5.5 Avoid programming tricks and hidden code.Such maneuvers aren't so clever to someone who doesn't know the trick. If you think you must add comments to explain how a block of code works, consider rewriting the code to clarify its purpose. Use of the obscure "bit-twiddling" opcodes (BITON, BITOFF, MxxZO, TESTB, TESTZ) may be a sign that your source needs updating.

Modular Programming Techniques

The RPG IV syntax, along with the AS/400's Integrated Language Environment (ILE), encourages a modular approach to application programming. Modularity offers a way to organize an application, facilitate program maintenance, hide complex logic, and efficiently reuse code wherever it applies.

Use RPG IV's prototyping capabilities to define parameters and procedure interfaces.Prototypes (PR definitions) offer many advantages when you're passing data between modules and programs. For example, they avoid runtime errors by giving the compiler the ability to check the data type and number of parameters. Prototypes also let you code literals and expressions as parameters, declare parameter lists (even the *ENTRY PLIST) in the D-specs, and pass parameters by value and by read-only reference, as well as by reference.

Store prototypes in /COPY members.For each module, code a /COPY member containing the procedure prototype for each exported procedure in that module. Then, include a reference to that /COPY module in each module that refers to the procedures in the called module. This practice saves you from typing the prototypes each time you need them and reduces errors.

Include constant declarations for a module in the same /COPY member as the prototypes for that module.If you then reference the /COPY member in any module that refers to the called module, you've effectively "globalized" the declaration of those constants.

Use IMPORT and EXPORT only for global data items.The IMPORT and EXPORT keywords let you share data among the procedures in a program without explicitly passing the data as parameters - in other words, they provide a "hidden interface" between procedures. Limit use of these keywords to data items that are truly global in the program - usually values that are set once and then never changed.

Character String Manipulation

IBM has greatly enhanced RPG IV's ability to easily manipulate character strings. Many of the tricks you had to use with earlier versions of RPG are now obsolete. Modernize your source by exploiting these new features.

Use a named constant to declare a string constant instead of storing it in an array or table.Declaring a string (such as a CL command string) as a named constant lets you refer to it directly instead of forcing you to refer to the string through its array name and index. Use a named constant to declare any value that you don't expect to change during program execution.

Avoid using arrays and data structures to manipulate character strings and text.Use the new string manipulation opcodes and/or built-in functions instead.

Use EVAL's free-format assignment expressions whenever possible for string manipulation.When used with character strings, EVAL is usually equivalent to a MOVEL(P) opcode. Use MOVE and MOVEL only when you don't want the result to be padded with blanks.

Avoid Obsolescence

RPG is an old language. After 30 years, many of its original, obsolete features are still available. Don't use them.Don't sequence program line numbers in columns 1-5.Chances are you'll never again drop that deck of punched cards, so the program sequence area is unnecessary. In RPG IV, the columns are commentary only. You may use them to identify changed lines in a program or structured indentation levels, but be aware that these columns may be subject to the same hazards as right-hand comments (see style guideline 1.5).

If an opcode offers a free-format syntax, use it instead of the fixed- format version.Opcodes to avoid include CABxx, CASxx, CAT, DOUxx, DOWxx, IFxx, and WHxx.

If a BIF offers the same function as an opcode, use the BIF instead of the opcode.With some opcodes, you can substitute a built-in function for the opcode and use the function within an expression. At V4R1, the SCAN and SUBST opcodes have virtually equivalent built-in functions, %SCAN and %SUBST. In addition, you can usually substitute the concatenation operator (+) in combination with the %TRIMx BIFs in place of the CAT opcode. The free-format versions are preferable if they offer the same functionality as the opcodes.

Shun obsolete opcodes.In addition to the opcodes mentioned earlier (style guidelines 5.2 and 5.3), some opcodes are no longer supported or have better alternatives.

CALL, CALLB.The prototyped calls (CALLP or a function call) are just as efficient as CALL and CALLB and offer the advantages of prototyping and parameter passing by value. Neither CALL nor CALLB can accept a return value from a procedure.

DEBUG.

With OS/400's advanced debugging facilities, this opcode is no longer supported.You should use display file I/O to display information or to acquire input.

FREE.This opcode is no longer supported.

PARM, PLIST.If you use prototyped calls, these opcodes are no longer necessary.

Miscellaneous Guidelines

Here's an assortment of other style guidelines that can help you improve your RPG IV code.

In all specifications that support keywords, observe a one-keyword-per-line limit.Instead of spreading multiple keywords and values across the entire specification, your program will be easier to read and let you more easily add or delete specifications if you limit each line to one keyword, or at least to closely related keywords (e.g., DATFMT and TIMFMT).

Relegate mysterious code to a well-documented, well-named procedure.Despite your best efforts, on extremely rare occasions you simply will not be able to make the meaning of a chunk of code clear without extensive comments. By separating such heavily documented, well-tested code into a procedure, you'll save future maintenance programmers the trouble of deciphering and dealing with the code unnecessarily.Final Advice

Sometimes good style and efficient runtime performance don't mix. Wherever you face a conflict between the two, choose good style. Hard-to-read programs are hard to debug, hard to maintain, and hard to get right. Program correctness must always win out over speed. Keep in mind these admonitions from Brian Kernighan and P.J. Plauger's The Elements of Programming Style:Make it right before you make it faster.Keep it right when you make it faster.Make it clear before you make it faster.Don't sacrifice clarity for small gains in efficiency.

Tuesday, October 11, 2011

RPG is a programming language for business applications. Originally an initialism for Report Program Generator, it officially no longer stands for anything. Note that while the primary vendor of RPG has been and remains IBM, the language was available from other mainframe and microcomputer manufacturers, including Unisys. The latest incarnation of RPG is RPG IV (ILE RPG) on IBM's System i servers; it inherits the System i Integrated Language Environment’s features such as prototyped functions and procedures, static and dynamic binding, access to C routine libraries, dynamic link libraries, and fully recursive and re-entrant modular code.

OverviewRPG is the mainstay programming language of the IBM System i platform. Originally designed as a query tool, IBM has enhanced the language to become a full-fledged, powerful programming language.An RPG program typically starts off with File Specifications, listing all files being written to, read from or updated, followed by Data Definition Specifications containing program elements such as Data Structures and dimensional arrays, much like a "Working-Storage" section of a COBOL program or var statements in a Pascal program. This is followed by Calculation Specifications, which contain the actual meat of the code. Output Specifications can follow which can be used to determine the layout of other files or reports. Alternatively files, some data structures and reports can be defined externally, mostly eliminating the need to hand code input and output specifications.In the early days of RPG, its major strength was known as the program cycle: every RPG program executes within an implied loop, which can apply the program to every record of a file. At that time each record (individual punch card) would be compared to each line in the program, which would act upon the record, or not, based upon whether that line had an "indicator" turned "on" or "off" — from a set of logical variables numbered 01–99 for user-defined purposes, or other smaller sets based upon record, field, or report processing functions.Alternatively, the cycle can make an interactive program continue to run until explicitly stopped.Today, most RPG programmers avoid using the cycle in favor of controlling the flow of the program with standard looping constructs. The concept of level breaks and matching records is unique to the RPG II language. It was originally developed with card readers in mind. RPG III adds some interesting constructs, but the original RPG language is difficult to beat assuming the developer embraces all of the available constructs and features.

HistoryRPG is one of the few languages created for punch card machines that is still in common use today. This is because the language has evolved considerably over time. It was originally developed by IBM in the 1960s. The name Report Program Generator was descriptive of the purpose of the language: generation of reports from data files, including matching record and sub-total reports.FARGO (Fourteen-o-one Automatic Report Generation Operation) was the predecessor to RPG. Both FARGO and RPG were intended to facilitate ease of transition for IBM tabulating machine unit record equipment technicians to the new IBM 1401 series of computers.Tab machine technicians were accustomed to plugging wires into control panels or plug-boards to implement input, output, control and counter operations (add, subtract, multiply, divide). Tab machines programs were executed by impulses emitted in a machine cycle; hence, FARGO and RPG emulated the notion of the machine cycle with the program cycle. RPG was superior to and rapidly replaced FARGO as the report generator program of choice.The alternative languages generally available at the time were either COBOL or FORTRAN: COBOL was a verbose business oriented language, FORTRAN was a language that facilitated mathematical applications. Other languages of the era included PL/1, ALGOL, and Autocoder. COBOL was more common in mainframe business operations (System/360 models 30 and above) and RPG was more common in shops that were transitioning from tabulating equipment (System/360 model 20).

Language evolutionRPG II was introduced with the System/3 series of computers. It was later used on System/32, System/34, and System/36, with an improved version of the language. ICL also produced a version on its VME/K operating system.RPG III was created for the System/38 and its successor the AS/400 (a mid-range machine). RPG III significantly departed from the original language, providing modern structured constructs like IF-ENDIF blocks, DO loops, and subroutines (RPG2 Supported Subroutines). RPG III was also available for larger systems including the IBM System/370 mainframe running OS/VS1. It was also available from Unisys for the VS/9 operating system running on the Univac 90/60 mainframe.DE/RPG or Data Entry RPG was exclusively available on the IBM 5280 series of data-entry workstations in the early 80s. It was similar to RPG III but lacking external Data Descriptions (DDS) to describe data(files) like on the System/38 and its successors. Instead, the DDS part had to be included into the RPG source itself.RPG/400 with a much cleaner syntax, and tighter integration with the integrated database. This language became the mainstay of development on the AS/400, and its editor was a simple line editor with prompt templates for each specification (type of instruction).RPG IV (aka RPGLE, aka RPG/ILE) was released in 1994 and the name, officially, was no longer an initialism. RPG IV offered a greater variety of expressions within its new Extended Factor-2 Calculation Specification.

RPG IV, a modern languageIn 2001, with the release of OS/400 V5R1, RPG IV offered even greater freedom for calculations than offered by the Extended Factor-2 Calculation Specification: a free-format text-capable source entry, as an alternative to the original column-dependent source format. The "/FREE" calculation does not require the operation code to be placed in a particular column; the operation code is optional for the EVAL and CALLP operations; and syntax generally more closely resembles that of mainstream, general-purpose programming languages.Today, RPG IV is a considerably more robust language. Editing can still be done via the simple editor or it can be edited via PC using IBM's Websphere Development Studio (a customized implementation of Eclipse). IBM is continually extending its capabilities and adding more built-in functions (BIFs). It has the ability to link to Java objects (See IBM's RPG Reference Manual), and i5/OS APIs; it can be used to write CGI programs with the help of IBM's Cgidev2 web toolkit, RPG xTools CGILIB and other commercial Web enabled packages. Even with the changes it retains a great deal of backward compatibility, so an RPG program written 37 years ago could run today with little or no modification.OS/400 was later renamed i5/OS to correspond with the new IBM System i5 branding initiative; the 5 was later dropped in favor of just System i. In March 2008 i5/OS was renamed IBM i as part of the Power Systems consolidation of System i and System p product lines. The new Power Systems also adopt more mainstream version numbers, substituting 6.1 for the twenty year old V1R1M0 notation. The latest release is now referred to as IBM i 6.1 and fully supports the RPG IV language, as well as many others. WebSphere Development Studio Client (WDSC) is now referred to as Rational Developer for i (RDi), of which three product levels are available. They are called Rational Developer for i (RDi), RDi Service Oriented Architecture (RDi SOA), and Rational Application Developer (RAD). The new lineup provides in more granular packaging all of the development tools and support previously offered by WDSC and WDSC Advanced Edition

PlatformsAs stated above, the RPG programming language originally was introduced by IBM for their proprietary 1401, /360, /3, /32, /34, /36, /38 AS/400 and System i systems. There have also been implementations for the Digital VAX, Sperry Univac BC/7, Univac system 80, Siemens BS2000, Burroughs B1700, Hewlett Packard HP3000, ICL 2900 series, Honeywell 6220 and WANG VS, as well as miscellaneous compilers & runtime environments for Unix-based systems (INFINITE 36 (formerly UNIBOL36)) and PCs (Baby/400, Lattice-RPG).RPG II applications are still supported under the HP MPE operating system on HP3000 and the OpenVMS operating system on VAX, Alpha, Unisys MCP, and Integrity processors by the third party Migration RPG compiler

As400 Query, QUERY/400 as it used to be called or IBM Query for Iseries, which is whats shown these days on the Installed Licensed Programs screen (GO LICPGM Option 10) is probably one of the most widely used tools on the as400. This tool has a very straightforward user interface, so is often used by both technical and non technical staff (with relevant training of course). Its a very easy to use tool for displaying, extracting and reporting on data. Query is a separate chargeable product, but I don’t think I have ever worked at a site that didn’t have it installed on all their systems, so you can be pretty sure almost every AS/400 will have the IBM provided query language QUERY/400.

As an example, we will write a query over a typical database file that almost every business system has, the CUSTOMER master file. After extracting the data we will create a report.At the as400 command line type in WRKQRY and hit ENTER:

----------------------------------------------------------------Work with Queries

---------------------------------------------------------------Enter CUSTOMER (or whatever your customer master file is called) as the file you want to query and YOURLIB (replace with your relevant database library) as the Library and press ENTER. Pressing ENTER again will take you back to the Define the Query screen.

The next option down, the Define result fields option, is described thus: “Select this option either to define one or more new fields tobe used as result fields or to see what result fields are already defined for the query. The new fields will hold the results of arithmetic, character, or date and time operations done on other fields in this query”. In this case we don’t need any result fields so we can ignore this option for now.

We do need to select fields that we want to report on. Type 1 next to "Select and Sequence Fields" and press ENTERYou should now see:

----------------------------------------------------------------Type sequence number (0-9999) for the names of up to 500 fields to appear in the report, press Enter.

Since the AS/400 Query knows the file you want to see, as you selected it earlier, it has retrieved the fields in the file and listed them for you to choose from.Weare going to select the following columns:cust numbercust name and address 1cust townlocation codeWe need to enter a number to select each of the fields that we require, so enter a number next to each field, which will determine the order in which they are displayed. Enter 2 next to CUSTNA1, 1 next to CUSTN, 4 next to CUSTTOWN, and 6 next to LOCCD. Press ENTER twice and then you will be back at the definition screen.

as400 QUERY allows you to view the results of the query while you are modifying it, which is handy as it allows you correct any errors there and then

This is the first steps to creating a query that shows records on an as400 database file.

The standard IBM CUA window keys are available on this screen. F20 will move the data window to the right, F19 will move the data window back to the left. F21 will split the screen into two mini windows, one fixed and one moveable, so you can view 2 parts of the data similultaneously. F12 to cancel returns to the main definition screen

Next is to take option 1 for Column Formatting to modify the column headings to be more descriptive. This allows you to change them to be more meaningful to the out being produced.

To change the sequencing of the query, type 1 next to "Select Sort Fields". Typing a 1 next to the customer number field will ensure that the data is produced in customer number order. Pressing F5 will allow review of the result of applying the sort to the customer number field.

The next step is to decide which records to select. Enter a 1 next to select records. In this case we only want to select records with a location code of '030'. The screen will look like:

Saturday, October 8, 2011

A Service Program is a collection of runnable procedures and available data items easily accessible by other ILE programs. In many respects it is similar to a subroutine library and procedure library.A service program differs from a program in two ways:It does not contain a program entry procedure. This means that you cannot call a service program using the CALL operation.A service program is bound into a program or other service programs using binding by reference.

EDTCDE & EDTWRDare key words used for formatting purpose. EDTCDE cannot be applied to Character filed. And EDTCDE has some Codes pre-defined for example, EDTCDE(Z) – for suppressing the leading zero Y – for date field.EDTWRD can be used to define user defined formatting for a fields.

With the help of Command attention key we can pass only the indicator status to program not the data from screen. While command function key passes indicator status as well as a data from screen to program.

Monday, October 3, 2011

Excellent! Nice to see an AS/400 programmer caring about error handling for a change.

There are three major error handling techniques in RPG; do nothing and let the default error handler take control (that's the one which displays something like "Error occurred at line 1234 (C G D S)"), use resulting indicators and TEST their status, or code automatic subroutines to handle errors.

There are two possible subroutines; A file error subroutine (INFSR) and a program error subroutine (*PSSR). File error routines can be given any name but need to be associated with the file. That is done on the F-spec by using the INFSR keyword. The program error subroutine MUST be called *PSSR and simply having it declared in the program is enough for the RPG compiler to pass control to it when an unmonitored (no resulting indicator) exception occurs. Note that the *PSSR WILL NOT automatically get control for I/O exceptions however the *PSSR can be used for both purposes if you name the *PSSR as the INFSR routine. Both the file and program error routines can be invoked by EXSR e.g., EXSR *PSSR.

Now for the bad news: When the file and program error routines are invoked by the RPG exception handler due to an unmonitored exception it is done as an unconditional branch, a GOTO if you will, rather than an EXSR. This makes it very difficult to determine the return point. The return points provided by RPG (*GETIN, *DETC, etc) are parts of the cycle and are effectively targets for a GOTO from the ENDSR statement in the *PSSR. *GETIN is the start of the Get Input section of the logic cycle. It is not possible to provide your own branch points on the ENDSR statement.

Usually what one does is to use the error routines to gracefully exit the program rather than try to recover. However it may be possible to use the STATUS code fields in the INFDS or SDS data structures to determine if the error is recoverable and design logic into your program such that the *PSSR can determine where it was called from; a status flag of some sort which is tested and then an unconditional branch is performed to the appropriate section of the program. This is usually SO UGLY that I cannot commit such an atrocity and mostly send a nice screen to the user telling them why the program broke, send a message to QSYSOPR, dump the program, job, and joblog, and cleanly close down.

Russ Popiel wrote a book called "RPG Exception Handling" available from Duke Press (News/400 Magazine) which is fairly good.

Here is an extract from my template showing how this stuff is defined. Note that the SDS is externally described and has the fields #STSCD and #LFUST, etc. The DUMP subroutine is the one which decides whether to dump the program, joblog, job, etc. You would test the value of the DBFSTS or DSPSTS fields in the *PSSR to determine if the error was recoverable. A SELEC block with tests and GOTOs would work (ugly but no other choice)***************************************************************************FABC2 UF A E K DISK InfSR(*PSSR) D************************************************* C MOVE '12' KEY 2 C KEY CHAIN ABC2 90 C IF NOT%FOUND(ABC2) C MOVE KEY VBID C MOVE 'AAAAAA' VBNAME C WRITE ABCR2 C ELSE C UPDATE ABCR2 C ENDIF C C************************************************* C EVAL *INLR = '1' C *PSSR BEGSR C RETURN C ENDSR ***************************************************************************

Learning to use the tools on the AS/400 is one of the best ways to leverage your expertise. Managers may be surprised to learn how easy it is to provide users with sample report layouts that can be designed with an on-line tool. This on-line tool is RLU, Report Layout Utility. Because many programmers find its interface to be confusing, not many have become proficient RLU users. Read on and you will learn to create report layouts quickly and easily. In the early days of RPG, reports were always printed using OUTPUT specifications. With the advent of DDS, it became possible to make print files using DDS. This is similar to the way DDS is used to make display files. The AS/400 provides SDA, Screen Design Aid, as an on-line tool to design display files. Similarly, RLU, is an on-line tool to design reports. Suppose a user needs a report showing:

1. Customer number

2. Customer name

3. Customer city

4. Annual purchase amount

These fields are in the customer master file, CUST. We will write an RPG program, CUSR005 to read the CUST file and write a print file, CUSW005. Figure 1 shows the finished report that we will design with RLU. To start RLU, enter the command STRRLU and hit F4. Enter QDDSSRC as the source file. Enter the library name and CUSW005 as the source member. Since this is a narrow report, enter 65 for the page width. For a standard width report, you would use 132 for the page width. RLU now displays its DESIGN REPORT screen. RLU uses so many function keys that there is a base set of function keys and an alternate set of keys. F22 is used to toggle between the base keys and the alternate keys. Right now RLU shows the word, BASE in the upper left portion of the screen to indicate that the base set of function keys is in use. F22 changes to the alternate keys and the changes the display from BASE to ALT. The simplest way to use RLU is to define each line as a separate record. To start working with a line of the report, key DR for DEFINE RECORD in the command area on a blank line. When you hit the enter key, RLU names the record with the default name RCD001. After defining a record, enter VF for VIEW FIELDS in the command area of the same line. RLU then adds a line above the record to show the field information. The heading for the report will be CUSTOMER ANNUAL PURCHASES. On the line with RCD001, key in the heading. Then, convert this string of characters to a constant. Do this by placing the cursor on the first character of the heading and hitting F11 for DEFINE FIELD. Hit F11 again and then ENTER to convert the string of characters to a constant. Finally, center the heading by keying CF for CENTER FIELD on the command portion of the RCD001 line. When you hit ENTER, the heading will center. Now, create a second record. This will be used to print the customer fields. First insert a line to work with. Key I for INSERT in the command area of the RCD001 line and hit ENTER. Then, as before, key DR to define this as a record and then VF for VIEW FIELDS. Next, use RLU to retrieve the field definitions from the master file. Hit F10 for DATABASE FIELDS. Key 1 for the option to ADD FIELD. Leave the FIELD value blank. Enter the library name and CUST for the File. Enter the record name of the CUST file. RLU will then retrieve all the fields in the CUST file and list them. Select the fields for the report. Hit ENTER until you return to the DESIGN REPORT screen. The names of the fields you selected are at the bottom of the screen. Each field is sequentially numbered. To insert the first field in the report, key 1 in the text area of the FLD record above the detail record line. When you hit ENTER, RLU puts that field in the layout. RLU has re-sequenced the remaining fields. Place the remaining fields in the report. If you overlap fields, RLU can get confusing. The simplest way to recover is to delete the record by keying a D in the command area of the record. Then start the record over. If you want to remove a field, put the cursor on the field and hit F16. If you need to move a field, use F13 to mark where the cursor is positioned and then F15 to move the field to a new location. Now that you have placed the fields in a detail record, create headings for the detail line. Insert a line above the detail line. As always, key DR for DEFINE RECORD and then VF to VIEW FIELDS. Simply key the headings in the text area of the blank record that you inserted. Then convert each field to a constant by putting the cursor on the first character of each literal and hitting F11 twice. To help visualize the report, create some sample data lines. Make 5 copies of the detail line by keying SD5 on the command line of the detail line. Now, add a line at the bottom of the report for the total annual purchases. Do this by keying I in the command line of the last record on the screen. As always, key DR and then VF in the command area of the record. Key the word TOTAL in the text area of the record. Convert the word to a constant by placing the cursor on the first letter of the word and hitting F11 twice. Now, add a new field for the accumulated total. This can get confusing. Place the cursor where you want the total amount to print. Hit F11 to DEFINE FIELD. On the DEFINE FIELD INFORMATION screen, change the name of the field from the default FLD001 to TOTPUR. Change the length of data to 9. Hit PAGE DOWN. Change the data type to 2 for ZONED and enter 2 for decimal positions. Then hit F10 to WORK WITH KEYWORDS. Select EDTCDE by keying 2 next to it. Hit ENTER and key 1 for the EDTCDE value. Hit ENTER a few times and you will see that you have added a field for the total purchases. Finally, add the date and page counter to the first heading line. Do this by adding a field of the appropriate length, converting it to a constant and then selecting the appropriate keyword. Also, rename the records by using F18 for RECORD KEYWORDS and then F10 to rename the record. Exit RLU with F3. You can save the DDS, compile it and generate a prototype report all from the exit screen. Figure 2 shows the complete RPG program to print the report.

RPG Output Specifications.

The edit code is in position 44 on the same line as the field name to be edited.An edit word can be entered in quotation marks for more specific editing.

DDS Specifications.

EDTCDE() or EDTWRD() on screen and printer dds's is entered in the section against the field name to specify how the field is displayed. If the EDTCDE() orEDTWRD() is used on a PF dds, the keyword is used to format the field in QUERY reports.

Calculation specifications.

%EDITC in the calculations section formats a numeric field and stores it in a character field. %TRIM can be used with this to left justify an edited field.

%EDITC has the following formats ...

%EDITC(number: editcode);

12,345.67

%EDITC(number: editcode: currency);

€12,345.67

%EDITC(number: editcode: *astfill);

***12,345.67

%EDITC(number: editcode: *cursym);

€12,345.67

where number = 0012345.67,editcode = K,currency = €,*cursym = €.*CURSYM has a default value of $.This is defined in the system values at QCURSYM. To change the value of *CURSYM for the program, use CURSYM on the H (control) specification.e.g. H cursym('€')

This is an example of using %EDITW ...

%EDITW(znumber: zword);

12,345Euros 67Cents

where znumber is defined as 7,2 and containes 0012345.67,zword contains " , Euros& Cents".(There are 4 spaces to the left of the comma, 3 spaces to the right of the comma and 2 spaces after Euros.The & will force a space to be output, the spaces will be filled with digits from the number field.)

About Me

Hi AS400 Guy

This blogs is helpfull for AS400 Learner, Programmer, Analyst, and AS400 Trainer.

Here i m giving the Topoics which is very important in the world of AS400 Programming and Maintainance and these Topics have really helpfull for me also.

Everyone who related to IBM's As400 Technology (System i) most welcome to leran and elaborate AS400 from this Blog.
I want to help those person who finds difficulty to learn As400 technology and the person who wants more eleborate the As400 skill.
At the end I welcome your suggestion also by your comments..