Standard routines
The standard routines (also called FRM Routines) are the source parts which the user must write. Their objective is to carry out a particular process for a field (either a PF file field, or a display or printer field). The routine is described once in each language. It will be duplicated into several copies (by insertion to the existing sources), in order to repeat the process in many fields.
Each routine has a name divided into 2 parts:
- The first 5 characters constitute the name of the routine.
- The following characters (on 2 to 5 chars.) correspond to the language in which the routine was implemented. It is necessary for each routine to anticipate as much implementation as the language in which it can be used.
For organizational purposes, try to give similar names in alphabetical order (RESA1, RESC2, RESC5) to all the routines that you create for special needs. In this way, they will be easier to find later.
In the case of a routine absent from a language, you can check to see if it exists in a near equivalent language (SQLRPG --> RPG, SQLRPGLE --> RPGLE, RPG38 --> RPG, RPT --> RPG, CLLE --> CLP ...). However, be careful in this case of slight syntax differences between these languages.
In an attempt to insert a source routine into a source, if you don’t find the implementation for the language used, an error message is inserted into the source instead of the routine.
ERROR: Standard FRM Routine XXXXX not found for language YYYYY.
All the routines are stored in the source file AARFRTNF1 in the library produced by ARCAD.
The following are the processes that use routines:
ACVTPGMFLD
Step 3: Automatic modifications of programs. In the case where the routines were configured to be inserted before file writing, or after file reading.ACVTDDSFLD
: Automatic modifications of screens and printers. In the case where routines were configured to be inserted before display, or after input.AFMTFLDDTA
in *GENPGM: Generation of Recovery programs. You must describe in an RPGLE routine the process model that will allow you to generate recovery programs on the processed PF fields.
The main goal of routines is to simplify jobs. The routine must, therefore, be reliable. For that, first test if the code to be inserted meets the required functionality.
If in doubt, you can build a test (a few programs, screens, files), run the propagation with automatic modifications on your test, apply it, compile, make a few manual modifications and then test the obtained results.
If the testing is satisfactory, you can delete your test in the version using option=99 ; the routine is now ready to be inserted to several copies in a number of sources.
Before devising a routine, it is important to understand its particularity. The points below present scenarios when an RPG, CLP or CBL routine will be in the code to be inserted.
-
RPG, RPGLE
If an RPG routine is in the code to be inserted (beginning with BEGSR up to ENDSR), it will only be inserted once in the program.
It is illogical to put the variables $$F1, $$F2, etc.… between a BEGSR and an ENDSR as it will only take the value of these variables.
Be careful when you visualize the new source (using
AWRKFRMCHG
and option 8); you may be surprised as the RPG sub-routine will be inserted right in the middle of processing but this gets fixed itself. During the application of modifications, it will be moved to the end of the code. -
CLP
In the code to be inserted, you can also include CLP work variable declarations.
Each one of these variable declarations (beginning with DCL) will only be inserted once in a source (whether it comes from one or several routines); also, the declarations will be in place (after the PGM or the last DCL).
-
CBL
You can also place COBOL work variable declarations in the code to be inserted.
Each one of these variable declarations (beginning with a level number (01, 77, ...)) will only be inserted once in a source (whether it comes from one or several routines); also, the declarations will be in place (in the WORKING-STORAGE SECTION).
In this section you will see the list of FRM variables which can be used in standard routines. You can put these variable names either on a code line to be inserted, or on a line in routine check language.
In the source code describing the routines, you can use the following FRM variables; these will be replaced by the name of the true variables at insertion.
In CLP, precede these variable names with &: &$$F1.
Don’t forget to leave a few blanks after the variable name in the fixed column languages (RPG, RPGLE), because if the variable name is longer than the 4 characters of its $$xx code, you risk losing one or two characters.
$$F1: Name of the actual field in the file (PF, LF or DSPF/PRTF).
$$A1: For the generation of recovery programs, field name in associated file. For a DSPF/PRTF - name of the associated field if it was possible to name it during the propagation process. Otherwise it is blank.
$$F2: For a PF, LF name of the new file field. For a DSPF/PRTF - name of the field added to the screen (*ALWAYS) or newly-renamed field in the screen replacing the previous field (*NEVER).
$$F3: For a PF, LF name of the third file field, if it was defined. For a DSPF/PRTF - name of the “Other” field if you chose to add this other field in the configuration of propagation types (otherwise blank).
$$FM: Original field format. In this format, each character in the field is represented (max. 50 characters).
Be careful of the recovery programs; it is the format of the field as was entered in the LST_CCPLT
field for the list of fields to propagate.
The format value is systematically inserted here between two apostrophes, so to test this value in a %IF you must also put the comparison value between two apostrophes.
The following table shows the format value of the field as entered in the LST_CCPLT
field.
Format Value | Description |
---|---|
$$TY | Type of original field for a character (A, P, S, ...). |
$$LG | Total length of the original field. (Ex: 5 or 15) |
$$LD | Number of decimals in the original field (Ex: 0 or 2). 0 if it is an alpha field. |
$$DF | Original file name (PF, LF, DSPF, PRTF) for the routine insertion. |
$$DT | Original file type for the insertion: PF(38), LF.., DSPF.., PRTF.. |
$$DM | Original file format for the insertion. |
$$DP | Code insertion position in relation to the instruction. (A for After, and B for Before) |
$$TX | Complete field text (only available for the routines used for generating recovery programs). |
$$T1,$$T2,$$T3,$$T4,$$T5 | Each one of the 5 parts of the text field, each on 10 characters (from 1 to 10, from 11 to 20, etc. …) |
In the entered FRM routines, you can insert check instructions which allow you to direct the insertion processes. These instructions use a mini language based on several commands all starting with % and detailed below.
Once you start using a few lines from this check language, don’t forget to run option 6 = Verify after the routine input. This will avoid incorrect insertions caused by test overlapping such as %IF.
Standard routine languages: here are the language check commands and descriptions:
- %CM condition
- Commentary - Each line having %CM is a commentary which explains the routine: it will not be inserted in the source; it is ignored by the check language.
- %EXIT condition
- Insertion end - Once an active line having %EXIT is reached, the insertion stops.
- %IF condition
-
Conditioning the Insertion - After the %IF you can place a test composed of two items to compare separated by a comparison operator; this could be: = > < <> != <= >= LIKE EQ GT LT NE LE GE.
If the condition is verified, the lines placed after the %IF will be inserted into the source; otherwise the insertion will take place after the %ELSE or after the %ENDIF.
If you want to test a value in relation to a blank, enclose the two items with apostrophes: %IF '$$A1’ <> ' '.
In comparison, the two values compared are put as uppercase letters before evaluating the test. (So, ‘Aa’ = ‘AA’ <- Always TRUE.)
For example, the LIKE operator is used with a comparison item in which the points are considered as any character. %IF $$FM LIKE ‘CCCC....’ indicates that the field format has 8 characters of which the first 4 are Cs and the last 4, any other character.
The conditions can be interlinked (%IF in a %IF, etc..).
- %AND condition
- Following Conditioning - Allows you to have multiple conditions; the %AND must be placed on the line that follows an %IF, another %AND or an %OR. (%AND has priority over %OR).
- %OR condition
- Following Conditioning - Allows you to have multiple conditions; the %OR must be placed on the line that follows an %IF, an %AND or another %OR.
- %ELSE condition
- Negative Conditioning - Indicates the following lines are to be inserted only if the condition placed higher up is not verified.
- %ENDIF condition
- End of lines to insert for a condition - Indicates the end of a condition started higher up by an %IF. The %IF - %ENDIF must be matched.
- %ONCE identifier
-
Insert once - Indicates that the following lines must be inserted only once in the source (the insertion place will be determined by the type of lines to insert (F, D, I, C Card) in RPG(LE).
After %ONCE, you must specify a 3-character ID that will allow you to clearly identify these lines (in the case where they were already added (for another field), coming from the same or another routine).
Important!In these lines to be inserted once, do not use replacement variables; only their first value will be taken into account.
- %ENDONCE
-
Indicates the end of a %ONCE block.
NoteIf you tend to write complex routines but you cannot anticipate all the cases (only the more frequent), you can arrange for all the non-anticipated cases to show up as compilation errors (therefore requiring manual intervention):
Standard routines are used in two very different cases. These are:
- Generation of data recovery programs.
-
Insertion of processes after File read or before File write (or update). This action is configured in the propagation type.
- You indicate by file, either the data files (PF, LF) or the Display/Printer Files (DSPF/PRTF).
- The insertion is normally carried out just before or just after the order that starts an operation on the file, apart from the odd slight difference.
If the programs use the files with external descriptions, the routine will be inserted just before the write order (WRITE, UPDATE, EXFMT) or just after the read order (READ, READE, etc.., CHAIN, EXFMT, CLEAR).
If the file is used as an external description of a data structure, processes are added before writing the *DTAARA (IN) or after its reading (OUT).
If exceptional outputs are used (EXCEPT with except name), the routine will be inserted before the EXCEPT order if the field is in output (in O card).
If exceptional outputs are used (EXCEPT without except name), the routine will be inserted before the first EXCEPT order if the field is in output (in O card). You must verify the placement of the insertion and possibly move the inserted block.
If the file is managed in primary or secondary, the processes after read will be added to the start of C cards; the processes before update will be added before the Total C cards (L1, L2) or before the first subroutine.
It may be necessary to add conditions to these processes.
In CLP, only the SNDRCVF
or RCVF
can allow routine insertions.
In COBOL, the inserted routines are also placed just before or just after the access to the file by READ, WRITE, REWRITE, START.
However, the orders for access to files are multi-line, therefore the insertion is made:
- after the line containing the end of instruction Dot ‘.’ or the END-READ, END-WRITE.
- before the line containing the READ.
In COBOL, another method is often used to access files: the utilization of an intermediate BUFFER (like BUFFER is linked to the file, and BUF1 contains the field descriptions).
* FILE READ, then MOVE BUFFER TO BUF1 a few lines further.
* MOVE BUF1 TO BUFFER, then order WRITE BUFFER a few lines further.
In this case the insertion of routines is made just after or just before the MOVE order (if this is placed in the 50 lines of code after the READ or before the WRITE).
No automatic modification is possible for the access to D.B. files via:
- SQL orders in SQLRPG or SQLCBL
- OPNQRYF or CPYF in CLP.
No routine will be inserted for these methods of file access. However, these orders are managed in the propagation and therefore, are marked.
The AWRKSTDRTN
command allows you to manage the standard routines. It displays the list of available routines. You can place yourself on screen from a specific name, and/or select the routines written for a specific language.
In regards to the implementation of a routine for a language, you can enter one of the following options:
Option | Description |
---|---|
1 = Select | Allows you to choose the routine (to indicate in the configuration, the propagation types. |
2 = Edit | Allows you to modify the routine contents with SEU. If you wish to modify the text, you can do this by exiting SEU then modifying the text and asking for it to be saved. |
In COBOL, certain lines may be flagged as being in anomaly under SEU (as you only insert a bit of incomplete code). Also, the variables $$F1 are incorrect in syntax under this name. This will disappear when $$F1 is replaced by the real field name at the insertion into a COBOL source. | |
3 = Copy | Allows you to copy a routine to a new routine. |
4 = Delete | Deletes the routine in the language indicated. |
5 = Display | Displays the contents of the routine via SEU. |
6 = Check | This option allows you to verify if the FRM syntax for the Routine Check language present in the source is correct or not. |
A message will inform you if the command ran successfully i.e. without any errors. If there are errors, a spool file containing the routine with the annotated errors found is displayed.
The verification relies on the FRM syntax (%IF with %ENDIF, %ELSE with an %IF, %IF with a correct syntax condition, ...), but in no case will it verify the contents of the routines to insert to the corresponding language.
The objective of EZMFI routine to insert before file update and carry out a verification/conversion calculation of the original file field ($$F1) and build the 2 added file fields ($$F2 et $$F3); the calculation needs a number of decimals for the field ($$LD).
EZMFI routine in RPGLE
C*%CM==================================================================
C* Lines automatically inserted by ARCAD-FRM - copyright ARCAD Software
C* Calculate ECART field and file field assignments before file updat
C CALL 'CVZECRFI'
C PARM $$F1 WCVTIN 30 9
C $$F2 PARM $$F2 WCVTAL 30 9
C $$F3 PARM WCVTEC 30 9
C PARM $$LD WCVTDC 2 0
This RPGLE routine can also be a base for the generation of recovery programs.
EZMFI Routine in CBL
*%CM=============================================================
* Lines automatically inserted by ARCAD-FRM - copyright ARCAD SOF
01 WCVT-EURO-GES PIC S9(13)V9(5) COMP-3.
01 WCVT-EURO-ALT PIC S9(13)V9(5) COMP-3.
01 WCVT-EURO-ECART PIC S9(13)V9(5) COMP-3.
01 WCVT-EURO-NBDEC PIC 99 COMP-3.
* Calculate ECART field and file zone assignments before file u
MOVE $$F1 TO WCVT-EURO-GES
MOVE $$F2 TO WCVT-EURO-ALT
MOVE $$LD TO WCVT-EURO-NBDEC
CALL "CVZECRFICB" USING WCVT-EURO-GES WCVT-EURO-ALT
WCVT-EURO-ECART WCVT-EURO-NBDEC
MOVE WCVT-EURO-ALT TO $$F2
MOVE WCVT-EURO-ECART TO $$F3
*%EXIT
The objective of EXAFA routine to insert before screen display to work with an alternating display (either in standard currency, or in alternate currency according to the value of the indicator 57).
The display field is replaced by a new $$F2 field in place of the previous one. A 3-character field is added next to it for informing the user of the currency display. The value of this currency code is not directly in the program; it must be loaded at the beginning of the process. Also, for certain fields, an $$A1 associated field containing the converted value is sometimes routed parallel to the data file until the screen.
The routine to insert is different if you have this associated field (‘$$A1’ <> ‘ ’) or if it doesn’t exist.
EXAFA Routine in RPG
C*%CM=============================================================
C*%CM Systematic addition of retrieval of values to test
C*%IF '$$F3' <> ' '
C*%ONCE SRE
C* Retrieval of values of currency codes for the Euro
C EXSR SREURS
C*%ENDONCE
C SREURS BEGSR
C CALL 'CVXCODES'
C CALL 'CVXCODES'
C PARM WDVGES 3 Stored curr.entered
C PARM WDVGEA 3 " " displ'd
C PARM WDVALS 3 Alt. curr. entered
C PARM WDVALA 3 " "
C PARM WDVALA 3 " " displ'd
C ENDSR
C*%ENDIF
C*%CM=============================================================
C*%CM Case of a known associated field (based on similarity).
C*%IF '$$A1' <> ' '
C* Lines automatically inserted by ARCAD-FRM - copyright ARCAD Sof
C* Assign the field either in stored currency, or in the other!
C *IN57 IFEQ '0' *IN57 OFF:sto.cur
C*%IF '$$F3' <> ' '
C MOVELWDVGEA $$F3 Display curr.code
C*%ENDIF
C CALL 'CVZAFFIC' Alternate display
C $$F1 PARM $$F1 WCVTOU 309 Amount in sto.cur
C $$F2 PARM $$A1 WCVTIN 309 Amount in alt.cur
C PARM $$LD WCVTDC 20 Number of decimal
C ENDIF
C*%ELSE
C*%CM Case of an unknown associated field.
C* Lines automatically inserted by ARCAD-FRM - copyright ARCAD Sof
C* Assign the field either in stored currency, or in the other!
C *IN57 IFEQ '0' *IN57 OFF:sto.cur
C*%IF '$$F3' <> ' '
C MOVELWDVGEA $$F3 Display sto. curr
C Z-ADD$$F1 $$F2
C ELSE
C*%IF '$$F3' <> ' '
C MOVELWDVALA $$F3 Display
C*%ENDIF
C CALL 'CVZAFFIC' Alternat
C $$F1 PARM $$F1 WCVTOU 309 Amount in sto.cur
C $$F2 PARM 0 WCVTIN 309 Amount in alt.cur
C PARM $$LD WCVTDC 20 Number of decimal
C ENDIF
C*%EXIT
C*%ENDIF
The call of the RPG sub-routine by EXSR SREURS is placed between %ONCE SRE and %ENDONCE; it will only be inserted once in the program. It may be necessary to move it (to put at the beginning of the program for example).
However, the contents of the SREURS routine (from BEGSR to ENDSR) will be, like all RPG sub-routines present in the standard routines code, inserted once in the program.
EXAFA Routine in CBL
/*%CM=============================================================
/*%CM Routine:calculate Euro amount before display (with code in
*%CM==============================================================
*%IF $$DT = DSPF
*%OR $$DT = DSPF38
05 Screen indicator for function key Currency Change pressed
05 IN07 PIC 1 INDIC 07.
88 IN07-ON VALUE B"1".
88 IN07-OFF VALUE B"0".
05 Screen indicator for display of message for Currency Change
05 57 OFF --> in stored currency 57 ON --> in alternate currency
05 IN57 PIC 1 INDIC 57.
88 IN57-ON VALUE B"1".
88 IN57-OFF VALUE B"0".
*%ENDIF
01 Currency indicator for amounts
01 WCVT-CHOIX-AFF PIC X.
88 WCVT-CHOIX-AFF-GES VALUE B"0".
88 WCVT-CHOIX-AFF-ALT VALUE B"1".
01 WCVT-EURO-GES PIC S9(13)V9(5) COMP-3.
01 WCVT-EURO-ALT PIC S9(13)V9(5) COMP-3.
01 WCVT-EURO-NBDEC PIC 99 COMP-3.
01 WCVT-DEV-GES-SAI PIC XXX.
01 WCVT-DEV-GES-AFF PIC XXX.
01 WCVT-DEV-ALT-SAI PIC XXX.
01 WCVT-DEV-ALT-AFF PIC XXX.
*%CM Systematic addition of retrieve processing of values to test
*%IF '$$F3' <> ' '
*%ONCE SRE
* Retrieval of values of currency codes for the Euro
CALL "CVXCODES" USING WCVT-DEV-GES-SAI WCVT-DEV-GES-AFF
WCVT-DEV-ALT-SAI WCVT-DEV-ALT-AFF
* Basic : Activate the currency display in stored currency
SET WCVT-CHOIX-AFF-GES TO TRUE
*%IF $$DT = DSPF
*%OR $$DT = DSPF38
MOVE WCVT-CHOIX-AFF TO IN57 OF INDICATOR-AREA
* F7 Change displayed currency (applied after screen read)
IF IN07-ON
IF WCVT-CHOIX-AFF-ALT
SET WCVT-CHOIX-AFF-GES TO TRUE
ELSE
SET WCVT-CHOIX-AFF-ALT TO TRUE
END-IF
MOVE WCVT-CHOIX-AFF TO IN57 OF INDICATOR-AREA
GO TO FinEcrxxx
END-IF
*%ENDIF
*%ENDONCE
*%ENDIF
*%CM=============================================================
*%CM Case of a known associated field (based on similarity).
*%IF '$$A1' <> ' '
* Lines automatically inserted by ARCAD-FRM - copyright ARCAD SOF
* Assign the field either in stored currency, or in the other!
IF WCVT-CHOIX-AFF-GES
*%IF '$$F3' <> ' '
MOVE WCVT-DEV-GES-AFF TO $$F3
*%ENDIF
MOVE $$F1 TO $$F2
ELSE
*%IF '$$F3' <> ' '
MOVE WCVT-DEV-ALT-AFF TO $$F3
*%ENDIF
MOVE $$F1 TO WCVT-EURO-GES
MOVE $$A1 TO WCVT-EURO-ALT
MOVE $$LD TO WCVT-EURO-NBDEC
CALL "CVZAFFICCB" USING WCVT-EURO-GES WCVT-EURO-ALT
WCVT-EURO-NBDEC
MOVE WCVT-EURO-GES TO $$F1
MOVE WCVT-EURO-ALT TO $$F2
END-IF
*%ELSE
The comment lines which must stay as declaratives are preceded by a level N° (05). Without that, they will be inserted into the code (PROCEDURE DIVISION
). However, you must manually replace this 05 by a comment*.
05 Screen Indicator for function key Chng forced currency
05 IN07 PIC1 INDIC 07