Cette évolution est apportée par la PTF SI51094 (il faut aussi la SF99701 level 26 pour le SQLRPGLE)
Cette mise à jour apporte un format libre complet : plus de spécifications H, F, D et P.
Plus besoin de /free /end-free, les colonnes 6 et 7 à blanc suffisent.
on peut mixer (est-ce une bonne pratique ?) :
read fichier; C MOVEA *ALL'0' *IN exfmt ecran; IF *in03; ..... |
Donc les colonnes 6 et 7, sont encore réservées :
Le type de source reste RPGLE ou SQLRPGLE
Avec la TR3 et SI58137 (7.2) ou SI58136 (7.1) vous pouvez maintenant
ctl-opt OPTION(*NODEBUGIO : *SRCSTMT) ALWNULL(*USRCTL) ; |
ctl-opt OPTION(*NODEBUGIO : *SRCSTMT) |
DCL-F FICHIER1 KEYED ; // Fichier BdeD en lecture par clé |
// associe à un fichier avec INDARA, une DS contenant des variables // indicateurs (IND).Cette DS est utilisée A LA PLACE de *IN DCL-F ECRAN WORKSTN INDDS(indic); DCL-DS Indic LEN(99); sortie ind pos(3); retour ind pos(12); sflclr ind pos(40); END-DS; //en code : if not sortie; sflcrl = *ON; ... |
Type | remarque | équivalent D | paramètres |
BINDEC | binaire "décimal" | B | Bindec(lg [:décimales]) |
CHAR | alphanumérique | A | Char(lg, max 16 Mo) |
DATE | date | D | Date(format [séparateur]) |
FLOAT | notation scientifique | F | Float(lg) |
GRAPH | DBCS | G | Graph(lg) |
IND | Indicateur | N | |
INT | vrai Binaire (compatible C et API) |
I | Int(lg -> 3 ,5 10 ou 20) |
OBJECT | pour Java ( JNI ) | O | Object(*JAVA : classe) |
PACKED | numérique packé | P | Packed(lg, max 30[:décimales]) |
POINTER | pointeur | * | [*PROC] |
TIME | heure | T | Time(format [:séparateur]) |
TIMESTAMP | horodatage | Z | |
UCS2 | Unicode | C | UCS2(lg) |
UNS | binaire non signé | U | Uns(lg) |
VARCHAR | Alphanumérique à taille variable | A + VARYING | Varchar(lg) |
VARGRAPH | DBCS à taille variable | G + VARYING | Vargraph(lg) |
VARUCS2 | Unicode à taille variable | C + VARYING | Varucs2(lg) |
ZONED | Numérique étendu | S | Zoned(lg[:décimales]) |
DCL-S compteur INT(5); DCL-S flag IND; DCL-S message CHAR(30); |
2 possibilités pour les déclarer DIM(*AUTO:nbmax) ou DIM(*VAR:nbmax)
DIM(*AUTO:nbmax)
nbmax postes au maximum (ici nbmax)
La dimension du tableau s'incrémente au fur et à mesure des affectations dans les postes par nom-tableau(*NEXT)
Il est possible de définir explicitement le nombre de postes avec la BIF %elem(nombre de postes)
DIM(*VAR:nbmax)
nbmax postes au maximum (ici nbmax)
La dimension doit être définie explicitement par la BIF %elem(nombre de postes) pour pouvoir affecter des valeurs dans les postes
Restrictions sur les tableaux à dimension variable
- Ne peut être que pour un tableau autonome, ou un tableau de structure de données (mais pas sur une sous-zone)
- Ne peut pas être utilisé dans des calculs sous forme fixe
- Ne peut pas être importé ou exporté
- Ne peut pas être passé en paramètre à une procédure ou un programme prototypé
- En effet cette fonctionnalité est basée sur des pointeurs, si la taille du tableau augmente, le pointeur change de place
- Il faudra le dimensionner à la plus grande taille, puis le passer avec OPTIONS(*VARSIZE) avec en plus le paramètre du nombre d'occurences
- Ne peut pas être compatible avec les valeurs NULL (mot-clé NULLIND)
- N'est pas utilisable en spécif I/O
- Le mot-clé FROMFILE ne peut pas être utilisé
Ancienne version | nouvelle version |
DCL-S DATCMD DATE NULLIND; |
DCL-S DATCMD DATE NULLIND(DATCMD_VIDE); |
DCL-S DATPOSSIBLE DATE DIM(10) NULLIND(DAT_VIDE); |
DCL-DS Clients QUALIFIED; id INT(10); nom VARCHAR(50); ville VARCHAR(50); cdes LIKEDS(cde_template) DIM(100); nbcdes INT(10); END-DS Clients; |
DCL-DS nom-de-ds EXT EXTNAME('MAREFERENCE') END-DS;
DCL-DS nom-de-ds LIKEDS(autreds) ;
remarquez qu'il n'y a pas de END-DS avec LIKEDS et LIKEREC.
Comparaison de deux membres sources appelant l'Api: QzipZip, le pgm se nomme QZIP
Dpath_fmt DS TEMPLATE qualified D CCSID 10I 0 inz D pays 2 inz(*ALLx'00') D langage 3 inz(*ALLx'00') D reserve1 3 inz(*ALLx'00') D typ_indicateur 10I 0 inz(0) D path_len 10I 0 D path_delimiter 2 inz('/') D reserve2 10 inz(*ALLx'00') D path_name 1024
D chemin_in DS likeds(path_fmt) inz(*LIKEDS) D chemin_out DS likeds(path_fmt) inz(*LIKEDS)
DZipoption DS qualified D verbose 10 inz('*NONE') D subtree 6 inz('*ALL') D comment 512 D comment_lg 10U 0
DerrcodeDS ds qualified d tailleDS 10i 0 inz(0) d taille 10i 0 d msgID 7 d reserve 1 d errdta 50
D QZIPZIP PR EXTPROC('QzipZip') D chemin_inp likeds(path_fmt) D chemin_outp likeds(path_fmt) D format 8 const D optionp likeds(zipoption) D error likeds(errcodeds)* paramètres en entrée DQZIP PI EXTPGM('QZIP') D chemin 32 D result 32
/free chemin_in.path_name = chemin; chemin_in.path_len = %len(%trimr(chemin)); chemin_out.path_name = result; chemin_out.path_len = %len(%trimr(result)); zipoption.comment = 'Zipé par 5770SS1 , V7'; zipoption.comment_lg = %len(%trimr(zipoption.comment));Qzipzip(chemin_in : chemin_out : 'ZIP00100' : zipoption : errcodeds);*inLR = *on; /end-free Dcl-Ds path_fmt TEMPLATE qualified; CCSID Int(10) inz; pays Char(2) inz(*ALLx'00'); langage Char(3) inz(*ALLx'00'); reserve1 Char(3) inz(*ALLx'00'); typ_indicateur Int(10) inz(0); path_len Int(10); path_delimiter Char(2) inz('/'); reserve2 Char(10) inz(*ALLx'00'); path_name Char(1024); End-Ds;
Dcl-Ds chemin_in likeds(path_fmt) inz(*LIKEDS); Dcl-Ds chemin_out likeds(path_fmt) inz(*LIKEDS);
Dcl-Ds Zipoption qualified; verbose Char(10) inz('*NONE'); subtree Char(6) inz('*ALL'); comment Char(512); comment_lg Uns(10); End-Ds;Dcl-Ds errcodeDS qualified; tailleDS Int(10) inz(0); taille Int(10); msgID Char(7); reserve Char(1); errdta Char(50); End-Ds;Dcl-Pr QZIPZIP EXTPROC('QzipZip'); chemin_inp likeds(path_fmt); chemin_outp likeds(path_fmt); format Char(8) const; optionp likeds(zipoption); error likeds(errcodeds); End-Pr;// paramètres en entrée Dcl-Pi QZIP EXTPGM('QZIP'); chemin Char(32); result Char(32); End-Pi;
chemin_in.path_name = chemin; chemin_in.path_len = %len(%trimr(chemin)); chemin_out.path_name = result; chemin_out.path_len = %len(%trimr(result)); zipoption.comment = 'Zipé par 5770SS1 , V7'; zipoption.comment_lg = %len(%trimr(zipoption.comment));Qzipzip(chemin_in : chemin_out : 'ZIP00100' : zipoption : errcodeds);*inLR = *on;
- DCL-SUBF quand la sous-zone porte le même nom qu'une instruction RPG (Select par exemple)
- Les mots-clés sont en partie les mêmes que sur la spécif D, excepté :
- OVERLAY où il n'est plus admis de faire référence à la DS, utiliser POS à la place
// exemple INFDS DCL-F fichier DISK(*EXT) INFDS(fichierInfo); DCL-DS fichierInfo; status *STATUS; opcode *OPCODE; msgid CHAR(7) POS(46); END-DS; DCL-F ecran WORKSTN; |
Les déclarations de fichiers et de variables peuvent être mélangées !
DCL-DS client; |
Peut la recouvrir même si elle est plus longue, ce qui est impossible avec OVERLAY
DCL-DS CLIENT QUALIFIED; |
DCL-DS CLIENT EXT EXTNAME(CLIENTP1) END-DS; |
DCL-DS client qualified; |
DCL-DS DSmodele QUALIFIED TEMPLATE; |
DCL-DS article QUALIFIED DIM(20); |
dcl-ds ds_dep TEMPLATE; |
|
Spécifs C en format libre
il s'agit de ligne blanches (sans la lettre C en colonne 6)
situées entre /free et /end-free (colonne 7, devenue faculative en V7)
l'instruction peut être éclatée sur plusieurs lignes (sans caractère + )
la fin de CHAQUE instruction étant marquée par " ; "
/free test(E) date ; // commentaire if not %error ; date = date + %DAYS(1) ; nbjours = %DIFF(date : undimanche : *DAYS); joursemaine = %rem(nbjours : 7); if joursemaine < 1; joursemaine = joursemaine + 1; endif; *inlr = *on; endif; return; /end-free
syntaxe générale du code opération EVAL
il s'agit d'un ordre d'affectation (idem à CHGVAR en CL)
eval resultat = expression
evalr (cadrage à droite)eval(H) permet de calculer un arrondi, c'est même la seule possibilité
eval(M) permet une précision maximum
eval(R) permet un arrondi à chaque étape intermédiaire
à noter la forme suivante
eval *in40 = (qte > 0)
qui demande à ce que *in40 recoive le résultat du test QTE > 0
(40 = *on si qte plus grand que zéro)
pour les ordres EVAL et CALLP, l'ordre est facultatif.
ttc = ht + tva ;
sauf EVAL-CORR (V5R40) qui copie d'une structure à l'autre toutes les
zones de même nom, ayant un format compatible.
syntaxe des codes de test (IF, DOU, DOW, WHEN et FOR)
if a > B;
dou a = 0 or x <> Y;
dow not sortie;
FOR indice [= val. de départ]
[BY incrément]
[TO val. maxi | DOWNTO val. mini]
...
ENDFOR;
valeur de départ et incrément sont par défaut de 1.
valeur limite est par défaut *HIVAL
comme avec le DO, des indicateurs peuvent être utilisés :
un indicateur sur l'ordre FOR contitionne l'ensemble du traitement
un indicateur sur le ENDFOR conditionne la REPETITION (comme DO)
etc ...
Expressions :
• chaînes de caractères:
+ = concatenation entre deux chaînes
• variables numériques
+ , - , * , / = addition , soustraction, multiplication , division
** = élévation à la puissance+= ou -= pour ajouter ou soustraire à la valeur
• tests logiques
= , >= , > , <= , < , <> (EQ, GE, GT, LE, LT, NE)
AND , OR , NOT, (, ) (et, ou, non)
un indicateur représente déja un test logique
Pour les ordres acceptés en format libre la règle est la suivante :
ordre(option) [facteur1] facteur2 ;
[ CHAIN nocli clientf1 ]
[ READ(N) clientf1 ]
les ordres invalides en format libre on été substitués soit par une fonction intégrée (souvent nouvelle en V5R10) ,
soit sont considérés comme des ordres devenus obsolètes avec le temps (GOTO, MOVE, SETON, BITOFF)
Prototypes/Interface de Procédures
-> L'ordre CALL n'existe plus en format libre
Il faut à la place déclarer le programme et ses paramètres, cela s'appelle un PROTOTYPE.
avant,
en spécif D, PR indique qu'il s'agit d'un prototype (même positions que DS) -> En free-form RPG, DCL-PR
DCL-PR QCMDEXC EXTPGM; cde CHAR(50) CONST; cdl PACKED(15 : 5) CONST; END-PR; |
Utilisation ensuite :
Qcmdexc(cmd : %len(cmd)) ;
Qcmdexc('WRKSPLF': 7) ;
- EXTPGM le nom du pgm externe (peut être qualifié)
si non précisé, il s'agit d'une procédure (au sens ILE), voir ci-dessous
- S'il s'agit d'une procédure de type fonction, indiquer le type retour sur la déclaration
DCL-PR DayOfWeek zoned(1); //retourne 1 à 7 datwrk DATE CONST; END-PR; |
DCL-PR MaFonction PACKED(5:0) END-PR; |
DCL-F infile_t TEMPLATE BLOCK(*YES) EXTDESC('FICHIER'); |
La réception des paramètres peut elle-même être réalisée sur le même principe, avec une interface de procédure
DCL-PI nom-de-procédure | *N [type de retour]
paramètre type mots-clés ;
END-PI [nom-de-procédure] ;
Depuis la V7R10, le prototype n'est plus obligatoire pour le programme en cours
- Pour un programme sans prototype (V7) DCL-PI *N; suffit (il faut SI57842[7.1], SI57858 [7.2] .)
DCL-PI *N;
param char(10); END-PI;
dsply param; *INLR = *ON;
- Sinon,
indiquer le nom du pgm en cours et EXTPGM
ou
un nom et EXTPGM(' le nom du pgm en cours')
- Comparaisons
- Le code suivant : S'écrit maintenant (FREE01) :
Dwp_date s D Dwp_jour s 1 0 Dundimanche s D inz(D'1980-01-06') Dnbjours s 6 0 c *entry plist c parm wp_date c parm wp_jour Dcl-S undimanche Date inz(D'1980-01-06'); Dcl-S nbjours Packed(6:0);
// Procedure interface (remplace *ENTRY PLIST) Dcl-Pi FREE01 ExtPgm; wp_date Date; wp_jour Packed(1:0); End-Pi; ou bien --> Dcl-S undimanche Date inz(D'1980-01-06'); Dcl-S nbjours Packed(6:0);
// Procedure interface (remplace *ENTRY PLIST) Dcl-Pi *N; wp_date Date; wp_jour Packed(1:0); End-Pi;
Exemple avec un pgm utilisé an tant que web service
![]()
- S'il n'y a pas de paramètre en entrée (fonction par exemple), indiquer END-PI sur la même ligne
// fonction, retourne un booléen
DCL-PI *N IND END-PI;
- *N fait référence à la procédure ou au programme en cours
// Pgm avec un paramètre en entrée
DCL-PI *N;
nom CHAR(10) CONST;
END-PI;
dsply ('bonjour ' + nom) ;
*INLR = *ON;
- Préciser EXTPGM pour un pgm sans cycle
CTL-OPT MAIN(Bonjour) ;
DCL-PROC Bonjour ;
DCL-PI *N EXTPGM;
nom CHAR(10) CONST;
END-PI;
dsply ('bonjour ' + nom) ;
END-PROC;
Enfin, un prototype peut faire référence à un programme externe ou à une procédure
Une procédure peut être comme un sous-programme ou externalisée dans un objet *SRVPGM
Elle possède ses propres variables (locales) et ses propres déclarations de fichier (DCL-F)
Dans ce dernier cas
- les entrées/sorties doivent être impérativement réalisées à l'aide de DS.
- les fichiers sont fermés automatiquement à la fin de la procédure,
sauf à utiliser STATIC, qui garde les fichiers ouverts.
Spécif P
Comparaisons
Un Sous/pgm (BEGSR) devient une procédure (DCL-PROC)
h nomain |
Ctl-Opt nomain; |
DCL-PR lecture CHAR(50); code INT(10) CONST; END-PR; |
DCL-F infile_t TEMPLATE BLOCK(*YES) EXTDESC('FICHIER'); |
DCL-PROC getCdeSuivante; DCL-PI *N IND EXTPROC(*DCLCASE); commandeDS LIKEDS(commande_t); END-PI; DCL-F cdes STATIC; READ cdes commandeDS; RETURN %eof(cdes); END-PROC getCdeSuivante; |
dcl-pr calechdate date; |
Les codes opération suivants NE peuvent PAS être saisie en format libre
ADD | ADDDUR | ALLOC | ANDxx | BITOFF | BITON |
CABxx | CALL | CALLB | CAS | CAT | CHECK |
CHECKR | COMP | DEFINE | DIV | DO | DOUxx |
DOWxx | END | EXTRCT | GOTO | IFxx | KFLD |
KLIST | LOOKUP | MHHZO | MHLZO | MLHZO | MLLZO |
MOVE | MOVEL | MULT | MVR | OCCUR | ORxx |
PARM | PLIST | REALLOC | SCAN | SETOFF | SETON |
SHTDN | SQRT | SUB | SUBDR | SUBST | TAG |
TESTB | TESTN | TESTZ | TIME | WHENxx | XFOOT |
XLATE | Z-ADD | Z-SUB |
Codes Opération en format libre
Code |
Exemple |
EVAL (evalr) |
eval(H) montant = (qte * prix) * (1 + (tva /100) ); |
IF | if *in30; |
DOU | Dou %EOF; |
DOW | Dow not *in03 and not *in12; |
SELECT |
SELECT ; |
FOR | FOR i = 1 to 15 ; ENDFOR; |
CALLP | callp QCMDEXC('wrksplf' : 7) // nécessite un prototype via DCL-PR, CALLP est facultatif ! |
----------- | format libre V5 |
ACQ | ACQ(E) device fichier; // lien entre un fichier DSPF/ICF et une unité (*DEVD) |
BEGSR/ ENDSR |
BEGSR toto; |
CHAIN | CHAIN(N) nocli clientf1 [uneds]; |
CLEAR | Clear *nokey clientf1; // remise à blanc de clientf1 sauf les clés |
CLOSE | Close clientp1; |
COMMIT | Commit; // validation de la dernière transaction |
DEALLOC | dealloc(N) ptr; //libère l'espace mémoire et affecte null à ptr |
DELETE | delete clientf1; |
DSPLY | dsply 'voulez-vous continuer ?' 'QSYSOPR' rep; |
EVAL-CORR |
eval-CORR DS1 = DS2; // toutes les zones de même nom sont copiées. |
ELSE | if a = B; |
ELSEIF | if a = B; |
EXCEPT | Except detail; // sortie (spécif O) immédiate, à éviter. |
EXFMT | Exfmt image [uneds]; |
EXSR | Exsr monsouspro; / exécute monsouspro |
FEOD | FEOD entcdep1 ; // force écriture physique dans entcdep1 |
FORCE | FORCE entcdep1 ; // force ce fichier a être lu au prochain cycle |
IN | IN *lock dataarea ; // lecture d'une data aréa (avec verrou) |
ITER | iter; // (saute un tour de boucle (dans un FOR par exemple) |
LEAVE | leave; // (sortie anticipée d'une boucle) |
LEAVESR | leavesr; // (sortie anticipée d'un sous programme) |
MONITOR | Monitor; // (démarre un groupe d'instructions sous contrôle) |
NEXT | next ecran nomfichier; // indique l'unité à lire la prochaine fois |
ON-ERROR | Monitor; |
ON-EXIT | on-exit flag; // traitement en fin de procédure |
OPEN | OPEN CLientp1; |
OUT | OUT dataarea; // mise à jour d'une data-area |
POST |
Post Ecran01; // met à jour l'INFDS d'Ecran01 |
READ/readp |
dow not %eof; |
READE/ |
READe nocde detdcep1 [uneds]; //lecture du suivant si la clé égale nocde. |
READC |
READC FE; // lecture séquentielle des lignes modifiés dans sous fichier FE. |
REL |
REL UNITE ; // le contraire de ACQ |
RESET |
RESET datastructure; // réattribue les valeurs initiales. [INZ( ).] |
RETURN |
return: // sortie anticipée d'un programme |
ROLBK | rolbk; // annulation de la dernière transaction |
SETLL/setgt |
SETLL nocli entcdef1; // se positionne sur la première commande |
SORTA |
Sorta tbldestva ;//(tri le tableau, avant la V7, il doit être déclaré ASCEND/DESCEND) |
SORTA (A | D) |
SORTA(D) clientDS(*).depart; //Depuis la V7, compatible avec DS qualifiées et le critère de tri peut être dynamique |
TEST(E |
test(ed) *ISO datechar; // test DATECHAR avant conversion. |
UNLOCK |
if *in12 ; |
UPDATE |
else ; |
WRITE |
write clientf1 [uneds]; // ajout d 'un nouveau client. |
XML-INTO |
xml-into DS1 %xml(data); // lecture XML et placement dans DS1. |
EXEC SQL |
EXEC SQL |
Options pour les codes opération
Code |
Exemple |
(H) | réalisation d'un arrondi lors de l'opération. |
(N) | lecture sans verrouillage. |
(M) | pour un calcul, travailler avec une précision maxi (un seul arrondi). |
(R) | pour un calcul, travailler avec la même précision que la variable |
(E) | Erreur gérée (pour tous les ordres avec indicateur en <<). |
(D | T | Z) | pour TEST (date, heure, horodatage). |
(A | D) | pour SORTA (V7R1), indique dynamiquement le critère de tri. |
Fonctions intégrées
Fonction(x) |
Retourne |
Exemple |
%ADDR | l'adresse d'une variable | EVAL ptr= %addr(data) |
%PADDR | l'adresse d'une procédure | |
%ELEM | donne le nombre d'occurrences d'un tableau ou d'une DS | if I < %elem(tbl_tva) |
%SUBST | extraction d'une chaîne de caractère | if %subst(raisoc : 1 : 1) <> ' ' |
%SIZE | donne la longueur déclarée d'une variable | if %SUBST(nom : %size(nom): 1) = *blank |
%DECPOS | donne le nombre de décimales | |
%TRIM | élimination des espaces d'extrémité | eval NP = %trim(nom) + ' ' + %trim(prenom) |
%TRIML|%TRIMR | élimination des blancs de gauche/de droite | |
%PARMS | indique le nombre de paramètres recus | if %parms > 2 |
%ABS | valeur absolue | |
%DEC %DECH |
transforme une suite de chiffres ou une date en numérique packé |
eval DATAMJ = %dec(DATCDE : *YMD) |
%INT %INTH |
transforme une valeur numérique
ou caractère au format binaire signé |
|
%UNS %UNSH |
transforme une valeur numérique
ou caractère au format binaire non signé |
|
%FLOAT |
transforme une valeur numérique ou caractère au format virgule flottante (scientifique) | |
%EDITFLT |
transforme de virgule flottante vers chaîne | |
%EDITC |
transforme du numérique en chaine avec
application d'un Edit code (comme EDTCDE DDS) |
eval msg = 'date de traitement' + |
%EDITW |
idem %EDITC mais avec un mot d'édition (EDTWRD) | |
%CHAR | transforme date ou numérique en chaîne | ZoneChar=%CHAR(ZoneDec) // 000123,45- ==> '-123,45' |
%STR | transforme une chaine RPG en chaîne compatible C (pointeur vers une chaine terminée par x'00' ) |
|
%LEN |
retourne la longueur d'une expression | if %len(%trim(nom)) > 2 eval L = %len(zone-variable) |
%SCAN |
recherche position d'une chaîne de caractères | eval chaine = 'ILE/RPG-IV' |
%REPLACE | remplace par une chaîne l'information située à la position indiquée | [var1 = 'AS/400'] |
%NULLIND |
test la valeur nulle sur un champ base de données | IF %NULLIND(datcmd) = *ON |
%OPEN |
indique si un fichier est ouvert | if %open(clients) |
%EOF |
indique si l'on est fin de fichier | dow not %eof(clients) |
%ERROR |
indique si on est en erreur (à utiliser suite à un code avec option (E).) |
if %error |
%STATUS |
indique le n° d'erreur (code status) | if %error and %status(clients) = 1252 |
%EQUAL |
indique un positionnement par égalité (SETLL) |
|
%FOUND |
indique un positionnement réalisé(SETLL,SETGT) un recherche aboutie (CHAIN) |
|
---- V4R40 ---- |
||
%GRAPH |
conversion en DBCS | |
%UCS2 |
conversion en UNICODE | |
%XFOOT |
somme d'un tableau | eval total = %xfoot(tb_salaire) + prime |
%DIV |
résultat de la division (entiers uniquement) | |
%REM |
reste de la division (entiers uniquement) | if %rem(an : 4 )= 0 |
---- V5R10 ---- |
||
%ALLOC | l'adresse d'un nouvel espace mémoire | EVAL prt= %alloc(nboctets) |
%CHECK | la position du premier caractère invalide (0 si tous sont OK) | Eval pos = %check('0123456789.' : variable) |
%CHECKR | Idem %CHECK, mais droite-> gauche. | |
%DATE | convertit une variable (alpha ou dec) en date ou, sans argument, retourne la date du jour. | eval datcmd = %DATE(datchar : *YMD0)//(zéro = pas de séparateur) |
%DAYS | indique un nombre de jours dans un calcul | eval datliv = datcmd + %DAYS(15) |
%DIFF | exprime un écart entre deux dates ou deux heures | eval ecart = %DIFF(datliv : datcmd : *DAYS) |
%SUBDT | extrait une partie d'une date | eval annee = %SUBDT(datliv : *YEARS) |
%HOURS | exprime un nombre d'heures dans un calcul | eval demain = maintenant + %hours(18) |
%LOOKUP |
indique si un élément est présent dans un tableau | eval pos = %lookup('$' : monnaies) |
%MINUTES | exprime un nombre de minutes dans un calcul | voir %HOURS() |
%MONTHS | exprime un nombre de mois dans un calcul | voir %DAYS() |
%MSECONDS | exprime un nombre de microsecondes dans un calcul |
voir %HOURS |
%OCCUR | positionne sur une occurrence de DS |
%OCCUR(DS1) = 7 ou x = %occur(DS2) |
%REALLOC | Réalloue un espace mémoire plus grand |
voir %ALLOC |
%SECONDS |
exprime un nombre de secondes dans un calcul | voir %HOURS() |
%SHTDN |
indique si le JOB ou le système est en phase d'arrêt | if %SHTDN |
%TIME |
convertit une variable (alpha ou dec) en heure ou, sans argument, retourne l'heure en cours. | if %time(pointage : *HMS) = T'23:59:59' |
%XLATE | transforme une variable aphanumérique | eval resultat = %XLATE('abcdef' : 'ABCDEF' : origine) |
%YEARS | exprime un nombre d'années dans un calcul | voir %DAYS |
---- V5R20 ---- |
||
%KDS | Utilisation d'une DS en tant que liste de clés sur un CHAIN. | CHAIN %KDS(dscli) clientf1; |
%FIELDS | Mise à jour d'une liste finie de zones lors d'un UPDATE . | Update clientf1 %FIELDS(nomcli : depcli : ville) ; |
%BITNOT | inverse les bits | %BITNOT(x'00') = x'FF' |
%BITOR | applique un OU logique bit à bit | %BITOR(x'F0' : x'0F') = x'FF' |
%BITAND | applique un ET logique bit à bit | %BITAND(x'F1' : x'1F') = x'11' |
%BITXOR | applique un OU exclusif bit à bit | %BITXOR(x'F1' : x'1F') = x'EE' [1110 1110) |
---- V5R30 ---- |
||
%SUBARR | une partie d'un tableau | resultat = %xfoot( %subarr(tbl : i : 5) )// 5 postes |
---- V5R40 ---- |
||
%XML | coordonnées des données XML à lire (cf XML-INTO) | xml-into DS1 %xml(data) // parse data pour placement dans DS1 |
---- V7R10 ---- |
||
%LOOKUP |
indique si un élément est présent dans une DS à dimension | pos = %lookup(44 : clientDS(*).depart ); |
%SCANRPL | recherche et remplace une chaîne | eval resultat = %SCANRPL('GAP' : 'RPG' : origine) |
%PARMNUM | retourne la position d'un paramètre | if %parms > %parmnum(nocli) // nocli transmis ? |
---- V7R30 ---- |
||
%SCANR |
comme %scan mais dans le sens droite vers gauche | eval chaine = 'ILE/RPG-IV' |
%MAX |
Retourne la plus grande valeur (TR2) | maxi = %max(priha: prirv: privente); |
%MIN |
Retourne la plus petite valeur (TR2) | datecheance = %min(datliv : datfac) + %days(60); |
%PROC |
Retourne le pgm ou la procédure en cours (TR3) | monpgm = %proc(); |
---- V7R40 ---- | ||
%ELEM | nombre d'occurrences d'un tableau ou d'une DS à taille variable admet un deuxième paramètre | Cible avec 1 seul paramètre: %ELEM(montableau) = Nouveau nombre de postes Cible avec 2 paramètres %ELEM(montableau:*ALLOC) = nombre de poste alloués %ELEM(montableau:*KEEP) = nombre de postes dont le contenu est conservé |
Source Nombre de postes alloués = %ELEM(montableau:*ALLOC) Nombre de postes max = %ELEM(montableau:*MAX) |
Proposition de remplacement des codes invalides en format libre
Code Opération |
Remplacement |
Exemple |
ADD | + | EVAL A = A +1 ou A = A+1 ou A+=1 |
ADDDUR | + | Datliv = datcmd + %DAYS(45) |
ALLOC | %alloc | |
ANDxx | (test en libre) | if A=B AND compteur<>0 |
CABxx | (à éviter) | |
CALL | CALLP + DCL-PR avec EXTPGM | CALLP pgmA (parm1 : parm2) |
CALLB | CALLP + DCL-PR avec EXTPROC | idem |
CASxx | IF + EXSR | |
CAT | + | Message = 'date de traitement' + DATCHAR |
CHECK | %check | pos = %check('0123456789-+,' : qtechar) |
CHECKR | %checkr | idem |
*LIKE DEFINE | déclaration DCL-S avec LIKE( ) | |
*DTAARA DEFINE | déclaration DCL-S avec DTAARA( ) | |
DIV | / | |
DO | FOR | FOR i = 1 to 50 |
DOUxx | DOU | Dou %eof |
DOWxx | DOW | Dow not %eof |
END | ENDxx (déjà recommandé avant) | |
ENDCS | cf CAS | |
EXTRCT | %subdt | mois = %SUBDT(DATCMD : *M) |
GOTO | c'est quoi ? ;-) | GOTO DEBUT -> ITER GOTO FIN -> LEAVE |
IFxx | IF | if GAP = 4 |
KFLD | %KDS ou directement (K1 :K2) | CHAIN (societe: nocli) clientf1 |
KLIST | (cf ci-dessus) | |
LOOKUP | %lookup | tva = %lookup(code : tbtva) |
MOVE | EVALR , Convertir avec les fonctions intégrées | datcmd = %DATE(datchar:*ISO) ou chaine = %char(datcmd) |
MOVEL | EVAL , idem pour les conversions | |
MOVEA | Définition d'une zone CHAR en recouvrement puis %SUBST |
DCL-S IND99_p POINTER INZ(%addr(*in)); DCL-S ind99 CHAR(99) BASED(IND99_p); MOVEA '010' *in(80) -> %SUBST(IND99 : 80 : 3) = '010'; |
MULT | * | |
MVR | %rem | if %rem(AN : 4) = 0 |
OCCUR | %occur | |
ORxx | cf ANDxx | |
PARM | DCL-PR | |
PLIST | cf PARM | |
REALLAOC | %realloac | |
SCAN | %scan | QUATRE = %scan('4' : 'RPG4') |
SETOFF | *inxx = *off; | |
SETON | *inxx = *on; | |
SUB | - | |
SUBDUR | - | HIER = AUJOURDHUI - %days(1) |
ou SUBDUR | %diff | UN = %DIFF(aujourdhui : hier:*Days) |
SUBST | %subst | |
TAG | cf GOTO | |
TESTN | %check | if %check('0123456789' : QTECHAR) > 0 |
TIME | %date() ou %time() | aujourdhui = %date() |
WHENxx | WHEN | |
XFOOT | %xfoot | TVA = %xfoot(tbmt) * TAUX |
XLATE | %xlate | GRAND = %xlate(minuscules: majuscules: PETIT) |
Z-ADD | EVAL | |
Z-SUB | EVAL - |
Sur une base vinicole, un producteur ayant un ou plusieurs vins, chaque vin est constitué de UN à QUATRE cépages
pgm de constitution d'un fichier infocentre, contenant le nbr de vins, le cépage le plus utilisé et le nbr de cépages différentsdéclarations
boucle principale
![]()
Pour chaque producteur (nbr de vins, encave (oui/non) ? )
s/pgm de mémorisation d'un des cépages de ce vin
Calcul du cépage le plus utilisé par ce producteur et du nombre de cépages différents
![]()
le même en FreeForm
boucle principale
Notez qu'en fin de producteur, il suffit de trier la DS de type tableau en décroissant
sur le nombre, pour que le poste 1 contienne le cépage le plus utilisé !
Pour chaque producteur (nbr de vins, encave (oui/non) ? )
Remarquez l'appe à la procédure plutôt qu'au s/pgm
procédure de mémorisation d'un des cépages de ce vin
Enfin, on peut faire le parallèle avec le CL qui lui-même a beaucoup évolué :
RPG CL Exemple Dow DOWHILE DOWHILE COND(&cpt *LT 100) ... ENDDODou DOUNTIL DOUNTIL COND(&cpt *EQ 100)
...
ENDDOFor DOFOR DOFOR VAR(&cpt) FROM(1) TO(22) BY(3) ... ENDDOLeave LEAVE Iter ITERATE Select/ When/
OtherSELECT
WHEN( )
OTHERWISE
ENDSELECT SELECT WHEN(&A = 0)
CALL PGMA WHEN(&A = 1)
CALL PGMB
OTHERWISE
CALL PGMZ ENDSELECTExsr CALLSUBSR CALLSUBR SUBR(TEST) RTNVAL(&RT)Begsr/Endsr SUBSR
ENDSUBR RETURN SUBR SUBR(TEST) .../... ENDSUBR RTNVAL(&rt)%Subst %SST CHGVAR VAR(&A) VALUE(%SST(&B 5 2)) /* caractères 5 et 6 */%Trim %TRIM 1 CHGVAR VAR(&A) VALUE(%TRIMR(&B '* ')) /* on enleve '*' */%Trimr %TRIMR 1 %Triml %TRIML 1 %Check %CHECK 2 CHGVAR VAR(&P) VALUE(%CHECK('123456789' &A) /* premier non chiffre */%Checkr %CHECKR 2 CHGVAR VAR(&D) VALUE(%CHECKR('123456789' &A) /* dernier */%Scan %SCAN 2 CHGVAR VAR(&P) VALUE(%SCAN(',' &A)) /* recherche position de ',' */%Char %CHAR 3 SNDPGMMSG MSG(%char(&nbr) *Bcat 'Objets modifiés')%Dec %DEC 3 %Int %INT 3 %Uint %UINT 3 %Xlate %LOWER
%UPPER 3 CHGVAR VAR(&MSG) VALUE(%lower(&MSG))%Len %LEN 3 CHGVAR VAR(&LG) VALUE(%len(&A *CAT &B))%Size %SIZE 3 CHGVAR VAR(&LG) VALUE(%size(&MSG))%parms %PARMS 4 IF cond(%parms *ge 2) then(...
notes, disponible depuis 7.1 et PTF : SI48166 1 ,SI49061 2 / 7.2 + SI519433 / 7.3 + SI67797.