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.