La spécif C en ILE/RPG-IV RPG ! RPG-IV ! signification ! commentaires ------!---------!--------------------!----------------------------------- ! ! ! 6 ! 6 ! C ! ! ! ! 7-8 ! 7-8 ! Niveau de contrôle ! Lx ! ! ou ! ! ! Continuation ! AN/OR ! ! ! 9-17 ! 9-11 ! Conditions ! Nxx (un seul indicateur !) ! ! ! ! ! ! Mais il est possible d'utiliser ! ! ! des lignes de continuation : ! ! ! ! ! ! N24 30 Z-ADD 0 RESULT ! ! ! devient ! ! ! N24 ! ! !AN 30 Z-ADD 0 RESULT ! ! ! |
18-27 ! 12-25 ! Facteur 1 ! les noms sont à 10, les tableaux ! ! ! indicés à 14 nomtableau(in) ! ! ! 28-32 ! 26-35 ! Code opération(O) ! Options possibles : ! ! ! (H) arrondi ! ! ! (N) Read with no lock ! ! ! (P) complémenté (padded) à blanc ! ! ! (D) manipulation d'une date ! ! ! (T) " d'une heure ! ! ! (Z) " d'un horodatage. ! ! ! (M|R) en V3R70 : idem EXPROPTS ! ! ! (E) en V4R20 : gestion des erreurs ! ! ! 33-42 ! 36-49 ! Facteur 2 ! Toujours 14 positions. ! ! ! 43-48 ! 50-63 ! zone résultat ! " " " . ! ! ! 49-51 ! 64-68 ! longueur ! Définition de la zone résultat 52 ! 69-70 ! nbr de décimales ! 53 -----------------------------> ! H,N,P : maintenant (O) 54-59 ! 71-76 ! indics résultants ! >><<== ------!---------!--------------------!-------------------------------------- |
les codes opération : IF, DOU/DOW, WHEN, FOR et EVAL utilisent une spécif C à facteur 2 étendu (invite SEU IPCX ) ! RPG-IV ! signification ! commentaires !---------!--------------------!----------------------------------- ! 6 ! C ! ! ! ! ! 7-8 ! Niveau de contrôle ! Lx ! ! ! ! 9-11 ! Condition ! Nxx ! ! ! ! 26-35 ! Code opération(O) ! Options : EVAL(H | M |R), CALLP(E) ! ! ! ! 36-80 ! Facteur 2 étendu ! expression en format libre !---------!--------------------!----------------------------------- Une expression peut occuper plusieurs lignes (sans marque de continuation) le format des lignes de continuation sera: ! RPG-IV ! signification ! commentaires !---------!--------------------!----------------------------------- ! 6 ! C ! ! 36-80 ! Facteur 2 étendu ! suite de l'expression. !---------!--------------------!----------------------------------- |
syntaxe générale du code opération EVAL il s'agit d'un ordre d'affectation (idem à CHGVAR en CL) eval resultat = expression (V4R40) evalr (cadrage à droite) syntaxe des codes de test (IF, DOU, DOW, WHEN et FOR) if a > B dou a = 0 or x <> Y etc ... à 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) |
Expressions : -> toute fonction valide (voir plus loin) -> chaînes de caractères: + = concatenation entre deux chaînes -> variables numériques + , - , * , / : addition , soustraction, multiplication , division ** : élévation à la puissance += , -= , *= , /= : V5R20: Calcul de la variable sur elle même. (cpt += 1 est identique à cpt = cpt + 1) -> tests logiques = , >= , > , <= , < , <> (EQ, GE, GT, LE, LT, NE) AND , OR , NOT, (, ) (et, ou, non) |
un indicateur représente déja un test logique C dow not *in03 C if *in12 and *in50 Les expressions occupants plusieurs lignes suivent les règles suivantes: Un caractère de continuation n'est obligatoire que lorsqu'une CONSTANTE est scindée sur deux lignes : (un "+" dans une phrase est ignoré) C eval msg = 'ceci est une constante vraiment très + C longue avec en + un caractère spécial' Une fonction peut occuper plusieurs lignes Dans ce cas, il est conseillé de ne pas scinder au milieu d'un mot. ces deux lignes ne sont pas comprises : C eval result = %subst(%trim(message):1:%size(variab C le)) ces deux lignes le sont, (et sont plus lisibles) : C eval result = %subst(%trim(message) : 1 : C %size(variable) ) |
en V4R4 l'ordre FOR vient remplacer la boucle DO FOR réalisation d'une boucle en faisant varier un indice 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) |
Quelques exemples : C if (codetarif = '1' or codetarif = '2') C and *in90 C ... C endif * factoriel C eval factoriel = 1 C FOR i = 1 to n C eval factoriel = factoriel * i C ENDFOR * recherche du dernier car. non blanc C FOR i = %len(raisoc) downto 1 C if %subst(raisoc : i : 1) <> ' ' C leave C endif C ENDFOR |
V5R10 : spécifs C en format libre il s'agit de lignes non colonnées (sans la lettre C en colonne 6) situées entre /free et /end-free (colonne 7 avant la 7.2) l'instruction peut être éclatée sur plusieurs lignes (sans caractère + ) la fin de CHAQUE instruction étant marquée par " ; " /free nocli = 100 ; // commentaire chain(N) nocli clients ; if not %found ; *in50 = *on ; else ; nomcourt = %subst(raisoc : 1 : 25) ; exfmt image2 ; endif ; *inlr = *on; /end-free |
remarques : les colonnes 6 et 7 DOIVENT être à blanc si vous copiez une partie de source (/COPY ou /INCLUDE) le source copié est supposé contenir des spécif C en format fixe. si ce n'est pas le cas le source copié doit contenir lui-même /free et /end-free avant la 7.2. le niveau de contrôle (cycle GAP) n'est pas accessible en format libre -soit vous codez une spécif C en format fixe, puis vos spécif C en format libre (tout action doit être conditionnée par IF *inlx ...) -soit vous renvoyez à un sous-programme par une spécif C totale et vous écrivez le sous programme en format libre les noms de champs peuvent dépasser 14 caractères en format libre. en V5R40, les ordres SQL peuvent aussi etre indiqués en format libre s'ils sont placés derrière exec sql et s'ils sont terminés par ; |
pour les ordres EVAL et CALLP, l'ordre lui même est facultatif. [ttc = ht + tva ; ] sauf EVAL-CORR (V5R40) qui copie d'une structure à l'autre toutes les zones de meme nom, ayant un format compatible. pour les autres 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 par une fonction intégrée (souvent nouvelle en V5R10) , soit sont considérés comme des ordres devenus obsolètes avec le temps (MOVE, SETON, BITOFF) voici la liste des fonctions intégrée au RPG : |
Fonctions reconnues dès la V3R10 : fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ %ADDR ! variable ! pointeur ! adresse de la variable ! ! ! %PADDR ! procédure ! proc-pointeur ! utilisable par CALLB ! ! ! %ELEM ! Tableau ! numérique ! nombre de postes !DS à occurences! ! nombre d'occurences ! ! ! %SIZE ! variable ! numérique ! taille de la variable ! tableau ! ! taille d'un poste ! tableau:*ALL ! ! taille du tableau ! ! ! %SUBST ! (var:deb:lg) ! chaîne ! extrait une chaîne ! .......................................................... ! : if %subst(raisoc : 1 : 1) <> ' ' |1er car. : ! : | : ! : if %subst(raisoc : %size(raisoc) : 1) <> ' '|dernier : ! : | : ! : eval %subst(pgm : 1 : 1) = 'Q' | : ! :.......................................................>: |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ %TRIM ! chaîne[:car] ! chaîne ! supprime les blancs extrèmes ! ! ! (le caractère supprimé peut ! ! ! être indiqué depuis la V5R3) ! ! ! %TRIML ! chaîne[:car] ! chaîne ! supprime les blancs de gauche ! ! ! %TRIMR ! chaîne[:car] ! chaîne ! supprime les blancs de droite ! ! ! %PARMS ! (aucun) ! numérique ! nombre de paramètres recus. ! ! ! ! ............................. ! : if %parms > 2 : ! : eval wp3 = p3 : ! :...........................: ! ! ! Fonctions V3R70 : ! %ABS ! variable ! numérique ! valeur absolue ! ! ! %DEC ! num : precis.! packé ! précision indiquée en %DECH !(Char en V5.2) ! ! argument (%DECH = arrondi) |
%DEC(d:*f) !(date en V5.3) ! ! le format souhaité est alors ! ! ! indiqué en 2eme position ! ! ! %DECPOS ! numérique ! numérique ! nombre de décimales ! ! ! %EDITC ! num : editcod! chaîne ! retourne le chiffre édité ! ........................................................ ! : exemple : eval msg = 'date de traitement' + : ! : %editc(date : 'Y') : ! : : ! : eval montanchar = %editc( : ! : qte * prix : '3'): ! :......................................................: ! ! ! %EDITFLT ! scientifique ! chaîne ! retourne le chiffre édité ! ! ! %EDITW ! num : editword! chaîne ! retourne le chiffre édité ! ! ! (mais avec un mot d'édition) ! ! ! %FLOAT ! numérique ! scientifique ! conversion ! (Char en V5.2)! ! ! ! ! |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ ! ! ! %INT ! numérique ! binaire ! conversion %INTH ! (Char en V5.2)! signé ! (%INTH = arrondi) ! ! ! %UNS ! numérique ! binaire ! conversion %UNSH ! (Char en V5.2)! non signé ! (%UNSH = arrondi) ! ! ! %LEN ! expression ! numérique ! longueur ! ! ! %STR ! pointeur ! chaîne ! gestion des chaînes à ! ! ! terminaison 0 (langage C) ! ! ! %SCAN !ch1:ch2 [:dep] ! numérique ! recherche si ch1 est dans ch2 ! !(position ou 0)! à partir de 'dep' ! ........................................................... ! : exemple : chaine = 'ILE/RPG-IV' : ! : pos = %scan('I' : chaine) // pos=1 : ! : deb = pos + 1 : ! : pos = %scan('I' : chaine: deb) // pos=9 : ! :.........................................................: |
! ! ! fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ %NULLIND ! variable ! booléen ! test ou assignation de la ! ! (*ON ou *OFF) ! valeur nulle. en effet RPG-IV supporte les variables à valeur nulle (ALWNULL en SDD), si vous compilez avec ALWNULL(*USRCTL) en spécification H. les tests se font sous la forme IF %NULLIND(datcmd) = *ON l'affectation : EVAL %NULLIND(PRIME) = *ON ou bien EVAL %NULLIND(prime) = *OFF puis EVAL prime = 1500 |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ ! ! Fonctions V4R20 : ! ! %CHAR ! date|heure ! char ! conversion en caractère ! horodatage ! ! ! ! ! %REPLACE ! ch1:ch2:d [:l]! char ! remplace par ch1 la chaîne ! ! ! se trouvant en position D ! ! ! [sur l caractères] dans ch2. !.............................................................. !: eval x = %scan('4':var1) [var1 = 'AS/400'] : !: : !: eval var2 = %replace('5':var1:x) [var2 = 'AS/500'] : !:ou : !: eval var2 = %replace('5':var1:%scan('4':var1) ) : !: : !:et encore : !: eval var2 = %replace('X':var1: 1 : 3) [var2 = 'X500'] : !: : !:le X vient remplacer TROIS caractères en position 1 : !:............................................................: |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ ! ! ! %OPEN ! nom-fichier ! booléen ! '1' si le fichier est ouvert ! ! ! %EOF ! nom-fichier ! booléen ! '1' si on est en fin (EOF) ! ! ! %STATUS ! nom-fichier ! numérique ! dernier code status ou 0. ! ! ! %EQUAL ! nom-fichier ! booléen ! '1' si SETLL est positionné ! ! ! ! nom-tableau ! booléen ! '1' si LOOKUP a trouvé ! ! ! %ERROR ! ! booléen ! indique une erreur ! ! ! ............................................................... : %ERROR et extension (E) , vous pouvez sur tous les ordres : : acceptant (ou qui acceptaient, pour le format libre) : : un indicateur d'erreur (<<) l'extension (E) pour tester : : ensuite if %error : :.............................................................: |
! ! ! %FOUND ! nom-de-zone ! booléen ! '1' si dernier CHECK,CHECKR ! ! ! ou SCAN a trouvé qq chose. ! ! ! %FOUND ! nom-fichier ! booléen ! '1' si dernière E/S a trouvé ! ! ! (SETLL,SETGT,CHAIN,DELETE) ! ! ! Exemples : vous remarquerez que les indicateurs ne sont pas indiqués sur la ligne du CHAIN en spécif C,ils sont forcément absents en format libre. 1. C code chain ARTICLE C IF %FOUND C .... C ENDIF 2. /free CHAIN code ARTICLE CHAIN code ENTETCDE IF not %FOUND(ARTICLE) and %FOUND(ENTETCDE); .... ENDIF; |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ Fonctions V4R40 : %GRAPH ! variable:ccsid! variable ! conversion en DBCS ! ! ! %UCS2 ! variable:ccsid! variable ! conversion en UNICODE ! ! ! %XFOOT ! nom-tableau ! numérique ! fait la somme des éléments ! ! ! %DIV ! entier:entier ! entier ! fait la division ! ! ! %REM ! entier:entier ! entier ! retourne le reste (division) Fonctions V5R10 : %CHECK !'ok':var[:deb] ! position ! position du 1er car. invalide ! ..................................................... ! : invalide = %CHECK('0123456789' : qte); : ! :...................................................: ! ! ! %CHECKR !'ok':var[:deb] ! position ! idem %CHECK ,droite->gauche ! ! ! |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ %LOOKUP ! arg:tableau ! numérique ! retrouve la position de ARG ![:D [:maxi] ] ! ! dans tableau à partir de D ! ! ! (en examinant MAXI postes) ! ........................................................... ! : : ! : if %lookup(devise : tblmoney) > 0 ; : ! : montant = prix * tbltaux( %lookup(devise:tblmoney)); : ! :.........................................................: ! ! ! %LOOKUPxx ! idem %LOOKUP ! numérique ! recherche dans un tableau ! ! ! autre que par égalité ! ! ! (xx : GE, GT, LE, LT) ! ! ! %TLOOKUP ! arg:table ! booléen ! recherche dans une table,GAPII ![table alternée ] ! ! ! ! %TLOOKUPxx ! idem %TLOOKUP ! booléen ! idem %TLOOKUP, mais recherche ! ! ! autre que par égalité ! ! ! (xx : GE, GT, LE, LT) ! ! ! |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ %XLATE ! de:a:ch [:d] ! chaîne ! remplace dans CH à partir de D ! ! ! tous les caractères présents ! ! ! dans DE par le même dans A ! ! ............................................. ! ! : // remplace ä par a, ü par u, etc.. : ! ! : libart = %XLATE('äüïë' : 'auie' : libart) : ! ! : : ! ! :...........................................: ! ! ! %OCCURS ! datastructure ! (position) ! manipulation d'occurences(DS) ! ! ! ............................. ! ! ! : %OCCURS(ds1) = x : ! ! ! :OU : ! ! ! : n = %OCCURS(ds1) : ! ! ! :...........................: ! ! ! %SHTDN ! ! indicateur ! indique si le pgm est en cours ! ! ! d'arrêt (ENDJOB *CNTRLD) ! ! ! %SQRT ! numérique ! numérique ! racine carrée. |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ %DAYS ! numérique ! durée ! exprime un nombre de jours ! ! ! %MONTHS ! numérique ! durée ! exprime un nombre de mois ! ! ! %YEARS ! numérique ! durée ! " " " d'années ! ! ! %HOURS ! numérique ! durée ! " " " d'heures ! ! ! %MINUTES ! numérique ! durée ! " " " de minutes ! ! ! %SECONDS ! numérique ! durée ! " " " de secondes ! ! ! %MSECONDS ! numérique ! durée ! " " " de micro.s ! ! ! %DATE ! zone :*format ! DATE ! convertit en DATE une zone ! ! ! numérique ou chaine ! ! ! (rien = aujourd'hui) ! ! ! ! ! ! format:*YMD[*DMY|*MDY ! ! ! *ISO|*EUR|*USA|*JIS |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ %TIMESTAMP ! zone ! horodatage ! convertit en HORODATAGE une ! ! ! zone ou retourne maintenant. ! ! ! ! ! ! le format doit être : ! ! ! YYYY-MM-DD.hh.mm.ss.mmmmmm ! ! ! %TIME ! zone :*format ! heure ! convertit en HEURE une zone ! ! ! (num. ou chaine) ou maintenant ! ! ! ! ! ! format:*HMS|*EUR|*USA ! ! ! ! ! ! %DIFF ! date1:date2:*D! numérique ! calcul l'écart entre deux ! ! ! dates(ou heures) ! ! ! %SUBDT ! date1: *D ! numérique ! extrait une partie d'une date ! ! ! ! ! ! *D représente un code/durée ! ! ! [*Y|*M|*D, *H|*Mn|S|*MS] ! ! ! |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ ! ! ! %ALLOC ! nb d'octets ! pointeur ! allocation mémoire ! ! ! %REALLOC ! ptr : nb ! pointeur ! réallocation mémoire, les ! ! ! données de ptr sont copiées. ! ! ! Fonctions V5R20 : ! ! ! ! ! %BITNOT() ! chaîne ! chaîne ! inverse les bits ! ! ! %BITNOT(x'00') = x'FF' ! ! ! %BITOR() ! chaîne ! chaîne ! OU logique bit à bit ! ! ! %BITOR(x'F0' : x'0F') =x'FF' ! ! ! %BITAND() ! chaîne ! chaîne ! ET logique bit à bit ! ! ! %BITAND(x'F1' : x'1F')=x'11' ! ! ! %BITXOR() ! chaîne ! chaîne ! XOR (ou exclusif) bit à bit ! ! ! %BITXOR(x'F1' : x'1F')=x'EE' ! ! ! |
fonction ! argument ! type retour ! signification -----------!---------------!---------------!------------------------------ %KDS( ) ! nom de DS ! liste de clés ! Utilise une DS comme liste ! ! ! de clés pour un CHAIN,... ! ! ............................................. ! ! : chain %kds(nom-ds) fmt ; : ! ! : // équivalent à : : ! ! : chain (zone1:zone3) fmt; : ! ! :...........................................: %FIELDS() ! liste de ! ! mise à jour partielle : ! zones ! ! UPDATE fmt %FIELDS(TEL: FAX) ! ! ! Fonctions V5R30 : ! ! ! ! ! %SUBARR() ! tableau:d:nbr! tableau ! retourne un extrait de tableau ! ! ! à partir de D sur nbr postes ! ! ............................................. ! ! : // ne traiter que les 5 premiers postes : ! ! : resultat = %xfoot( %subarr(tbl:i:5) ) : ! ! ............................................. ! ! ! ------------!---------------!---------------!------------------------------ |
fonction ! argument ! type retour ! signification ------------!---------------!---------------!------------------------------ Fonctions V5R40 : ! ! ! ! ! %XML( ) ! flux XML ! DS avec ! lit le flux XML (zone ou ! ! XML_INTO ! fichier) et le "parse" ! ! ! %HANDLER( )! procédure ! ! définit une procédure (ILE) ! ! ! à appeler pour traiter le XML ! ! ! Fonction V7R10 : ! ! ! ! ! %SCANRPL() !chaîne1:chaîne2! chaîne ! remplace chaîne1 par chaîne2 La plupart des fonctions peuvent être utilisées directement dans des tests : ________________________________________________________________________ | if %subst(nom : %size(nom) : 1) <> ' ' | si le dernier car. est non blanc | if %len(%trim(raisoc)) > 1 | s'il y a plus d'un caractère | if %rem(%subdt(date:*Y) : 4) = 0 | si l'année est divisible par 4 |
Exemple : remplace dans un fichier source "origine" par "remplacement" : FQtxtsrc UF E Disk RENAME(qtxtsrc : srcf) D origine s 20 D remplacement s like(origine) D position S 5I 0 D debut S like(position) D trouve s n c *entry plist c parm origine c parm remplacement c read srcf c dow not %eof c exsr traitement c read srcf c enddo c eval *inlr = *on |
C traitement begsr C eval debut = 1 C eval trouve = *off C dou position = 0 or debut > %size(srcdta) C eval position = %scan(%trim(origine) : C srcdta : debut ) C if position >0 C eval trouve = *on C eval srcdta = %replace(%trim(remplacement) : C srcdta : position : C %len(%trim(origine))) C eval debut = position + C %len(%trim(remplacement)) C endif enddo C C if trouve C update srcf C endif C endsr |
OU /free begsr traitement ; debut = 1; trouve = *off; dou (position = 0 or debut > %size(srcdta) ); position = %scan(%trim(origine) :srcdta : debut ); if position >0; trouve = *on; srcdta = %replace(%trim(remplacement) : srcdta : position : %len(%trim(origine))); debut = position + %len(%trim(remplacement)); endif; enddo; if trouve; update srcf %FIELDS(srcdta); endif; endsr; /end-free |