Brochure ILE RPG

Transcription

Brochure ILE RPG
1
Brochure
ILE RPG
Chapitre
TABLE DES MATIERES
Objectifs ; introduction.
Pages
3
CHAPITRE I ILE RPG
I.1) Structure du programme
I1
IF.. ELSE.. ENDIF
Structure
SELECT.. WHEN.. OTHER.. ENDSL
DOW LEAVE ITER ENDDO ; DOU
DO
LEAVE ITER ENDDO
EXSR LEAVESR ENDSR
CALLP Sous-Procédures (non utilise gén.).
I.2) Carte F, carte D, Gestion base de données
I2
Carte F, RENAME, SFILE, INFDS
Accès, fichiers,
Carte D et Data Structure, LIKE, OVERLAY
données de
CHAIN, READE, UPDATE, DELETE, CLEAR; *ALL;
travail
%EOF, SETLL
I.3) Instructions de base
EVAL(h)
I3
ADD, SUB, MULT, DIV, +=, -=, *=, /=
Instructions
CLEAR, MOVE, MOVEL, CAT, EVAL
ILE RPG
Tableaux MOVEA T(I) XFOOT SORTA
Tout sur les dates : carte D, ADDDUR, SUBDUR
TEST(DE) test de la date
Tableaux chargés à la compilation, CTDATA
MOVE, MOVEL, TEST(n), *ALL’a’
EVAL alphanumérique, CAT
BIF : %SUBST %LEN %TRIM
API QCLSCAN CALLP.
4
5
7
9
10
11
12
13
15
18
19
21
22
24
26
27
28
29
30
31
CHAPITRE II Personnaliser
(page
suivante)
1
2
Chapitre
Pages
TABLE DES MATIERES
CHAPITRE II Personnaliser
II.1) Debogue
II.2) Contrôle
II.3) Préaffichage
Sous-programmes
II.4) Finitions
II.5) Sous-fichier
II.6) Edition
II.6) Modif.
COLHDG
Comment deboguer un programme ILE RPG ?
Comment ajouter un contrôle manuel dans une fiche FCH ?
Comment préafficher un champ E/S en création fiche FCH ?
Comment afficher les sous-programmes d’un modèle ?
Comment visualiser ou effacer une finition générée ?
Comment mixer finition générée et modification manuelle ?
Comment charger le sous-fichier en total ?
Comment forcer le chargement du sous-fichier ?
Comment sont gérées les touches de fonction ?
Comment est structuré un programme d’édition ?
Comment paramétrer l’entête standard pour une société ?
Comment s’effectuent les sauts de page à rupture et/ou à
l’overflow ?
Comment paramétrer l’overflow ?
Comment modifier le COLHDG d’un PF et LF associés sans
recompilation ?
33
35
39
41
43
44
45
47
47
49
50
2
3
Objectifs et Introduction
Introduction :
En informatique de gestion, l’expérience prouve qu’ il est possible d’écrire
un programme en n’utilisant qu’une trentaine d’instructions de base environ.
Les instructions peuvent de subdiviser en trois parties :
1. les instructions de structurations : le sous-programme, la structure
conditionnelle et la structure répétitive.
2. les instructions de gestion de la base de données avec l’accès en
lecture, l’écriture, la mise à jour…
3. les instructions de manipulation des données : les tables, les calculs,
le peuplement des zones de travail…
Nos générateurs génèrent des programmes complets à partir de modèles
comme les programmes transactionnels, les éditions et les critères de
sélection. Les développeurs doivent en connaître la structure globale afin de
pouvoir personnaliser en fonction des particularités de chaque entreprise.
Objectifs :
A l’issue de cette formation ILE RPG pour nos générateurs, les stagiaires
pourront réaliser des applications de gestion en ILE RPG clé en main,
plusieurs fois plus vite, toutes les applications étant standardisées donc de
qualité constante.
Afin de garder un contrôle intellectuel sur les programmes, nous n’utilisons
volontairement qu’un nombre limité d’instructions ILE RPG. Il existe
aujourd’hui des centaines d’instructions sophistiquées ILE RPG. Le
stagiaire pourra s’y reporter par la suite à mesure des besoins spécifiques de
son entreprise en consultant les brochures IBM.
Nos générateurs s’adressant aux sites qui ont souvent un fort existant en
RPGII et RPGIII, aussi nous mettons parfois en regard les instructions
RPGIII afin de relever les différences et d’y faciliter l’apprentissage. Il ne
faut pas oublier non plus que le ILE RPG accepte également 80% de la
syntaxe RPGIII.
Première remarque : un membre source RPGIII se distingue d’un membre
source ILE RPG par le type du membre source :
RPGLE pour le ILE RPG.
RPG pour le RPGIII
La syntaxe est contrôlée lors de la saisie en fonction du type du membre
source.
3
4
CHAPITRE I ILE RPG
I.1) Structure
En RPGIII, la syntaxe utilise le facteur1 et le facteur2. En ILE RPG, le
facteur2 étendu permet d’exprimer la condition de façon très naturelle.
Rappel RPGIII :
IF
……
ELSE
……
ENDIF
CL0N01N02N03Factor1+++OpcdeFactor2+++Result
C
Z1
IFEQ 'A'
C
Z2
ANDNE'B'
C
*IN12
ANDEQ'1'
C
ZA
IFEQ ‘B’
C
ZA
OREQ ‘C’
C*......
C
ELSE
C*......
C
ENDIF
C
ENDIF
Voici les mêmes instructions en RPGIV :
CL0N01Factor1+++++++Opcode&ExtFactor2++++++++
C
IF
Z1 = 'A' AND Z2 <> 'B'
C
AND *IN12 = *ON
C
AND (ZA = ‘B’ OR ZA = ‘C’)
*.......
C
ELSE
*.......
C
ENDIF
Remarques :
Le facteur2, qui exprime la condition du IF, est libre. Il peut être
complété sur plusieurs lignes.
Les conditions OR doivent souvent être mis entre parenthèses lorsqu’il y
a également des AND car le AND est prioritaire sur le OR. Exemple :
…AND (ZA = ‘B’ OR ZA = ‘D’)
L’expression s’écrit exactement comme on l’écrirait au stylo sur une
feuille de papier libre. La syntaxe est donc naturelle.
Comme en RPGIII et contrairement au langage CL, il n’y a qu’un seul
ENDIF avec ou sans le ELSE. Cette structure traite donc la condition
avec la condition inverse si le ELSE est présent.
Notez : *IN12 est l’indicateur 12 qui servira par exemple dans un DSPF
au niveau zone pour activer un attribut d’affichage. *IN12 = ‘1’ est
équivalent à *IN12 = *ON ou simplement *IN12. L’inverse étant *IN12
= ‘0’ ou *IN12 = OFF ou NOT(*IN12). *ON et *OFF sont des mots clés
réservés équivalents à ‘1’ et ‘0’. *ON et *OFF peuvent s’employer avec
toute variable de travail alphanumérique de 1 de long.
4
5
CHAPITRE I ILE RPG
I.1) structure
SELECT
WHEN
….
WHEN
….
OTHER
….
ENDSL
WHEN est une instruction de structuration qu’il faut absolument maîtriser
en ILE RPG. (en fait cette instruction est puissante, lisible et simple).
WHEN peut remplacer simplement toutes les imbrications les plus
complexes qui nécessiteraient des if then else imbriqués les uns dans les
autres.
Par exemple, l’algorithme suivant, fonction étant la touche de fonction :
Si fonction = F06
| aller sous-programme SRWrkRcd
Sinon
| Si fonction = F04
| | aller sous-programme SRF04
| Sinon
| | Si fonction = F12
| | | ………..
etc…..
Peut être avantageusement représenté en ILE RPG avec la structure
WHEN (remplace également ELSEIF):
C*
C
C*
C*
C
C
C*
C*
C
C
C*
C
C
C*
C*
C
C
C*
C*
C
C
C
C*
C*
C
C
C
C*
C
SELECT
F06 créer
F03
F04
F12
:
WHEN
EXSR
KeyPress = F06 AND *IN01
SRWrkRcd
:
WHEN
………..
KeyPress = F03
WHEN
EXSR
KeyPress = F04
SRF04
WHEN
KeyPress = F12
:
:
……….
ROLLUP
:
WHEN
KeyPress = RollUp
……….
OTHER
Fonction invalide :
EVAL
WMsgId = 'FNC0001'
EVAL
WMsgF = WMsgFSys
CALL
'WSNDMSG'
WSndMsg
ENDSL
5
6
CHAPITRE I ILE RPG
I.1) structure
(suite)
SELECT
WHEN
….
WHEN
….
OTHER
….
ENDSL
Dans cet exemple, lorsqu’une condition est remplie, par exemple si
KeyPress = F04, les instructions correspondantes sont exécutées et
l’instruction suivante sera inconditionnellement celle qui suit le ENDSL,
même si la valeur de KeyPress a évolué lors de l’exécution des instructions
du sous-programme SRF04 et a pris entre temps la valeur F12.
Nous remarquons que l’emplacement des WHEN est très important car la
première condition remplie sera exécutée et ensuite le traitement se
poursuivra systématiquement après l’instruction ENDSL.
Il faut donc construire une hiérarchie de WHEN…
De ce fait, les conditions des WHEN qui suivent peuvent parfois être
singulièrement simplifiées relativement aux conditions qui précèdent. Il faut
considérer que la structure agit comme un filtre du haut vers le bas et
construire la hiérarchie en conséquence.
Si aucune condition est remplie et si OTHER est présent, les instructions qui
suivent OTHER seront exécutées.
Dans notre exemple, nous aurons alors un message d’erreur indiquant que la
valeur de la fonction KeyPress est invalide.
Nous verrons dans d’autres chapitres le traitement des erreurs, l’instruction
EVAL ainsi que la variable KeyPress dans les programmes transactionnels.
Notez que la condition peut être écrite au besoin sur plusieurs lignes.
Rappel de l’instruction WHEN en RPGIII :
C
C
C
C*......
C
C*......
C
C*......
C
C*......
C
Z1
Z2
SELEC
WHEQ 'A'
ANDEQ'B'
Z1
WHGE 'C'
*IN12
WHEQ '1'
OTHER
ENDSL
Equivalent en ILE RPG :
C*
C
C
C*……………..
C
C*……………….
C
C
C
C*…………
C
SELECT
WHEN
Z1 = ‘A’ AND Z2 = ‘B’
WHEN
Z1 >= ‘C’
WHEN
………..
OTHER
*IN12
ENDSL
Nous voyons bien que le ILE RPG est d’une syntaxe très proche d’ un
algorithme qui serait écrit à la main sur une feuille de papier, ce qui facilite
l’apprentissage et la lecture. Notez qu’il est plus naturel de représenter des
conditions complexes avec des AND et des OR entre parenthèses.
Notez que SELECT……..ENDSL qui délimitent la structure WHEN sont
obligatoires (un oubli sera signalé de toute manière lors de la compilation).
6
7
CHAPITRE I ILE RPG
I.1) Structure
répétitive
DOW
……
LEAVE
……
ITER
……
ENDDO
L’instruction de structuration DOW répète tant qu’une condition est
remplie.
Lorsqu’une instruction LEAVE est rencontrée, l’instruction suivante est
celle qui suit le ENDDO.
Lorsqu’une instruction ITER est rencontrée, l’instruction suivante est le
ENDDO lui-même afin d’effectuer une autre itération tant que la condition
est remplie.
LEAVE et ITER peuvent simplifier grandement l’algorithme à l’intérieur de
la boucle DOW. Ces 2 instructions n’ont pas les inconvénients de sauts
inconditionnels dont ne sait pas, à première lecture, où sont placées les
étiquettes de destination. LEAVE et ITER font donc partie intégrante de la
structure répétitive elle-même.
DOW est très utilisé en informatique de gestion associé à la lecture des
enregistrements des fichiers.
Lire le premier enregistrement
Tant que non fin de fichier
| ……….
| lire l’enregistrement suivant
Fin Tant que
C
C
C*………………………………….
C
C
C
C*……………………………………
C
C
READ
DOW
EXCLIENTR
NOT %EOF(EXCLIENTL4)
IF
LEAVE
ENDIF
ERREUR = *ON
READ
ENDDO
EXCLIENTR
Dans cet exemple, le fichier EXCLIENTL4 est lu tant que non fin de fichier.
ERREUR est une donnée de travail alphanumérique de 1 de long définie par
le développeur et renseignée par le programme.
La syntaxe suivante qui utilise l’indicateur de fin de fichier IN60 est
strictement équivalente. Sont équivalents NOT(*IN60) ou *IN60 = ‘0’ :
C
C
C*………………………………….
C
C
C
C*……………………………………
C
C
C
READ
DOW
EXCLIENTR
*IN60 = *OFF
IF
LEAVE
ENDIF
ERREUR = ‘1’
READ
ENDDO
EXCLIENTR
60
60
7
8
CHAPITRE I ILE RPG
I.1) Structure
répétitive
(suite)
DOW
……
LEAVE
……
ITER
……
ENDDO
I.1) Structure
répétitive
DOU
……
LEAVE
……
ITER
……
ENDDO
Exemple en RPGIII :
CL0N01N02N03Factor1+++OpcdeFactor2+++Result
C
Z1
DOWEQ'A'
C
Z2
ANDNE'B'
C
*IN12
ANDEQ'1'
C*......
C
ENDDO
Equivalent en ILE RPG :
CL0N01Factor1+++++++Opcode&ExtExtended-factor2++++
C
DOW
Z1 = 'A' AND
C
Z2 <> 'B' AND *IN12
*.......
C
ENDDO
La structure DOU est un standard incontournable des langages actuels.
Règle de la structure DOU :
-) Un 1er passage dans la boucle au minimum est effectué
inconditionnellement, sans tester la condition de la répétitive.
-) Après le 1er passage, les passages suivants sont effectués jusqu’à ce que
la condition soit remplie. Autrement dit, c’est la condition inverse du DOW.
Exemple en RPGIII :
CL0N01N02N03Factor1+++OpcdeFactor2+++Result
C
Z1
DOUNE'A'
C
Z2
ANDEQ'B'
C
*IN12
ANDEQ'0'
C*......
C
ENDDO
Equivalent en ILE RPG :
CL0N01Factor1+++++++Opcode&ExtExtended-factor2++++
C
DOU
Z1 <> 'A' AND
C
Z2 = 'B' AND
C
*IN12 = *OFF
*.......
C
ENDDO
Remarque : il est préférable de connaître également la syntaxe RPGIII, car
elle est admise donc parfois utilisée dans les programmes en ILE RPG.
Ainsi, la commande IBM CVTRPGSRC permet de convertir un membre
source RPGIII en ILE RPG en gardant beaucoup de la syntaxe RPGIII.
8
9
CHAPITRE I ILE RPG
I.1) Structure La structure d’incrémentation DO permet d’exécuter une série d’instructions
incrémentation un nombre connu de fois. Notons qu’avec DO, ITER est très souvent utilisé.
Cette structure se rencontre souvent dans les programmes ILE RPG pour
gérer les tables. Nous verrons la syntaxe des tables ultérieurement. Ainsi :
DO n
CL0N01Factor1+++++++Opcode&ExtExtended-factor2++++
……
C
EVAL
I = 0
LEAVE
C
DO
10
C
EVAL
I = I + 1
……
C*
...........
ITER
C
ENDDO
……
ENDDO
Est strictement équivalent à :
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result
C
DO
10
I
C* ...........
C
ENDDO
Syntaxe :
facteur 2 : incrémentation
Résultat : la variable de travail numérique I incrémentée.
Eventuellement en facteur 1 : à partir de la valeur numérique. La valeur 1
est prise par défaut. Ici de 1 à 10 en incrémentant la variable I. Dans la
pratique, la variable incrémentée sert souvent d’indice de table comme nous
le verrons plus loin.
Débat :
Que penser de cette syntaxe ? Est-elle lisible ou non lisible ? Nous pensons
qu’elle peut être très valable pour simplifier les cas les plus complexes.
DO *HIVAL
ENDDO
C
C*........
C
C
C
C*
C
C
C*
C
C*…………………
C
C*.......
C
DO
*HIVAL
SELECT
WHEN
LEAVE
*IN03 = *ON
WHEN
LEAVE
ZONEA = ZONEB
OTHER
ENDSL
ENDDO
Cette répétitive boucle à l’infini par définition même (*hival). Cette
structure peut être utilisée avantageusement lorsque des conditions sont
beaucoup trop complexes pour être cumulées dans un DOW par exemple. Il
est plus simple dans ce cas de définir les les conditions de sortie de boucle
avec LEAVE dans une structure WHEN. Si les conditions internes sont
bien décrites la condition devient plus lisible. Pour utiliser cette structure, il
faut admettre conceptuellement que LEAVE fait partie intégrante de la
répétitive.
9
10
CHAPITRE I ILE RPG
I.1) Structure
Sous-programme
EXSR Nom
Nom BEGSR
……
LEAVESR
……
ENDSR
C*
C*
C
……………….
Chargement du sous-fichier page suivante :
EXSR
SRCharge
C
SRCharge
BEGSR
C
CLEAR
WCurLinWrt
C*
C*
Ligne courante < nbre de lignes dans une page écran
C
DOW
NOT %EOF(EXCLIENTL1)
C
AND WCurLinWrt < WSflPag
C*
C* Lectures détail ET préaffichages éventuels.
C
EXSR
SRDtlRead
C
ADD
1
RRN
C
ADD
1
WCurLinWrt
C
CLEAR
WOpt
C
MOVE
*ZERO
Z15
C
MOVEA
Z15
*IN(11)
C
WRITE
WSFL
C*
C* EXCLIENTL1 Client par Pays
C
EXCLIEN001
READE(n) EXCLIENTR
C*
C
ENDDO
C
C
ENDSR
Avantages de l’utilisation des sous-programmes :
-) grande simplicité.
-) isoler la structure d’un programme afin d’en avoir une vue d’ensemble
sur une seule page.
-) ranger les instructions correspondant à une fonction bien définie dans
des tiroirs logiques. Ici, les instructions du chargement du sous-fichier.
Le générateur et le développeur pourront ainsi retrouver et personnaliser
facilement les instructions de ce sous-programme. Par exemple : ajouter
un calcul niveau ligne du sous-fichier dans une zone de travail par
exemple dans le sous-programme SRDtlRead avant l’instruction WRITE
WSFL d’une ligne de sous-fichier.
-) LEAVESR permet de terminer directement le sous-programme afin de
simplifier l’algorithme. Notez que le saut inconditionnel est à bannir de
manière générale car le lecteur ne sait pas à la 1ère lecture où l’étiquette
est placée. LEAVESR ne présente pas cet inconvénient est donc admis.
Inconvénient du sous-programme :
-) pas de variable locale au sous-programme.
-) pas de possibilité d’appel depuis un programme externe.
La sous-procédure devrait en principe cumuler les avantages des sousprogrammes sans les inconvénients. Dans un but de facilité
d’apprentissage d’un ILE RPG simple, assez proche du RPGIII, nos
générateurs n’utilisent pas de sous-procédures sauf dans un cas ou deux
particulier.
10
11
I.1) Structure
Sous-procédure
(Non utilisé)
CHAPITRE I ILE RPG
Dans un souci de facilité d’apprentissage, d’un ILE RPG qui ne serait
pas trop éloigné du RPGIII, nos générateurs ne mettent pas en œuvre les
sous-procédures. Cependant, voici brièvement un exemple :
PR
……
CALLP
…….
PR
D
S
i
65535A
CONST OPTIONS(*VARSIZE)
65535A
OPTIONS(*VARSIZE)
10I 0 CONST
5
……………..……….
callp
CvtCaseEx1(szInput:szOutput:%size(szInput))
………….
B
PI
E
D CvtCaseEx1
D InString
D OutString
D nLen
P CvtCaseEx1
D CvtCaseEx1
D InString
D OutString
D nLen
B
PI
D nDur
D i
S
S
C
P CvtCaseEx1
E
Export
65535A
CONST OPTIONS(*VARSIZE)
65535A
OPTIONS(*VARSIZE)
10I 0 CONST
10I 0
10 0
……….
return
-) La sous-procédure doit être déclarée en début de programme en carte
D PR avec les paramètres.
-) Les paramètres de la sous-procédure doivent être décrits une seconde
fois à la fin du programme B PI…..E
-) L’instruction CALLP du corps de programme qui appelle la sousprocédure doit passer les paramètres décrits en PR, PI.
CALLP NomSousProc(Parm1 :Parm2 :Parm3)
-) Notons que les variables nDur et i sont des variables locales connues
uniquement par la sous-procédure CvtCaseEx1. Ces variables locales
peuvent tout à fait avoir un nom identique et des définitions différentes
au niveau global, dans ce cas c’est la variable locale de même nom qui
est prise à l’intérieur de la sous-procédure. Dans cet exemple, la variable
i est connue en local en tant que variable numérique de 10 de long
uniquement dans la sous-procédure CvtCaseEx1 et ailleurs en global
comme étant une variable alphanumérique de 5 de long.
Inconvénient :
-) lourdeur de la syntaxe (déclarer les parms deux fois PR et PI).
-) pas de possibilité de déclarer des fichiers en local alors que les
données des fichiers représentent 90 à 100% des données en
informatique de gestion.
Avantage :
-) variables de travail locales.
-) possibilité d’appel d’une sous-procédure depuis un programme
externe.
Conclusion :
-) indispensable dès que l’on fait de l’informatique scientifique
complexe où les variables de travail sont très nombreuses car on évite
ainsi des bogues vicieux en environnement de production.
11
12
I.2) Carte F
Carte D
Base de données
CHAPITRE I ILE RPG
Les cartes F sont décrites comme en RPGIII sauf pour les extensions.
Dans cet exemple, le fichier à description :
F* Client Exemples Fast
FEXCLIENT UF A E
K DISK
Update avec Ajout Externe par Key (clés)
Carte F
Pour renommer un nom de format de fichier en carte F:
FDBLFILE2
F
IF
E
K DISK
RENAME(DBLFILER:DBLFILE2R)
RENAME
Dans cet exemple, le format d’origine DBLFILER est renommé dans le
programme DBLFILE2R. Mémo : dans le même sens qu’un OVRDBF.
F*
Ecran dspf :
FABDSL2W
CF
E
F
F
SFILE
INFDS
WORKSTN
SFILE(WSFL:RRN)
INFDS(DS_Display)
SFILE : Pour le format du sous-fichier WSFL, la variable rang est RRN.
Nous verrons que le sous-fichier est un fichier relatif. Typiquement, le
programme doit incrémenter RRN, écrire les lignes du sous-fichier une à
une, puis afficher la page par une écriture globale du format de contrôle
associé. (n enregistrements du format WSFL)
INFDS : la data structure de nom DS_Display va contenir des
informations relative à l’écran. Nous verrons en détail la valeur de la
variable KeyPress dans les transactionnels afin de récupérer la touche de
fonction activée par l’utilisateur.
12
13
CHAPITRE I ILE RPG
I.2) Carte F
Carte D
Single
DVARETD1
DVARPAK1
DVARALPHA
S
S
S
7S 3
6 2
60
S=Zone autonome ou Single.
La variable VARETD1 est numérique étendue (S) de 7 dont 3
décimales
La variable VARPAK1 est numérique packé de 6 dont 2 décimales.
Packé par défaut si numérique (nombre de décimale <> blanc)
La variable VARALPHA est alphanumérique. De 60 caractères
(nombre de décimale = blanc)
Dans la pratique, pour déclarer une donnée de travail, il suffit de
recopier une carte D pour avoir le colonage et créer ainsi une nouvelle
carte D.
Rappel en RPGIII déclarer une donnée de travail VARDEC de longueur
7 dont 3 décimales en carte I :
I
LIKE
1
7 3VARDEC
===============================================
DNOFAM
………………………………….
DZFAM
S
20
S
LIKE(NOFAM)
Ici la zone autonome ZFAM est de même type et de même longueur que
NOFAM soit 20 de long alphanumérique. Note : il est également
possible de faire référence à une zone de fichier.
Avantage : En cas de changement de longueur d’une zone, il suffit de
recompiler le programme pour modifier automatiquement la longueur
les données de travail qui font référence à cette zone (qui peut provenir
d’un fichier).
Rappel en RPGIII nous avons l’équivalent en carte C mais NOFAM doit
être une zone de fichier.
C
Constante
*LIKE
DEFN NOFAM
ZFAM
Nous reviendrons aux carte D pour les tables.
==========================================
DVRAI
C
‘Y’
Vrai est une constante qui prend la valeur ‘Y’. Nous pourrons avoir dans
le programme le test suivant :
C
IF
TEST = VRAI
La condition est remplie si TEST a la valeur ‘Y’.
13
14
CHAPITRE I ILE RPG
I.2) Carte F
Carte D
DS
DSTRUCDS
D DSZONE1
D DSZONE2
D DSZONE3
DS
256
LIKE(C1PAYS)
LIKE(C1RAISON)
8
Le champ STRUCDS est une Data Structure alphanumérique de 256 de
long.
DSZONE1, DSZONE2 et DSZONE3 sont des sous-zone (car il n’y a
pas S pour zone autonome Single mais blanc)
Les sous-zones sont concaténées dans STRUCDS.
Exemple : la sous-zone DSZONE2 débute en position 6 si DSZONE1
fait 5 de long.
Donc les longueurs et les positions sont déduites automatiquement en
fonction des longueurs des sous-zones précédentes.
Par contre DSZONE3 est une donnée alphanum de 8 de long. La
position de début sera déduite automatiquement en fonction des
longueurs de C1PAYS et C1RAISON dans le fichier.
Il suffit de recompiler le programme si C1PAYS ou C1RAISON
venaient à changer de longueur.
OVERLAY
D
DDSNAMVAR
D
NAMVAR
D
NAMVAR5
DS
20
10
5
OVERLAY(DSNAMVAR:10)
OVERLAY(DSNAMVAR:10)
La Data Structure est composée de :
Une zone Alphanum. DSNAMVAR de 20 de long
Une s/zone Alphanum. NAMVAR
en position 10 de DSNAMVAR
10 de long
Une s/zone Alphanum NAMVAR5 en position 10 de DSNAMVAR 5
de long
Le mot clé OVERLAY permet des recouvrements de zones.
OVERLAY(name[ :pos])
:pos est la position de début dans la zone (par défaut 1)
Remarque : ici la data structure n’a pas de nom. Nous reviendrons aux
data structures lorsque nous traiterons les tableaux.
14
15
CHAPITRE I ILE RPG
I.2) Accès
bases de
données
CHAIN
C*
C* Accès : CLIPAYS Pays
C
CLIPAYS001
KLIST
C*
Code Pays
C
KFLD
C3CODPAYS
…………
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C*
C
MOVEL(p) C1PAYS
C3CODPAYS
C
*NOKEY
CLEAR
*ALL
CLIPAYSR
C
CLIPAYS001
CHAIN
CLIPAYSR
96
-) La KLIST CLIPAYS001 est une définition de clé(s) du fichier CLIPAYS.
Avec nos générateurs, le nom de KLIST est composé du nom du fichier suivi
du nombre de clés jusqu’à 99 maxi.
-) C’est le nom du format de fichier qui est utilisé pour les opérations bases de
données, ici CLIPAYSR.
-) MOVEL(p) permet d’affecter le contenu de la clé étrangère dans la clé pays
afin d’y accéder. (p) met à blanc la zone résultat. Ici MOVEL(p) est strictement
équivalent à EVAL, sauf pour le cas où C3CODPAYS serait alphanumérique et
C1PAYS numérique. En effet, EVAL ne peut être une instruction valide que
pour des données de même nature (tout alpahanum. ou tout num.)
C
*NOKEY
CLEAR
*ALL
CLIPAYSR
CLEAR est une instruction très puissante, connue depuis le RPGIII, qui
initialise tous les champs du format CLIPAYSR à zéro et à blanc avant la
lecture, sauf les clés *NOKEY.
Ainsi, lors de la lecture en boucle et de l’affichage dans les lignes d’un sousfichier ou d’une édition, si l’accès échoue, le programme ne récupère pas une
valeur déphasée de l’avant dernière lecture.
CHAIN(n)
C
PROSPEC001
CHAIN(n)
PROSPECTR
60
Si le fichier est déclaré en mise à jour en carte F, CHAIN(n) ne bloque pas
l’enregistrement en lecture. Notons qu’un fichier peut être ouvert en partagé en
dehors du programme en mise à jour avec une instruction CL :
OVRDBF SHARE(*YES) suivie d’un OPEN. Dans ce cas, le programme ne
tient aucun compte de la déclaration Input du fichier en carte F, puisque
l’ouverture du fichier est partagée par plusieurs programmes ; dans ce cas une
lecture bloquera l’enregistrement sauf si CHAIN(n).
15
16
CHAPITRE I ILE RPG
I.2) Accès
bases de
données
%EOF
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
PROSPEC001
CHAIN(n) PROSPECTR
60
C
IF
NOT %EOF(PROSPECTL5)
……………
C
ENDIF
NOT %EOF(PROSPECTL5) indique SI NON fin de fichier PROSPECTL5. Il
existe une autre syntaxe équivalente plus courte et plus classique :
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
PROSPEC001
CHAIN(n) PROSPECTR
60
C
IF
*IN60 = *OFF
……………
C
ENDIF
Ou encore IF NOT(*IN60).
Remarque: dans les transactionnels des générateurs avec sous-fichiers,
l’indicateur *IN60 conditionne également le mot clé DSPF SFLEND qui
affiche ou non le « + » ou « à suivre » en bas du sous-fichier. Cet indicateur 60
doit donc être coordonné avec l’indicateur de lecture de fin de fichier.
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
READ(n)
PROSPECTR
60
C
DOW
*IN60 = *OFF
……………
C
READ(n)
PROSPECTR
60
C
ENDDO
READ effectue une lecture suivante au fichier PROSPECTL5, format
PROSPECTR dans l’ordre des clés.
READ
READE
STELL
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
PROSPEC001
KLIST
C*
Code Pays
C
KFLD
C1PAYS
……………..
C
EVAL
C1PAYS = ‘FRA’
C
PROSPEC001
SETLL
PROSPECTR
C
PROSPEC001
READE(n) PROSPECTR
60
C
DOW
NOT %EOF(PROSPECTL5)
……………
C
PROSPEC001
READE(n) PROSPECTR
60
C
ENDDO
READE effectue la lecture suivante du groupe dont les clés sont définies dans
la KLIST PROSPEC001
SETLL effectue un positionnement du curseur sur le premier élément du
groupe ‘FRA’ d’enregistrements.
IMPORTANT : notez la structure :
1ère lecture avant la répétitive DOW
Lecture suivante avant le ENDDO
Cette structure s’appelle « lecture en tête ». Elle est utilisée partout dans les
programmes générés. La lecture avant le ENDDO permet de détecter la fin de
fichier afin de sortir de la boucle. Si le fichier READ ou le groupe
d’enregistrements du fichier READE est vide, la sortie de boucle est
immédiate.
16
17
CHAPITRE I ILE RPG
I.2) Accès
bases de
données
CHAIN
DOW
….
READE
ENDDO
READP
READPE
C
C
PROSPEC001
C
……………
C
PROSPEC001
C
EVAL
CHAIN(n)
DOW
C1PAYS = ‘FRA’
PROSPECTR
NOT %EOF(PROSPECTL5)
READE(n)
ENDDO
PROSPECTR
60
60
L’instruction CHAIN sur clé partielle majeure PAYS est équivalente à un
SETLL+READE de l’exemple plus haut.
Car l’instruction CHAIN sur clé partielle effectue implicitement les
opérations suivantes :
-) SETLL positionnement sur le premier enregistrement du groupe
-) READE lecture du premier enregistrement du groupe
READP lecture précédente. L’indicateur indique alors le début de fichier
(et non la fin de fichier).
READPE lecture précédente du groupe (clés majeures définies dans la
KLIST comme READE). L’indicateur indique le début du groupe.
REMARQUE : READP est le pendant de READ avec lecture arrière
READPE est le pendant de READE avec lecture arrière
……….. MOVE, EVAL etc… des champs de l’enregistrement à créer
WRITE
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLo
C
WRITE
PROSPECTR
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLo
C
PROSPEC001
CHAIN
PROSPECTR
60
C
IF
NOT(*IN60)
UPDATE
……….. MOVE, EVAL etc… des champs de l’enregistrement à modifier
C
C
UPDATE
ENDIF
PROSPECTR
NOTE: le CHAIN doit être sans (n) afin de locker l’enregistrement avant
UPDATE
L’enregistrement doit être trouvé pour que la mise à jour puisse s’effectuer
C
IF
NOT(*IN60)
IF
%FOUND(PROSPECTL5)
Est équivalent à
C
DELETE
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLo
C
PROSPEC001
CHAIN
PROSPECTR
60
C
IF
%FOUND(PROSPECTL5)
C
DELETE
PROSPECTR
C
ENDIF
NOTE: le CHAIN doit être sans (n) afin de locker l’enregistrement avant
DELETE
L’enregistrement doit être trouvé pour que l’annulation puisse s’effectuer
C
IF
NOT(*IN60)
IF
%FOUND(PROSPECTL5)
Est équivalent à
C
17
18
I.3) Instructions
de base
EVAL
CHAPITRE I ILE RPG
L’instruction EVAL est polymorphe en ILE RPG. Autrement dit, c’est
le contexte qui indique l’action de cette instruction. En effet, si tous les
données sont alphanumériques : une concaténation est effectuée ; si
toutes les données sont numériques : un calcul est effectué. Il n’est donc
pas possible de mixer des données numériques et alphanumériques avec
EVAL (contrairement à MOVE ou MOVEL).
EVAL calculs :
Soit a programmer la formule suivante en ILE RPG et en RPGIII :
TotalTTC = TotalHT + (TotalHT * Taux / 100)
En ILE RPG nous aurons par exemple:
EVAL(h) calculs
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
EVAL(H)
TOTTTC = TOTHT + (TOTHT * TAUX / 100)
Remarques :
-) L’opération peut se continuer sur plusieurs lignes au besoin.
-) EVAL(h) TOTTTC arrondi selon la règle du 5 Half.
Nous constatons qu’il n’y a aucune différence de syntaxe entre
l’opération formulée manuellement et celle codée en ILE RPG. D’où
une facilité de lecture du code et d’apprentissage.
-) Important : avec EVAL la donnée résultat est toujours remise à zéro
avant l’opération effective.
Voici maintenant la même opération en RPGIII. Notons que toutes les
opérations MULT, DIV, ADD, SUB, Z-ADD existent toujours en ILE
RPG et il convient donc de les connaître :
CL0N01N02N03Factor1+++OpcdeFactor2+++Result
C
*LIKE
DEFN TOTTTC
ZTTC
C
TOTHT
MULT TAUX
ZTTC
C
ZTTC
DIV 100
ZTTC
C
TOTHT
ADD ZTTC
TOTTTC
Notons que le résultat final risque de ne pas être tout à fait le même en
RPGIII à cause du problème des arrondis intermédiaires.
18
19
I.3) Instructions
de base
ADD
CHAPITRE I ILE RPG
Les instructions ADD, SUB, MULT, DIV et Z-ADD sont toujours très
utilisées en ILE RPG dans la pratique. ADD permet d’effectuer un
cumul et Z-ADD une mise à zéro préalable avant une addition. Voici
quelques exemples avec l’équivalent EVAL :
RPGIII ou ILE RPG
CL0N01N02N03Factor1+++OpcdeFactor2+++Result
C
ADD 1
COMPTEUR
OU :
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
EVAL
COMPTEUR = COMPTEUR + 1
OU :
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
EVAL
COMPTEUR += 1
Note : Dans ce cas, la valeur initiale de COMPTEUR est cumulée de +1.
De la même manière :
SUB
CL0N01N02N03Factor1+++OpcdeFactor2+++Result
C
SUB 1
COMPTEUR
OU :
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
EVAL
COMPTEUR = COMPTEUR - 1
OU :
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
EVAL
COMPTEUR -= 1
Multiplication :
MULT
CL0N01N02N03Factor1+++OpcdeFactor2+++Result
C
MULT 2
ZONE
OU :
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
MULT
ZONE = ZONE * 2
OU :
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
EVAL
ZONE *= 2
Division :
DIV
CL0N01N02N03Factor1+++OpcdeFactor2+++Result
C
DIV 2
ZONE
OU :
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
EVAL
ZONE = ZONE / 2
OU :
CL0N01Factor1++Opcode&ExtExtended-factor2++++++++++++++++
C
EVAL
ZONE /= 2
De la même manière il existe également **=
19
20
I.3) Instructions
de base
DIV
MVR
CHAPITRE I ILE RPG
MVR permet de récupérer le reste d’une division en RPGIII ou ILE
RPG. Ici, REMAINDER contiendra le reste de la division ou zéro si
ZONE est divisible par 3.
C
C
DIV
MVR
3
ZONE
REMAIDER
Note : l’instruction MVR doit suivre immédiatement l’instruction DIV.
Voici maintenant comment tester la numéricité d’une zone
alphanumérique RPGIII ou ILE RPG :
TESTN
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
TESTN
ZONEAL
97
C N97
MOVE
*ZEROS
ZONEAL
ZONEAL est un champ alphanumérique. Si ZONEAL contient que des
caractères numériques de 0 à 9, l’indicateur 97 sera mis à *ON. Si
ZONEAL ne contient pas que du numérique, l’instruction suivante
MOVE *ZEROS remplit ZONEAL avec des zéros.
Note : serait équivalent la syntaxe suivante :
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
TESTN
ZONEAL
97
C
IF
NOT(*IN97)
C
EVAL
ZONEAL = *ZEROS
C
ENDIF
Remarque : *ZERO peut être employé également avec une variable
numérique. Dans ce cas si ZONENUM est numérique :
Z-ADD *ZERO
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
Z-ADD
*ZEROS
ZONENUM
Equivalent à:
C
EVAL
ZONENUM = *ZEROS
Equivalent à :
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
CLEAR
ZONENUM
20
21
CHAPITRE I ILE RPG
I.3)
Instructions de CLEAR est une instruction polymorphe qui met à zéro une donnée
numérique et à blanc une donnée alphanumérique. CLEAR est également
base
capable de mettre à blanc et à zéro une structure de données. Voici quelques
exemples :
CLEAR
DSTRUCDS
D DSZONE1
D DSZONE2
D DSZONE3
DS
256
LIKE(C1PAYS)
LIKE(C1RAISON)
8
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
CLEAR
STRUCDS
Toutes les sous-zones de la data structure STRUCDS seront mises à blanc
ou à zéro selon qu’elles sont alphanumériques ou numériques.
C
C
*NOKEY
CLIPAYS001
CLEAR
CHAIN
*ALL
CLIPAYSR
CLIPAYSR
96
Dans cet autre exemple, toutes les données du format de fichier CLIPAYSR,
sauf les clés, seront remis à blanc ou à zéro avant la lecture avec les
avantages suivant :
-) on ne récupère pas une valeur d’une lecture précédente si la lecture
échoue.
-) en maintenance, un champ supplémentaire qui sera ajouté sera remis à
blanc ou à zéro automatiquement après recompilation du programme.
De la même manière, il est possible de mettre à blanc ou à zéro tous les
postes d’un tableau comme nous verrons plus loin.
21
22
CHAPITRE I ILE RPG
I.3)
Instructions La déclaration d’un tableau diffère du RPGIII car les cartes E ont disparu.
Ainsi, pour déclarer un tableau TZ10 avec 20 postes de 10 de long en RPGIII :
de base
DIM(nn)
E....FromfileTofile++Name++N/rN/tbLen
E
TZ10
20 10
Equivalent en ILE RPG :
DTZ10
S
10
DIM(20)
La longueur décrite est celle d’un poste en carte D. DIM(20) indique qu’il y a
20 occurrences de ce poste. Donc la longueur effective totale de TZ10 est de 20
postes * 10 = 200 caractères.
Voyons maintenant une déclaration de tableau en tant que poste d’une data
structure :
D
D FLD1
D FLD2
DS
5
INZ('ABCDE')
INZ
1
DIM(5) OVERLAY(FLD1)
DIM
OVERLAY Ici, la Data Structure est composée de :
Un champ FLD1 alphan. De 5 de long initalisé INZ avec la constante
‘ABCDE’
Un tableau FLD2 dont un poste est de longueur 1 soit 5 de long au total.
D’autre part, OVERLAY(FLD1) indique que le tableau FLD2 partage la même
zone de mémoire, donc le contenu de chacun des postes de FLD2 sera :
Le poste 1 contient ‘A’
Le poste 2 contient ‘B’
Le poste 3 contient ‘C’
Le poste 4 contient ‘D’
Le poste 5 contient ‘E’
Nous avons un équivalent :
DFLD1
S
5
INZ('ABCDE')
DFLD2
S
1
DIM(5)
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
MOVEA
FLD1
FLD2(1)
Dans cet exemple, les deux zones sont déclarées séparément Single en carte D.
L’instruction MOVEA peuple le tableau FLD2 à partir du poste 1. Le contenu
des postes sera équivalent à l’exemple précédent.
Remarque : noter la syntaxe pour un poste d’un tableau TABEAU(p)
22
23
CHAPITRE I ILE RPG
I.3)
Instructions Soit lire le tableau FLD2 de 5 postes de l’exemple précédent dans une boucle :
de base
DO
……..
T(nn)
……..
ENDDO
Di
DZONE
S
S
5
1
0
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
DO
5
I
C……….
C
EVAL
ZONE = FLD2(i)
C……….
C
ENDDO
La valeur de I est incrémenté 5 fois : boucle DO….ENDDO. La variable
ZONE prendra la valeur ‘A’ pour i=1……’E’ pour i=5
Pour rechercher l’indice correspondant au contenu d’un poste d’un tableau
alphanumérique, en RPGIII nous avions l’instruction LOKUP et en ILE RPG
LOOKUP.
LOOKUP
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
EVAL
I = 1
C
‘C’
LOOKUP
FLD2(i)
20
I prendra la valeur 3 car le poste 3 contient ‘C’. D’autre part l’indicateur 20
sera égal à *ON trouvé.
SORTA
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
MOVEA
‘CABFDE’
FLD2(1)
C
SORTA
FLD2
SORTA Effectue le tri du tableau : FLD2 contiendra ‘ABCDEF’.
XFOOT
DTOTAL
S
6
Dtn
S
5
C
EVAL
tn(1)
C
EVAL
tn(2)
C
EVAL
tn(3)
C
EVAL
tn(4)
C
XFOOT
tn
* Après : TOTAL contiendra 17
C
EVAL
*INLR
0
0
=
=
=
=
DIM(4)
5
2
6
4
TOTAL
= *ON
XFOOT effectue le total des postes d’un tableau numérique.
23
24
CHAPITRE I ILE RPG
I.3)
Instructions de
base
ADDDUR
SUBDUR
*days
*months
*years
HDATFMT(*ISO)
DNUM_8
DNUM_6
DALP_8
DZ6V0
DZ8V0
DDATISO
DDATDMY
* 1°) convertir
C
*YMD
* note 4
C
* note 5
C
*YMD0
* note 3
C
*YMD
* note 2
S
8 0 INZ(19960312)
S
6 0 INZ(960312)
S
8
INZ('19960312')
S
6 0
S
8 0
S
D
S
D
DATFMT(*DMY)
données num. ou alphanum. Vers données Date.
MOVE
NUM_6
DATISO
'1996-03-12'
MOVE
NUM_8
DATISO
'1996-03-12'
MOVE
ALP_8
DATISO
'1996-03-12'
MOVE
NUM_8
DATDMY
'12/03/96'
* 2°) Ajouter 1 an 2 mois et 10 jour à DATISO puis enlever 6 mois
ADDDUR
10:*days
DATISO
ADDDUR
2:*months
DATISO
ADDDUR
1:*years
DATISO
*
'1997-05-22'
C
SUBDUR
6:*months
DATISO
*
'1996-11-22'
* 3°) convertir données Date Vers données numériques alphanum.
C
MOVE
DATISO
Z8V0
*
19961122
C
MOVE
DATISO
ALP_10
*
‘1996-11-22’
C
*YMD
MOVE
DATISO
Z6V0
* note 5
'961122'
C
*YMD0
MOVE
DATISO
ALP_8
* note 5
note 2
'19961122'
C
EVAL
*INLR = *ON
C
C
C
L’exemple ci-dessus simule des dates numériques ou alphanumériques qui
seraient issues d’un fichier afin de les convertir et/ou d’y ajouter une
période.
Note 1 : la donnée DATISO est de format Date. Le format date doit
normalement être indiqué, s’il ne l’est pas, c’est la définition du format date
en carte H qui s’applique : H DATFMT(*ISO)
Note 2 : la donnée DATDMY est de format date *DMY. Soit ‘12/03/96’.
Note 3 : *YMD0 la donnée ALP_8 étant alphanumérique de 8, 0 indique
qu’il n’y a pas de séparateur.
Note 4 : *YMD s’applique à une donnée numérique de 6 ou de 8 de long. Si
la donnée est numérique de 6, le ILE RPG déduit le siècle.
Note 5 : Si la donnée numérique est différente de 8 ou alphanumérique de
10, il faut préciser *YMD ou *YMD0 pour le format.
Nous voyons que la syntaxe de conversion est très simple.
Il est très simple également en ILE RPG d’ajouter ADDDUR ou retrancher
SUBDUR une durée à une donnée de type Date.
24
25
CHAPITRE I ILE RPG
I.3)
Instructions de
base
Date et heure
du jour,
horodatage
*hours
*minutes
*secondes
CLEAR
*ms
HDATFMT(*ISO)
DDATISO
S
D
DTIMSTART
S
T
DHORODATAGE
S
Z
DZ26
S
26
* date du jour heure de l'instant
C
MOVE
*date
DATISO
*
'2006-03-05'
C
TIME
TIMSTART
*
'16.08.10'
C
TIME
HORODATAGE
*
‘2006-03-05-16.08.10.309000’
* Ajouter 2 heures à l'heure de l'instant
C
ADDDUR
2:*hours
TIMSTART
* Ajouter 2 minutes à l'heure de l'instant
C
ADDDUR
2:*minutes
TIMSTART
* Ajouter 2 secondes à l'heure de l'instant
C
ADDDUR
2:*seconds
TIMSTART
*
'18.10.12'
* note 1 initialiser et peupler HORODATAGE
C
CLEAR
HORODATAGE
*
‘0001-01-01-00.00.00.000000’
C
MOVE
DATISO
HORODATAGE
C
MOVE
TIMSTART
HORODATAGE
*
'2006-03-05-18.10.12.000000'
* note 2 ajouter 1234 millisecondes et 12 jours à HORODATAGE
C
ADDDUR
1234:*ms
HORODATAGE
C
ADDDUR
12:*days
HORODATAGE
* sans séparateur *ISO0 dans un champ alphanum. de 26c
C
*ISO0
MOVE
HORODATAGE
Z26
*
'20060317181012001234'
C
EVAL
*INLR = *ON
Note 1 : MOVE permet de peupler une zone de type z horodatage car nous
avons respectivement une zone de type D et une zone de type T en facteur 2.
Note 2 : Il est possible d’ajouter ou retrancher des jours, mois, ans, heures,
minutes, secondes, ms, à la zone de type Z horodatage.
==============================================
Comment calculer le nombre de jours entre deux dates par exemple
alphanumériques provenant d’un fichier ?
Ici date jj/mm/aa - mmjjaaaa en nombre de jours
SUBDUR
nombre de
jours entre
deux dates
HDATFMT(*ISO)
DZ8A
DZ8B
DDATISO1
DDATISO2
DZ8V0
C
*DMY/
C
*USA0
C
DATISO1
C**
2006-12-10
C
S
S
S
S
S
MOVE
MOVE
SUBDUR
EVAL
8
INZ('10/12/06')
8
INZ('02062005')
D
D
8 0
Z8A
DATISO1
Z8B
DATISO2
DATISO2
Z8V0:*D
2005-02-06 = 672 jours
*INLR = *ON
25
26
CHAPITRE I ILE RPG
I.3)
Instructions de
base
Contrôle
validité date
TEST(DE)
HDATFMT(*ISO)
DDATISO
S
D
DZ6V0
S
6 0 INZ(005544)
*
* tester la validité d'une date numérique provenant d'un fichier
C
*DMY
TEST(DE)
Z6V0
*
C
IF
%ERROR
C
CLEAR
DATISO
C
ELSE
C
*DMY
MOVE
Z6V0
DATISO
C
ENDIF
*
DATISO = '0001-01-01'
* date valide
C
EVAL
Z6V0 = 051098
C
*DMY
TEST(DE)
Z6V0
*
C
IF
%ERROR
C
CLEAR
DATISO
C
ELSE
C
*DMY
MOVE
Z6V0
DATISO
C
ENDIF
*
DATISO = '1998-10-05'
C
EVAL
*INLR = *ON
Remarque : *DMY implique que la date est sur 6 de long..
TEST(DE) permet de tester la validité d’une Date. Si la date est en erreur, le
test qui suit IF %ERROR ou un indicateur *ON à droite sous = permet de
détecter l’erreur.
Il y a l’équivalent TEST(TE) pour tester une donnée de type T Time.
*loval
*hival
C
CLEAR
*
C
MOVE
*LOVAL
MOVE
*HIVAL
*
C
*
DATISO
‘0001-01-01’
DATISO
‘0001-01-01’
DATISO
‘9999-12-31’
*LOVAL ou CLEAR et *HIVAL permettent d’initialiser une date *iso à la
valeur la + basse puis à la valeur la + haute.
=============================================
Quelques formats date courants :
Autres
formats date
DDATJUL
DDATUSA
DDATEUR
DZ6V0
C
*DMY
*
C
*DMY
*
C
*DMY
*
C
S
S
S
S
D
D
D
DATFMT(*JUL)
DATFMT(*USA)
DATFMT(*EUR)
6 0 INZ(200306)
MOVE
Z6V0
DATJUL
an/nbr jours
'06/079'
MOVE
Z6V0
DATUSA
mm/jj/aaaa
'03/20/2006'
MOVE
Z6V0
DATEUR
jj.mm.aaaa
'20.03.2006'
EVAL
*INLR = *ON
26
27
CHAPITRE I ILE RPG
I.3)
Instructions de Voici maintenant un exemple de tableau à n dimensions dont les postes sont
chargés à la compilation.
base
POSTAL est un tableau dont le poste est de 26 de long ; 5 postes.
Chaque poste est subdivisé en CODPOST 6 de long et VILLE 20 de long
REGION 2 de long également 2 premiers caractères de CODPOST.
L’exemple consiste a rechercher la ville du code postal CODPOST dont le
Tables
contenu est égal à ‘59000’ Le programme a été compilé et testé avec le
chargées à la
debogue pas à pas d’IBM comme nous verrons dans le chapitre suivant :
compilation.
CTDATA
n dimensions
PERRCD(n)
HDEBUG
D
DS
DPOSTAL
26
DIM(5) PERRCD(1) CTDATA
D
REGION
2
OVERLAY(POSTAL:1)
D
CODPOST
6
OVERLAY(POSTAL:1)
D
VILLE
20
OVERLAY(POSTAL:7)
Di
S
5 0
DZONE
S
20
* ------------------------------------------------------------------ *
C
EVAL
i = 1
C
'59000 '
LOOKUP
CODPOST(i)
20
C*
C
IF
*IN20
C
EVAL
ZONE = VILLE(i)
C
ENDIF
C*
C
SORTA
VILLE
C*
C
SETON
LR
**CTDATA POSTAL
75000 PARIS
13000 LA ROCHELLE
51600 SUIPPES
59000 LILLE
59222 BOUSIES
Remarque : la longueur est définie pour un seul poste. Ainsi, un poste de
POSTAL est de longueur 26. Les deux postes CODPOST et VILLE
recouvrent OVERLAY le poste POSTAL. Dans le programme, nous voyons
que CODPOST et VILLE sont des sous-tableaux.
Le mot clé CTDATA permet de charger le contenu d’un tableau à la
compilation, ce contenu étant précisé à la fin du programme ILE RPG à
partir de la position 1.
**CTDATA POSTAL
est obligatoire et indique que le contenu des lignes du tableau POSTAL
commence après.
Le mot clé PERRCD(1) signifie qu’il n’y a qu’un poste POSTAL pour
chaque ligne qui suit **CTDATA POSTAL.
SORTA VILLE : bien entendu, CODPOST et REGION suivront en
parallèle le tri de VILLE, car le tri s’effectue sur POSTAL, dans l’ordre de
la sous-zone VILLE.
27
28
CHAPITRE I ILE RPG
MOVE : Peuple la partie droite d’un champ résultat.
I.3)
Instructions MOVEL : Peuple la partie gauche d’un champ résultat.
Particularités :
de base
MOVE et MOVEL ne remettent pas à blanc ou à zéro le champ résultat avant
de le peupler. Les octets non peuplés contiendront donc les anciennes valeurs.
MOVE(p) et MOVEL(p) remettent à blanc ou à zéro le champ résultat avant de
MOVE
le peupler.
MOVEL
Polymorphisme de MOVE et MOVEL:
MOVE et MOVEL peuvent peupler des champs de nature différente. Par
exemple de l’alphanumérique dans du numérique ou du numérique dans de
l’alphanumérique. Ces instructions sont donc très puissantes. Notons que le
numérique peut être étendu ou packé. Mais si un champ alphanumérique doit
peupler un champ numérique, il doit contenir uniquement des 0..9. Un test
préalable de numéricité TESTN est donc indispensable dans ce cas.
Voici quelques exemples :
TESTN
*ALL’a’
DZ10ALPHA
S
10
INZ('ABCDEFGHIJ')
DZ5NUM
S
5 0 INZ(22222)
DW5ALPHA
S
5
INZ('12345')
DZ8NUM
S
8 0 INZ(34343434)
DZ15NUM
S
15 0 INZ(0123456789012345)
*
C
MOVE
W5ALPHA
Z10ALPHA
* Après Z10ALPHA = 'ABCDE12345'
C
MOVEL
W5ALPHA
Z10ALPHA
* Après Z10ALPHA = '1234512345'
C
MOVEL
Z5NUM
Z10ALPHA
* Après Z10ALPHA = '2222212345'
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result++++++++Len++D+HiLoEq
C
TESTN
Z10ALPHA
20
C
IF
*IN20
C
MOVE
Z10ALPHA
Z15NUM
C
ELSE
C
CLEAR
Z15NUM
C
ENDIF
* Après Z15NUM 0123452222212345
C
MOVE
*ALL'A'
Z10ALPHA
* Après Z10ALPHA = 'AAAAAAAAAA'
C
MOVEL
*ON
*INLR
Remarques :
TESTN : si Z10ALPHA est numérique, *IN20 = *ON
*ALL’A’ : peuple Z10ALPHA avec des A.
28
29
CHAPITRE I ILE RPG
EVAL permet de concaténer des champs alphanumériques. Cependant, cette
I.3)
Instructions de concaténation est brute comme dans l’exemple suivant :
base
EVAL pour
alphanum.
DPRENOM1
S
DPRENOM2
S
DNOM
S
DNOMPRENOM
S
*
C
EVAL
C
* Après : NOMPRENOM = 'Jean
C
EVAL
10
10
10
30
INZ('Jean
')
INZ('Etienne
')
INZ('LAFLECHE ')
INZ('AAAAAAAAAAAAAAAAAAA')
NOMPRENOM = PRENOM1 + PRENOM2 +
NOM
Etienne
LAFLECHE '
*INLR = *ON
Note : avec EVAL, tous les champs doivent être soit alphanumériques, soit
numériques : nous aurons respectivement une concaténation dans un cas et
un calcul dans l’autre. Seul l’opérateur + est admis pour une concaténation.
Ici, l’opération de concaténation est exprimée sur plusieurs lignes.
Attention : + en bout de ligne est un opérateur de concaténation et n’indique
en rien une quelconque continuation à la ligne suivante !
CAT associé à EVAL permet des concaténations plus élaborées, comme
dans l’exemple suivant :
CAT
Facteur2:1
DPRENOM1
S
10
INZ('Jean
')
DPRENOM2
S
10
INZ('Etienne
')
DNOM
S
10
INZ('LAFLECHE ')
DNOMPRENOM
S
30
INZ('AAAAAAAAAAAAAAAAAAA')
*
C
EVAL
NOMPRENOM = PRENOM1
* Après NOMPRENOM = 'Jean
'
C
NOMPRENOM
CAT
PRENOM2:1
NOMPRENOM
* Après NOMPRENOM = 'Jean Etienne
'
C
NOMPRENOM
CAT
NOM:1
NOMPRENOM
* Après NOMPRENOM = 'Jean Etienne LAFECHE
'
C
SETON
LR
Bien entendu, CAT ne remet pas à blanc avant afin de permettre des
concaténations en série. Facteur2 :1 indique qu’il y aura un blanc entre le
facteur1 et le facteur2. Ainsi, Facteur2 :0 exécute une concaténation sans
blanc entre le facteur1 et facteur2.
Le 1er EVAL met à blanc avant et peuple en justifiant à gauche.
29
30
CHAPITRE I ILE RPG
I.3)
Instructions
de base
%SUBST
%LEN
%TRIMR
DLGR
S
5 0
DPRENOM1
S
10
DPRENOM2
S
10
DNOM
S
10
DNOMPRENOM
S
30
INZ('Jean
Etienne
LAFLECHE
*
C
MOVEL(p) NOMPRENOM
PRENOM1
* Après : PRENOM1 = 'Jean
'
C
EVAL
PRENOM2 = %SUBST(NOMPRENOM:11:10)
* Après : PRENOM2 = 'Etienne
'
C
EVAL
NOM = %SUBST(NOMPRENOM:21:10)
* Après : NOM = 'LAFLECHE '
*
C
EVAL
LGR = %LEN(PRENOM1)
* Après : LGR = 10 longueur totale du champ PRENOM1
C
EVAL
LGR = %LEN(%TRIMR(PRENOM1))
* Après : LGR = 4 longueur du contenu du champ PRENOM1 'Jean'
C
EVAL
*INLR = *ON
Remarque :
%LEN(%TRIMR(champ)) retourne la longueur du contenu du champ sans les
blancs à droite. %LEN(champ) retourne la longueur totale du champ
indépendamment de son contenu (les blancs à droite sont comptés).
%SUBST(champ :position de début :longueur) permet une extraction à
l’intérieur d’une chaîne de caractères à condition de connaître la position de
début et la longueur.
Dans l’exemple suivant le séparateur de champ ; est détecté avec un SCAN :
SCAN
%SUBSTR
DD
S
5 0
DF
S
5 0
DLGR
S
5 0
DNOMPRENOM
S
30
INZ('Jean;Etienne;LAFLECHE')
DPRENOM1
S
10
DPRENOM2
S
10
*
C
';'
SCAN
NOMPRENOM
D
* Après : D = 5 *IN20 = *ON
C
IF
*IN20
C
EVAL
PRENOM1 = %SUBST(NOMPRENOM:1:D-1)
* Après : PRENOM1 = 'Jean
'
C
ENDIF
*
C
EVAL
D = D + 1
C
';'
SCAN
NOMPRENOM:D
F
C
EVAL
LGR = F - D
*
* Après : F = 13 D = 6
LGR = 7
C
IF
*IN20 AND D < F
C
EVAL
PRENOM2 = %SUBST(NOMPRENOM:D:LGR)
* Après : PRENOM2 = 'Etienne
'
C
ELSE
C
EVAL
PRENOM2 = *BLANKS
C
ENDIF
*
C
EVAL
*INLR = *ON
Remarque : facteur2 :D indique la position de début de la recherche dans la
chaîne de caractères. 1 par défaut.
30
20
20
31
CHAPITRE I ILE RPG
I.3)
Instructions
de base
API
QCLSCAN
DQCLSCAN
PR
EXTPGM('QCLSCAN')
D CharString
1024
D LenghtOfChar
3 0
D StartingPosit
3 0 const
D CharPattern
1024
D LengthOfChar
3 0
D TranslateChar
1
const
D TrimTrailingBl
1
const
D WidcardChar
1
const
D CharStringRes
3 0
DWString
S
1024
DWStrLen
S
3 0
DWPattern
S
1024
DWPatLen
S
3 0
DWResult
S
3 0
DWSelData
S
1
……………………………………………………………………
C
BEGSR
………………………………………………………..
C* SCAN
; Raison Sociale. Fichier: EXCLIENT Client Exemples Fast
C
IF
SCC1RAIS51 <> *BLANK
C
EVAL
WString = C1RAISON
C
EVAL
WStrLen = %Len(%Trim(C1RAISON))
C
EVAL
WPattern = SCC1RAIS51
C
EVAL
WPatlen = %Len(%Trim(SCC1RAIS51))
C
CALLP
QCLSCAN(WString:WStrLen:1:
C
WPattern:WPatLen:'1':'1':
C
'*':WResult)
C*
C
IF
WResult <= *zero
C
EVAL
WSelData = *OFF
C
LEAVESR
C
ENDIF
C*
C
ENDIF
………………………………………………………………………….
C
ENDSR
Dans ce dernier exemple sur les instructions ILE RPG, nous utilisons l’API
IBM QCLSCAN. Nous utilisons QCLSCAN plutôt que le SCAN ILE RPG à
cause de la traduction des majuscules en minuscules pour la recherche et du
caractère de remplacement ‘*’ dans les programmes de critères de sélection et
surtout de l’optimisation.
Nous avons là un exemple de calcul de la longueur du contenu des deux
variables afin d’optimiser le SCAN, sans quoi il effectuerait la recherche sur
toute la longueur du champ cible, soit 1024 caractères.
Notons que %TRIM est équivalent à %TRIMR (sans les blancs à droite).
Notons également l’utilisation de LEAVESR afin de sortir immédiatement du
sous-programme, dans un but d’optimisation, si le SCAN n’a pas été trouvé.
CONCLUSION :
ILE RPG est un langage de gestion très puissant. Pour la gestion classique, il
convient de se limiter aux instructions de base afin de garder un contrôle
intellectuel sur les applications sur le long terme. Mais il faut savoir qu’en cas
de nécessité, des instructions ILE RPG pointues sont à disposition du
développeur.
31
32
Partie II Personnaliser les programmes
32
33
CHAPITRE II Personnaliser les programmes
II.1)
Debogue
IBM ILE
RPG
Conseil : pour ajouter des instructions dans un programme, il est souvent
nécessaire d’avoir le contenu de toutes les données de tous les fichiers. Or, le
contenu des données qui ne sont pas utilisées par le programme ILE RPG ne
peut pas être affiché. En effet, seules les données utiles sont effectives dans un
but d’optimisation de la place mémoire d’un programme à l’exécution. C’est
pourquoi nous conseillons d’ajouter en carte H DEBUG le temps du debogue et
de l’enlever ensuite pour des raisons de place mémoire :
HDEBUG
===================================================
Préalable : pour qu’un programme ILE RPG puisse être debogué (un
programme compilé avec le générateur est en mode debogue par défaut) il faut :
Avec l’option 14 de PDM + F4, devant un membre source RPGLE, afficher les
paramètres et modifier DBGVIEW(*ALL) :
STRDBG
CRTBNDRPG avec DBGVIEW(*ALL)
====================================================
Pour effectuer un debogue rapide d’un programme, procéder comme suit :
1°) lancer la commande STRDBG UPDPROD(*yes)
Remarques :
Si votre bibliothèque est de type TEST, UPDRPOD n’a pas d’utilité.
Si votre bibliothèque est de type PROD : si STRDBG avec UPDPROD(*no) les
données du programme ne seront pas mises à jour jusqu’au lancement de la
commande ENDDBG qui termine le mode debogue.
===================================================
2°) lancer la commande DSPMODSRC
Ouvrir une
3°) commande F14
vue source
4°) Saisir 1 puis le nom du programme :
debogue
Opt
1
Pgm/module
abcsl2
Biblio
*LIBL
Type
*PGM
ENTREE
5°) Saisir 5 devant le *MODULE :
Opt
5
Pgm/module
abcsl2
ABCSL2
ABCSL2
Biblio
*LIBL
TSTLIBOBJ
Type
*PGM
*PGM
*MODULE
Sélectionné
33
34
CHAPITRE II Personnaliser les programmes
II.1)
Debogue
IBM ILE
RPG
Programme:
1
7
8
9
10
14
15
ABCSL2
Biblio:
HDEBUG
F* Ecran dspf :
FABCSL2W
CF
E
F
F
F* Prospects / Pays
FPROSPECTL1IF
E
TSTLIBOBJ
Module:
ABCSL2
WORKSTN
SFILE(WSFL:RRN)
INFDS(DS_Display)
K DISK
Le source du programme s’affiche:
Conseil : afficher toujours systématiquement la vue objet compilé :
Vue objet
6°) commande F15 puis saisir 1 devant Vue Listage ILE RPG:
Opt
1
Vue
Vue listage ILE RPG
Vue source ILE RPG
Vue copie ILE RPG
=====================================================
Ajouter/enlever les points d’arrêt :
Ajout point Commande F06 point d’arrêt devant une ligne carte C non en commentaire.
d’arrêt
Pour rechercher une ligne de code précise :
Lancer sur la ligne de commandes de debogage : TOP pour se positionner au
début du programme.
Rechercher puis comme avec SEU : F NomRecherche
puis F16 pour rechercher éventuellement l’occurrence suivante comme avec
SEU. Note : F09 commande précédente.
======================================================
Pour deboguer :
Appeler le programme normalement. Il doit s’arrêter au point d’arrêt spécifié.
S’il ne s’arrête pas, cela veut dire que le programme ne passe pas par les
instructions du point de debogue.
Voir ou
forcer un
contenu de
variable
ENDDBG
Pour voir le contenu d’une variable :
Lancer la commande EVAL nomvariable OU F11 le curseur étant
positionné sur la variable.
Pour visualiser le contenu en hexa. : EVAL NomVariable :x
F10 pour aller à la ligne suivante F12 au point d’arrêt éventuel suivant.
Pour forcer le contenu d’une variable :
Lancer la commande : EVAL NomVariable = ‘NouvelleValeur’
======================================================
ENDDBG : est le pendant de STRDBG et termine le mode debogue pour la
session.
34
35
CHAPITRE II Personnaliser les programmes
II.2 ) Ajout
Comment ajouter un contrôle personnalisé dans une fiche ou
d’un
formulaire modèle de type FCH ?
contrôle
Pour ajouter un contrôle vous devez savoir :
1°) Le point du programme où ajouter le contrôle.
2°) Ajouter un message personnalisé dans un fichier messages.
3°) Ajouter le contrôle en ILE RPG
4°) Compiler + Tester le programme.
Nous allons voir en détail ces points :
1°) Le sous-programme des contrôles. /SEU/ « Sous-prog. Du modèle »
Rappel : pour visualiser les sous-programmes d’un modèle :
R.A.D.
Critère/S
SEU_hlp
Manage
_________________________ ________________________
FastRPG Janvier 2006
Modifier Sources
Environnement par défaut
Compiler
FCH En_cours: AV001FCH A
________________________
PDM d'IBM
| F11=Date/Nom
F10-v
Sous-Prog. du modèle
-----------------------| 2/03/06 | EDTCLPY
Exemples pgms générés
| 1/03/06 | ABCSL2
| 1/03/06 | ABDSL2
ABDSL2
| SL2
> 1/03/06 | AV001FCH
AV001FCH
| FCH
Système
__________
. *PGM dé
re: EXCLI
_________
ress.: 1
--------dition
iste clas
Liste clas
Fiche
___________________________________________________________________
|
| Nom
| Fonction
| Routine
------------------------------------------------------------------|
AFFICHAGE DES ECRANS
| SRDSP_2
| Affichage écrans en Création ou en Modification
| SRDSP_2
| Affichage des écrans Visualisation OU Annulation
| SRDSP_5
|
CONTROLES ; APPLIQUER REGLES GESTION
| SRCTL_2
| Structure, contrôle des pages
| SRCTL_2
| Contrôle de la page 1
| SRWFCH1
|
(1..9 pages maxi)
| SRWFCH1
Le contrôle de la page 1 est SRWFCH1 … SRWFCH9. Il peut y avoir 9 pages
maxi.
Donc, allons dans le source avec SEU et recherchons le sous-programme
SRWFCH1 :
Nous voyons qu’à l’intérieur du « tiroir » SRWFCH1 il y a n compartiments,
un par donnée à contrôler, avec un tag + indicateur + Page.
C*
C* ind. erreur = 11 C1KCLI Code Client
C
End_IN11P1
tag
C*
C* ind. erreur = 12 C1RAISON Raison Sociale
C
End_IN12P1
tag
C*
C* ind. erreur = 13 C1ADR1 Adresse lgn 1
C
End_IN13P1
tag
35
36
CHAPITRE II Personnaliser les programmes
II.2 ) Ajout
Remarque :
d’un
Le tag est facultatif et est utilisé uniquement par le générateur pour
contrôle
regrouper les contrôles d’un même champ de saisie ensemble.
Si le tag n’est pas présent, le générateur insère le contrôle avant le ENDSR.
Les indicateurs d’erreur, pour chacune des pages, vont de 11 à 49.
Chaque indicateur gère uniquement DSPATR(RI PC) au niveau du champ, soit
le positionnement curseur et la reverse video. La gestion des messages est
totalement indépendante. Il peut y avoir un nombre infini de messages d’erreur
par champ contrôlé. Le texte du message d’erreur peut être géré en dehors du
programme.
Le tag : End_IN13P1 correspond par exemple à l’indicateur 13 de la page 1.
===================================================
2°) Ajouter un message personnalisé dans un fichier messages.
Vous devez créer en premier le fichier messages pour votre société et en aucun
cas prendre celui du générateur. Vous allez créer un fichier messages objet
i5/OS de type *msgf avec la commande IBM si votre société s’appelle ABC et
MYLIBOBJ ma bibliothèque objet courante :
CRTMSGF MYLIBOBJ/ABCMSGF
Ensuite il faut ajouter un message dans le fichier des messages avec l’une des
deux commandes IBM ADDMSGD ou WRKMSGD :
WRKMSGD MSGF(ABCMSGF)
puis F06 ajouter un message
Ajouter description de message (ADDMSGD)
Indiquez vos choix, puis appuyez sur ENTREE.
Identificateur de message .
Fichier de messages . . . .
Bibliothèque . . . . . . .
Texte message de 1er niveau
ville doivent être renseignés
.
.
.
.
. MSGID
. MSGF
.
. MSG
ABC0001
> ABCMSGF
>
TSTLIBOBJ
Le code postal et la
Texte message de 2e niveau . . . SECLVL
Si le code postal ou
la ville sont renseignés, alors les deux doivent être renseignés. Sinon
les deux doivent être laissés à blanc.
Saisir le message de 1er niveau et le message de second niveau éventuellement.
F05=Rafraichir
Important : l’identifiant du message, ici ABC0001 doit commencer par 3 lettres
puis 4 chiffres hexa. Soit 0..F
36
37
CHAPITRE II Personnaliser les programmes
II.2 ) Ajout
3°) Ajouter le contrôle en ILE RPG
d’un
contrôle
Nous allons maintenant ajouter le contrôle suivant :
Si (le code postal OU la ville sont <> de blanc)
ET (le code postal = blanc OU la ville = blanc)
| erreur.
Fin si
Autrement dit : les deux doivent être renseignés ou les deux doivent être à
blanc.
Nous allons donc mettre en reverse video le code postal et la ville en cas
d’erreur et envoyer à la file d’attente des messages du programme notre
message identifiant : ABC0001
Emplacement :
C*
C* ind. erreur = 16 C1CODPOS Code Postal
C
IF
(C1CODPOS <> *BLANK OR
C
C1VILLE <> *BLANK)
C
AND
C
(C1CODPOS = *BLANK OR
C
C1VILLE = *BLANK)
C
EVAL
*IN16 = *ON
C
EVAL
*IN17 = *ON
C
EVAL
WMsgf = 'ABCMSGF'
C
EVAL
WMsgId = 'ABC0001'
C
CALL
'WSNDMSG'
WSndMsg
C
ENDIF
C
End_IN16P1
tag
C*
C* ind. erreur = 17 C1VILLE Ville
C
End_IN17P1
tag
Le message d’erreur peut être inséré soit avant End_IN16P1, soit avant
End_IN17P1 soit bien entendu avant le ENDSR.
*IN16 et *IN17 vont mettre en reverse video les deux champs en erreur. Voir
dans les DSPF l’ attribut DSPATR(RI).
Remarque 1 : le programme WSNDMSG (dont vous avez le source. Voir
brochure 1), envoie le message à la file d’attente du programme.
Conseil : ne jamais utiliser le fichier des messages du générateur. Prendre le
fichier des messages pour votre société uniquement.
Remarque 2 : si nous ajoutons maintenant un contrôle par le générateur sur le
champ C1CODPOS, il insèrera le contrôle avant le tag End_IN16P1. Bien
entendu, sans toucher au contrôle personnalisé.
37
38
CHAPITRE II Personnaliser les programmes
II.2 ) Ajout
4°) Compiler et tester
d’un
Code Postal.
contrôle
Ville. . . .
. . . . .:
. . . . .:
Code Pays. . . . . . .:
75800
FRA France
F9=Valider F12=Prédt.
Le code postal et la ville doivent être renseignés
Nous avons bien le code postal et la ville en reverse video.
Si l’utilisateur place son curseur sur la ligne du message d’erreur et F01 ou
AIDE, nous aurons le message de deuxième niveau mais aussi l’identifiant du
message, ce qui est très utile en maintenance du programme. En effet, il suffit
ensuite d’effectuer des recherches sur l’identifiant du message d’erreur dans le
membre source, par exemple rechercher ‘ABC0001’ avec SEU.
ID message . . . . . . :
Type de message . . . :
Date d'envoi . . . . . :
ABC0001
Information
06/03/06
Gravité
. . . . . . . :
Heure d'envoi
. . . . :
00
17
Message . . . . :
Le code postal et la ville doivent être renseignés
Si le code postal ou la ville sont renseignés, alors les deux sont
obligatoires.
Puis F09=Détails du message
Programme de destination . . . :
Bibliothèque . . . . . . . . :
Module de destination . . . :
Procédure de destination . . :
Spécification destination . :
AV001FCH
TSTLIBOBJ
AV001FCH
AV001FCH
754
En plus de l’identifiant du message, nous obtenons avec F09 de suite le nom du
programme lui même.
Notez que AV001FCH est le programme de destination du message, le
programme d’origine étant WSNDMSG. C’est une communication i5/OS dite
de programme à programme. Nous avons également la ligne 754 qui
correspond à la ligne de debogue avec F15 vue de l’objet (voir chapitre
précédent).
750
751
752
753
754
C
C
C
C
C
EVAL
EVAL
EVAL
EVAL
CALL
*IN16 = *ON
*IN17 = *ON
WMsgf = 'ABCMSGF'
WMsgId = 'ABC0001'
'WSNDMSG'
WSndMsg
38
39
CHAPITRE II Personnaliser les programmes
Le préaffichage d’une fiche permet de préafficher en création des informations
II.3 )
Préaffichage dans des champs d’Entrée/Sortie. Le préaffichage en création répond
en création généralement à une demande pressante des utilisateurs comme :
- « 9 fois sur 10 je suis obligé de saisir la date du jour dans la date
d’une fiche
commande en création… »
- « 8 fois sur 10 en création le code pays est le même »
etc…
Nos générateurs savent traiter ces cas les plus courant, cependant il existe
toujours des spécificités en fonction de l’activité. Il faut donc savoir où insérer
le préaffichage en création dans une fiche, c’est à dire connaître le bon sousprogramme :
Sélectionner un programme de type FCH fiche à partir du menu principal :
Sousprogramme
d’un modèle
R.A.D.
Critère/S
SEU_hlp
Manage
Syst
_________________________ ________________________ ____
FastRPG Janvier 2006
Modifier Sources
Environnement par défaut
Compiler
. *
FCH En_cours: AV001FCH A
re:
________________________
PDM d'IBM
___
| F11=Date/Nom
F10-v
Sous-Prog. du modèle
res
-------------------------| 6/03/06 | AVSL201
Exemples pgms générés
ist
| 2/03/06 | EDTCLPY
dit
| 1/03/06 | ABCSL2
ABCSL2
| SL2 List
____________________________________________________________________
|
| Nom
|
| Fonction
| Routine
|
-------------------------------------------------------------------|
=> STRUTURE GENERALE DE LA FICHE
| *MAIN
|
|
| *MAIN
|
|
INITIALISATION
| SRPLIST
|
| PLIST utilisés dans le module
| SRPLIST
|
| KLIST utilisés dans le module
| SRKLIST
|
| Initialisation en début de programme
| SRINIT
|
|
S/STRUCTURE DE NIVEAU 2
| SRWRK_2
|
| S/Structure Création OU Modification fiche
| SRWRK_2
|
| S/Structure Annulation fiche
| SRWRK_4
|
| S/Structure Visualisation fiche
| SRWRK_5
|
|
PREPARATION ECRANS AVANT AFFICHAGE
| SRPRP_1
|
| Préparation écran en création
| SRPRP_1
|
Le sous-programme s’appelle SRPRP_1. Il suffit d’insérer le préaffichage juste
avant le ENDSR de ce sous-programme. Voyons un exemple :
39
40
CHAPITRE II Personnaliser les programmes
Soit par exemple, préafficher ‘75000’ dans le code postal à chaque fois que le
II.3 )
Préaffichage code pays est ‘FRA’ France. Nous supposerons que le code pays est passé en
paramètre en création (clé majeure). Nous aurons les instructions suivantes
en création
avant le ENDSR du sous-programme SRPRP_1 :
d’une fiche
C
SRPRP_1
BEGSR
C ……………………………………………………………………………….
C
IF
C1PAYS = 'FRA'
C
EVAL
C1CODPOS = '75000'
C
ENDIF
C*
C
ENDSR
Ce qui nous donnera en Création Fiche après F6 à partir du sous-fichier :
AVFCH01
Client par Pays
Code Pays : FRA France
Clé Client . .
Raison Sociale
Adresse lgn 1.
Adresse lgn 2.
Adresse lgn 3.
Code Postal. .
Ville. . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.:
.:
.:
.:
.:
.:
.:
Créer
000000
75000
================================================
Le pré-affichage en non(création) c’est à dire en modification par exemple
Préaffichage
obéît au même principe mais avec le sous-programme SRPRP_2. Cependant,
en
attention :
non(création)
Le pré-affichage en non(création) est utilisé pour présenter en saisie par
d’une fiche
exemple :
- une date dans une donnée de travail sous forme jjmmaa alors qu’elle est
sous forme aaaammjj dans le fichier.
- Découper en saisie un identifiant comme le code banque en une seule
partie dans le fichier.
- Etc….
Notons dans ce cas que le préaffichage seul ne suffit pas. Il convient
également de contrôler les données de travail en saisie mais aussi de remettre
les données de travail dans les données du fichier avant la mise à jour
effective. Nous devrons donc placer des instructions ILE RPG respectivement
dans trois sous-programmes :
SRPRP_2 : préparation en non(création)
SRWFCHn : contrôle de la fiche n= page 1..9
SRCHGF_2 : mise à jour fichier.
Notons que nos générateurs ont un raccourci qui permet de traiter une donnée
de travail numérique pour la date en une seule finition SHORTWAY qui
regroupe le préaffichage en non(création), le contrôle, et peupler la date
fichier avant la création ou la mise à jour effective.
40
41
CHAPITRE II Personnaliser les programmes
II.4 )
Finition
développée
par le
générateur
Comment visualiser une finition développée par un générateur ?
Comment effacer une finition ?
Peut-on ajouter une finition à un contrôle manuel ?
Ce paragraphe II.3 a pour objet de répondre à ces questions.
Visualiser
ou Effacer
Finition
Pour visualiser/effacer une finition d’un générateur, sélectionner le champs
d’Entrée/Sortie qui a fait l’objet d’un préaffichage ou d’un contrôle. Nous
prendrons comme exemple la finition SHORTWAY d’une date qui effectue un
préaffichage jjmmaa + un contrôle date+ une mise dans le fichier aaaammjj
avant mise à jour fichier :
Adresse lgn 3.
Code Postal. .
Ville. . . . .
Date . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.:
.:
.:
.:
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBB
99/99/99
Positionner le curseur et sélectionner le champ date. ENTRE
FINITIONS POUR:
WDTE Date
1=Sélection pour ajout règles de gestion
F09 ou F12=DESIGN
A_PREAFC
(Avant
saisie) Pré-affichage en CREATION
A_PREAFU
(Avant
saisie) Pré_affichage en NON(CREATION)
B_F04
(Aider
saisie) F4 sur champ; Appel pgm de sélect
C_CONTROL (Pendant saisie) Appliquer une règle ; contrôler
D_FILE
(Après
saisie) Renseigner les champs / fichier
SHORTWAY
RACCOURCI : Préaf. Ecran + Contrôle + ->Fichier
_____________________HISTORIQUE_________________________________
4=Supprimer règle historique
5=Voir RPGLE si Gen=1
Gen
4 SHORTWAY
SHORTDATE RACCOURCI DATE: Préaf. Ecran + Ctrl + 1
Le code génération = 1 de la finition SHORTWAY signifie que le ILE RPG a
été inséré dans le source cible. Saisir ‘4’ pour supprimer le code.
41
42
CHAPITRE II Personnaliser les programmes
II.4 ) Visu
ou effacer
finition
193.00
194.00
195.00
311.00
312.00
313.00
314.00
315.00
316.00
317.00
318.00
319.00
Y001 C
PARM
WMsgId
Y001 C
PARM
WMsgDta
--------------------------------------------------------Y001 C*
Y001 C* Conversion date : Date
Y001 C
MOVEL(p) C1DTCTUT
WDATE
Y001 C
EVAL
WFrmFmt = '*YYMD'
Y001 C
EVAL
WToFmt = '*DMY'
Y001 C
EVAL
WToSep = '*NONE'
Y001 C
CLEAR
WMsgId
Y001 C
CALL
'WCVTDAT'
WCvtDat
Y001 C*
Le source généré de la finition est affiché. F09 pour valider la suppression ou
F11 pour accéder au source via SEU. Notons les points suivants :
- Y001 est le code historique de la finition juste devant la carte C en position
1 à 4. A chaque finition, le code historique est incrémenté de 1 pour le
programme. Seules les lignes du source qui contiennent ce code historique
ET dont la date est égale à la date de génération sont affichées et seront
supprimées.
- Le trait séparateur ------ signifie que le générateur a développé la finition
dans deux sous-programmes différents.
- La ligne nnn.00 correspond à la ligne dans le source ILE RPG. Il suffit donc
de noter le numéro de la ligne puis F11=SEU pour accéder à une finition
via SEU.
- Notons que nos générateurs utilisent une routine de conversion et contrôle
de dates plutôt que les instructions ILE RPG relatives aux dates. En effet, ce
programme CL WCVTDAT peut être modifié pour traiter les cas
particuliers qui existent dans certaines sociétés, comme les dates initialisées
à zéro dans les fichiers ou encore les dates initialisées à 99999999. De plus
le contrôle date est homogène et ne bloque pas l’écran comme le contrôle
d’une donnée de type date contrôlée directement par le système i5 avant de
passer la main au programme.
42
43
CHAPITRE II Personnaliser les programmes
II.4 ) Finition
Peut-on mixer finitions par le générateur et finitions spécifiques ?
développée
Peut-on modifier manuellement une finition ?
par le
générateur et
manuellement Revenons à notre exemple du chaitre II.2 ajout manuel d’un contrôle relatif
au code postal et à la ville.
Ajouter le contrôle suivant avec le générateur :
Tout caractère du code postal doit être soit blanc, soit A..Z, 0..9
Le générateur va ajouter juste avant le tag End_IN16P1 le contrôle :
C*
C* ind. erreur = 16 C1CODPOS Code Postal
C
IF
(C1CODPOS <> *BLANK OR
C
C1VILLE <> *BLANK)
C
AND
C
(C1CODPOS = *BLANK OR
C
C1VILLE = *BLANK)
C
EVAL
*IN16 = *ON
C
EVAL
*IN17 = *ON
C
EVAL
WMsgf = 'ABCMSGF'
C
EVAL
WMsgId = 'ABC0001'
C
CALL
'WSNDMSG'
WSndMsg
C
ENDIF
C*
C* Autorisé A..Z ; 0..9 : Code Postal
C*
caractère blanc admis (mais champ > blanc).
C
EVAL
WBLOK = '1'
C*
C
IF
C1CODPOS = *BLANK
C
EVAL
*IN16 = *ON
C
EVAL
WMsgId = 'USR0003'
C
EVAL
WMsgF = WMsgFSys
C
CALL
'WSNDMSG'
WSndMsg
C
ENDIF
C*
C
MOVEL
*HIVAL
WFFDAZ09
C
MOVEL
C1CODPOS
WFFDAZ09
C
CALL
'WCRAZ09'
WCRAZ09
C*
C
IF
WAZ09OK = *OFF
C
EVAL
*IN16 = *ON
C
EVAL
WMsgId = 'USR0016'
C
EVAL
WMsgF = WMsgFSys
C
CALL
'WSNDMSG'
WSndMsg
C
ENDIF
C*
C
End_IN16P1
tag
Il suffit maintenant de supprimer manuellement les lignes en vert, générées
en trop, car C1CODPOS peut être à blanc entièrement. Nous pouvons donc
travailler main dans la main avec le générateur en ILE RPG. Nous ne
distinguons plus, sur le plan qualitatif, ce qui a été généré automatiquement
de ce qui a été généré manuellement.
43
44
CHAPITRE II Personnaliser les programmes
II.5 ) Sousfichiers
Comment charger le sous-fichier en total afin par exemple d’afficher une
totalisation des lignes commandes dans une donnée de travail d’entête du sousfichier ?
C
SRCharge
BEGSR
C
CLEAR
WCurLinWrt
C*
C*
Ligne courante < nbre de lignes dans une page écran
C
DOW
NOT %EOF(EXCLIENTL1)
C************
AND WCurLinWrt < WSflPag
C*
C* Lectures détail ET préaffichages éventuels.
C
EXSR
SRDtlRead
C
ADD
1
RRN
C
ADD
1
WCurLinWrt
C
CLEAR
WOpt
C
WRITE
WSFL
C*
C* EXCLIENTL1 Client par Pays
C
EXCLIEN001
READE(n) EXCLIENTR
C
ENDDO
1°) Pour charger le sous-fichier en total, mettre en commentaire la ligne en vert
(ET ligne courante < nombre de ligne par page). Ainsi, le fichier ou le groupe
sera lu entièrement.
2°) Après l’instruction CLEAR mettre à zéro la donnée de travail
3°) Dans le sous programme SRDTLREAD qui regroupe les lectures détail et
les préaffichages, totaliser la colonne dans la donnée de travail qui sera affichée
au niveau de l’entête.
====================================================
Comment forcer le chargement du sous-fichier ?
Remarque : le rafraichissement de l’écran est obtenu en activant F05. Soit :
C*
C
C
F05 réafficher :
WHEN
CLEAR
KeyPress = F05
WSflRcdNbr
Il suffit de mettre à zéro la variable WSFLRCDNBR. Au niveau de
l’algorithme général, si cette valeur est à zéro, un chargement du sous-fichier
sera effectué :
C
C
C*
C*
C
C*
C*
C
C*
C*
C
C*
C*
C
C*
C
DOW
NOT(KeyPress = F03) AND
NOT(KeyPress = F12)
Charger sous-ficher si rang courant = 0 OU 'A partir
IF
WSflRcdNbr = *ZERO OR *IN97
Mise à blanc du sous-fichier:
EXSR
SRClrSfl
1ER positionnement fichier :
EXSR
SR1rstRead
Chargement du sous-fichier page suivante :
EXSR
SRCharge
ENDIF
44
45
CHAPITRE II Personnaliser les programmes
II.5 ) Sousfichiers
Comment sont gérées les touches de fonction dans les programmes
transactionnels ? Définition de la variable KeyPress et F01..F24.
La variable KEYPRESS et les constantes des fonctions sont définies dans un
membre en /COPY :
D* Variables Système
D/COPY COPYF,COPYM
et INFDS fichier écran
Contenu de ce member source commun aux programmes en /COPY:
*
INFDS niveau écran :
DDS_DISPLAY
DS
DKeyPress
369
369
DCursorLoc
370
371B 0
*
Touches de fonction, valeurs de KeyPress
DF01
C
X'31'
DF02
C
X'32'
DF03
C
X'33'
DF04
C
X'34'
DF05
C
X'35'
DF06
C
X'36'
DF07
C
X'37'
DF08
C
X'38'
DF09
C
X'39'
DF10
C
X'3A'
DF11
C
X'3B'
DF12
C
X'3C'
DF13
C
X'B1'
DF14
C
X'B2'
DF15
C
X'B3'
DF16
C
X'B4'
DF17
C
X'B5'
DF18
C
X'B6'
DF19
C
X'B7'
DF20
C
X'B8'
DF21
C
X'B9'
DF22
C
X'BA'
DF23
C
X'BB'
DF24
C
X'BC'
DEnter
C
X'F1'
DHelp
C
X'F3'
DRollUp
C
X'F5'
DRollDown
C
X'F4'
D*** Print
C
X'F6'
45
46
CHAPITRE II Personnaliser les programmes
II.5 ) Sousfichiers
Remarque : l’INFDS retourne une valeur hexa à chaque foins que l’utilisateur
appuie sur une touche de fonction.
Par exemple, si l’utilisateur appuie sur entrée, la variable KEYPRESS prendra
la valeur hexa ‘F1’. Nous pouvons donc écrire en ILE RPG :
C
IF
KeyPress = x’F1’
Ce qui ne serait pas très lisible. C’est pourquoi nous avons défini autant de
constantes hexa qu’il y a de touches de commandes afin de pouvoir écrire
l’équivalent :
C
IF
KeyPress = Enter
A retenir : Il est tout à fait possible de forcer dans le programme la valeur de
KeyPress en cas de besoin. Ainsi, si l’appuie de la touche F12=Précédent est
équivalente à la touche F09=Valider, nous pourrons avoir :
C
IF
……………………………………………..
C
EVAL
KeyPress = F12 or KeyPress = F09
KeyPress = F09
Ce qui simplifiera la logique du traitement si l’utilisateur appuie sur F12, car
F09 est forcé plus loin afin de traiter l’équivalence.
Autre exemple :
C
………………………………………….
C
IF
ERREUR = *ON
EVAL
KeyPress = F03
En cas d’erreur grave, la sortie de travail est traitée en simulant F03=Sortie par
l’utilisateur, ce qui simplifie la logique du traitement.
Note : la touche PRINT est laissée en commentaire par défaut.
46
47
CHAPITRE II Personnaliser les programmes
II.6 )
Editions :
Rappel :
Les éditions partent des clés du fichier principal appelé fichier primaire. Ces
clés peuvent être soit les clés naturelles du PF ou LF, soit les clés issues d’un
OPNQRYF.
De ces clés, il faudra sélectionner les ruptures éventuelles de 9 à 1, sachant que
plusieurs clés peuvent partager le même niveau de rupture.
Principe des éditions :
PRTF : Il y aura autant de formats Entête et de formats Pied qu’il y a de
ruptures.
ILE RPG : Il y aura autant de sous-programmes Entête et de sousprogrammes Pied qu’il y a de ruptures.
Il est important de constater que :
L’algorithme dépend des ruptures déclarées.
Chaque Format entête ou pied du PRTF ou sous-programme entête ou pied
du ILE RPG peut être vide. S’il est vide, l’écriture du format vide est
effectué (sans effet sur l’impression). Donc, en maintenance un format
entête ou pied vide pourra toujours être peuplé par la suite au besoin.
Les ruptures déterminent également une présentation des éditions.
Outre les ruptures, il y a également un format entête début programme, un
format pied fin de programme ainsi qu’un format 1ère page.
Notons qu’un format spécial sera imprimé à chaque saut de page sur les
premières lignes de la page suivante indépendamment de l’algorithme. Ce
format peut être paramétré pour votre société :
SEU_hlp
Manage
Système
OS/400
____________________ ________________________________
io V6.3
FAST
Environnement temporaire
: ARC_USR/QRPGLESRC
Paramétrer ergonomie
____
----
ERGONOMIE
/
=Sélection
Opérations et Fonctions
Attribut clés ergonomie classique os/400
Attribut clés ergonomie menu déroulant
Présentations de la box
Titre pour critères de sélection
Entête standard EDITION /début page
Fonction SFLDROP
Il vous suffit alors de choisir une édition type en saisissant le fichier et membre
source du PRTF modèle. A chaque création, le générateur va copier ce format
de début à chaque saut de page.
47
48
CHAPITRE II Personnaliser les programmes
II.6 )
Editions :
Voici ci-après la structure type d’un programme d’édition PRT avec 9 niveaux
de ruptures maxi. Obtenu avec : /SEU/ « Sous-programmes du modèle. »
Début Programme
| Début rupture L9
| | Début rupture L8
| | | Début rupture L7
| | | | Début rupture L6
| | | | | Début rupture L5
| | | | | | Début rupture L4
| | | | | | | Début rupture L3
| | | | | | | | Début rupture L2
| | | | | | | | | Début rupture L1
| | | | | | | | | | Détail
| | | | | | | | | Fin rupture L1
| | | | | | | | Fin rupture L2
| | | | | | | Fin rupture L3
| | | | | | Fin rupture L4
| | | | | Fin rupture L5
| | | | Fin rupture L6
| | | Fin rupture L7
| | Fin rupture L8
| Fin rupture L9
Fin de programme
KLIST Edition
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SRFRSTPG
SRBEG_L9
SRBEG_L8
SRBEG_L7
SRBEG_L6
SRBEG_L5
SRBEG_L4
SRBEG_L3
SRBEG_L2
SRBEG_L1
SRDETAIL
SREND_L1
SREND_L2
SREND_L3
SREND_L4
SREND_L5
SREND_L6
SREND_L7
SREND_L8
SREND_L9
SRENDPGM_F
SRKLIST
==================================================
Retenir : Différence entre un PRTF et un DSPF :
Le fichier PRTF est un fichier d’impression qui ressemble à un DSPF avec les
particularités suivantes :
-) Le numéro de ligne est facultatif. Le passage à la ligne suivante s’effectue
lorsque le mot clé SPACEB(n) est rencontré, le passage à la page suivante
lorsque le mot clé SKIPB(n) est rencontré, lors de l’écriture du format, n étant
un nombre compris entre 1 à 9. (Saut de 1 à 9 lignes avant l’écriture).
-) L’écriture des lignes s’effectue séquentiellement jusqu’à atteindre la valeur
de l’overflow déduction faite du nbre lignes / pied édition.
Saut de page au niveau du générateur :
Le mot clé SKIPB(1) saut de page est présent dans un seul format du PRTF :
A
A
R WSKIPB1
SKIPB(1)
Lorsque ce format est écrit, une page est sautée.
48
49
CHAPITRE II Personnaliser les programmes
II.6 )
Editions :
Ecritures ENTETE différées :
L’écriture ENTETE est retardée au tout dernier moment et est effectuée lors de
l’écriture de la ligne détail. Ainsi, une rupture d’ overflow ne peut pas se
cumuler avec une rupture où il y a un saut de page. En effet, l’indicateur
Wnew=saut de page peut être mis plusieurs fois à *ON, avec dans tous les cas
un seul saut de page au tout dernier moment. Pour les mêmes raisons, les
écritures ENTETE sont différées au tout dernier moment : WW_BL1=*ON mis
à *ON une ou plusieurs fois.
C* Début L1 Code Pays
C
SRBEG_L1
BEGSR
C*
C*
CLIPAYS Pays
C
MOVEL(p) C1PAYS
C3CODPAYS
C
*NOKEY
CLEAR
*ALL
CLIPAYSR
C
CLIPAYS001
CHAIN
CLIPAYSR
C*
C* Nouvelle page pour saut de page indirect
C
EVAL
WNew = *ON
C*
C* Ecriture indirecte format PRTF C1PAYS Code Pays
C
EVAL
WW_BL1 = *ON
C
ENDSR
==================================================
INFDS et l’overflow :
F*
Fichier PRTF :
FPRTPGMEDITO
E
F
……………………………………………..
DDS_Printer
D WRows
D WColimns
D WOverFlow
D WCurLine
D WCurPage
D*
PRINTER
INFDS(DS_Printer)
DS
152
154
188
367
369
153B
155B
189B
368B
372B
0
0
0
0
0
L’INFDS du PRTF DS_Printer permet de récupérer la ligne courante, la page
courante, la position exacte de l’impression mais aussi l’Overflow.
La valeur de l’Overflow peut être changée par un CHGPRTF. Ceci étant, le
CHGPRTF est fortement déconseillé : en cas de recompilation du PRTF, toutes
les paramètres modifiés sont perdus. En cas de modification des valeurs par
défaut du PRTF, il convient de créer un CL en amont avec une commande
OVRPRTF suivi de l’appel du programme d’édition.
49
50
CHAPITRE II Personnaliser les programmes
II.6 )
COLHDG : Nos générateurs reprennent les COHLDG des PF et LF en tant que sous-titres.
Très souvent les COLHDG n’ont pas été saisis avec soin lors de la création
initiale du fichier PF.
Comment modifier les COLHDG d’un source DDS sans recompiler les PF et
les LF ? Procéder comme suit :
1°) Modifier le membre source du PF (ou le répertoire) en ne modifiant que
COLHDG et le texte. Conseil : mettre un ou deux niveaux de sous-titre en
faisant bien attention à la longueur du champ. Le sous-titre ne doit pas trop
dépasser cette longueur. Ne pas oublier que les COLHDG seront utilisés
également par les QRY.
A
A
A
A
A
A
A
A
A
R EXCLIENTR
C1KCLI
C1RAISON
C1ADR1
C1ADR2
C1ADR3
C1CODPOS
C1VILLE
C1PAYS
6
32
32
32
32
5
26
3
0
COLHDG('Clé' 'Client')
COLHDG('Raison' 'Sociale')
COLHDG('Adresse' 'lgn 1')
COLHDG('Adresse' 'lgn 2')
COLHDG('Adresse' 'lgn 3')
COLHDG('Code' 'Postal')
COLHDG('Ville')
COLHDG('Clé' 'Pays')
2°) Lancer la commande CHGPF en précisant l’emplacement du fichier source
et du membre source.
CHGPF FILE(ARCHIPES/EXLIENT)
SRCFILE(TSTLIBSRC/QDDSSRC)
Les COLHDG seront pris en compte pour l’objet *file PF. Il sera également
modifié pour tous les LF dépendants qui partagent le même format que le
fichier physique.
50