Parlez REXX sur IBMi

REXX (Restructured Extended Executor) est un langage de script interprété créé par IBM, bien connu pour les « Roger » qui ont sévit sous OS2.
Il est conçu pour être facile à lire et facile à apprendre, tout en étant très puissant pour l’automatisation.

Sur IBMi, il est utilisé pour :
Automatiser des tâches système
Créer des utilitaires interactifs
Prototyper rapidement
Faire du traitement de texte et de données

Ces points forts sont :
Très rapide à écrire, idéal pour du scripting jetable
Permet d’appeler directement des commandes système sans compiler un programme
Peut servir de « colle » entre RPG, CL, SQL et PASE/QShell
Permet de faire des tests d’appels, des scripts de migration, des reprises de données.

Comment ca marche?

Vous devez créer un fichier source qui contiendra les scripts à exécuter

CRTSRCPF FILE(MALIB/QRXSRC) RCDLEN(112) TEXT(‘Sources REXX’)

Vous devez saisir vos scripts ici REXX01

/* REXX / / Boucle interactive jusqu’à ce que l’utilisateur tape ‘FIN’ */

DO FOREVER
SAY « Entrez une commande CL (ou FIN pour quitter) : »
PULL CMD
IF CMD = « FIN » THEN LEAVE
ADDRESS ‘COMMAND’ CMD
END

Ce scripte exécutera des commandes CLP, jusqu’à ce que saisissiez FIN

Pour exécuter ce script :

STRREXPRC SRCMBR(REXX01) SRCFILE(MALIB/QRXSRC)

Remarque :
Le rexx est de moins en moins utilisé mais, il peut encore être utilisé, en effet, il peut aider a du déploiement et de la mise au point, etc…

Pour en savoir plus :

https://en.wikipedia.org/wiki/Rexx

https://www.rexxla.org

Merci à Dilhan pour sa contribution

, , Les profils _NC en V7R6

En V7R6 vous avez de nouveaux profils qui apparaissent avec l’extention _NC

QPGMR_NC
QSECOFR_NC
QSYSOPR_NC
QUSER_NC

C’est des profils qui ne sont pas modifiables, et ils n’ont pas de mot de passe

Et certains services ibm démarrent avec ceux ci

Conclusions :
Attention, par exemple, si vous avez customisé QUSER ou QPGMR vous pouvez avoir des surprises après migration

, , Ajouter des fichiers à une archive ZIP

Vous connaissez tous la commande CPYTOARCF qui permet de Zipper un fichier

Mais vous ne pouvez pas un fois généré lui ajouter un fichier !

On va essayer de vous aider

Dans les produits opensys vous avez la commande zip

Vous avez ce répertoire dans votre path (similaire à votre *LIBL)
$

echo $PATH
/QOpenSys/pkgs/bin:/usr/bin:.:/QOpenSys/usr/bin
$

Remarque
Vous pouvez le régler par le fichier .profile

https://www.ibm.com/support/pages/setting-path-environment-variable-include-current-working-directory-qshell

Vous pouvez donc zipper sous QSH ou QP2TERM

exemple

$

zip archive.zip analyse.csv
adding: analyse.csv (deflated 84%)
$

et par défaut si vous zippez sur une archive existante il ajoute

zip archive.zip xmlversion.txt
adding: xmlversion.txt (stored 0%)
$

pour voir le résultat

unzip -l archive.zip
Archive: archive.zip
Length Date Time Name
——— ———- —– —-
9934 2019-03-29 23:44 analyse.csv
17 2019-02-13 10:49 xmlversion.txt
——— ——-
9951 2 files
$

Pour vous aider nous proposons une commande ADDTOARCF que vous pouvez retrouver ici
https://github.com/Plberthoin/PLB/tree/master/GTOOLS/
un CLLE + un CMD

Remarque :

Vous pouvez ajouter une un fichier à un zip généré par CPYTOARCF
Par défaut il créera la l’archive
Vous pouvez indiquer des options si elles sont valides dans la commande Zip
Vous avez un fichier stdout.log dans votre répertoire courant

Simple et efficace !

Comment faire afficher un écran à un traitement batch ?

Les traitements 5250 sont faits pour tourner en interactif, mais pour différentes raisons vous pouvez vouloir les faire tourner en batch :

Pas de login
sécurisation pas de attn request
etc …

Voici un exemple, dans une société ou j’ai travaillé, les unités de productions pouvaient demander un mot de passe à l’astreinte, par exemple la nuit.

La solution la plus simple qu’on avait trouvée était de lui afficher un programme de changement sur son unité écran.

On lui demandait donc son profil utilisateur et son unité écran et on lançait le programme sur celle ci, il pouvait changer son mot de passe directement.

C’est cet exemple que j’ai simplifié qui est ci dessous

le DSPF source

                                                                 
     A                                      DSPSIZ(24 80 *DS3)             
     A                                      CA03(03)                       
     A                                      INDARA                         
     A          R FMT01                                                    
     A*%%TS  SD  20240527  074541  PLB         REL-V7R4M0  5770-WDS        
     A                                  4 20'Réinitialiser un mot de passe'
     A                                  7  2'Utilisateur         :'        
     A                                  8  2'Nouveau mot de passe  :'        
     A                                 22  1'F3=Exit'                      
     A            USER          10A  O  7 26                               
     A            PWD           32A  B  8 26CHECK(LC)                      
     A            DEV           10A  O  4 54                               
     A            TEXTE         30   O 14  3                               

Le CLP source

pgm  (&dev &user)                                                
/*----------------------------------------------------------*/   
/* Ce programme permet de faire afficher un écran en batch  */   
/* vous devez acquérir l'unité écran                         */   
/* pour réinitialiser un mot de passe                        */   
/* sbmjob cmd(call initpwdr (&dev &user) job(QPADEV0001)    */   
/*----------------------------------------------------------*/   
dcl &dev  *char 10                                               
dcl &user *char 10                                               
/* Contrôles existence                      */                   
             CHKOBJ     OBJ(&DEV) OBJTYPE(*DEVD)                 
             MONMSG     MSGID(CPF9801) EXEC(DO)                  
             SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +           
                          MSGDTA('L''unité écran doit exister') +
                          MSGTYPE(*ESCAPE)                       
             enddo 
            ALCOBJ     OBJ((&DEV *DEVD *EXCLRD)) WAIT(0)       
            monmsg CPF1002  exec(do)                           
            SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +          
                         MSGDTA('Impossible d''allouer l''unité +
                         écran doit exister') MSGTYPE(*ESCAPE) 
            enddo                                                                                            
             CHKOBJ     OBJ(&user) OBJTYPE(*usrprf)              
             MONMSG     MSGID(CPF9801) EXEC(DO)                  
             SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Le +
                          profil utilisateur doit exister') +         
                          MSGTYPE(*ESCAPE)                            
             enddo                                                    
 /* Lancement du programme sur l'écran remote  */                      
             SBMJOB     CMD(CALL PGM(INITPWDR) PARM((&DEV) (&USER))) +
                          JOB(&DEV) JOBQ(QSYSNOMAX)  
             SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +          
                          MSGDTA('Travail, ' *bcat &dev *bcat + 
                          'démarré') MSGTYPE(*comp)                              
endpgm                                                                

Le CLP cible

pgm  (&dev &user)                                                
/*----------------------------------------------------------*/   
/* Ce programme réinitiliase  un mot  de passe              */   
/* Peut être envoyé sur un écran remote qui est sur la      */   
/* Mire                                                     */   
/*----------------------------------------------------------*/   
dcl &dev *char 10                                                
dclf initpwdr                                                    
monmsg cpf0000 exec(goto erreur)                                 
/* controles fait dans le programme appelant */                  
             OVRDSPF    FILE(INITPWDR) DEV(&DEV) OVRSCOPE(*JOB)  
          chgvar &pwd     'ici mot de passe'                     
             dountil &in03                                       
             SNDRCVF    RCDFMT(FMT01)                            
             if cond(*not &in03) then(do)                        
             if (&pwd *ne 'ici mot de passe') then(do)           
             CHGUSRPRF  USRPRF(&USER) PASSWORD(&PWD) PWDEXP(*YES)
             Chgvar &texte ('Mot de passe réinitialisé')         
             enddo                                               
             enddo                                                   
             enddo                                                   
/* fin traitement */                                                 
             DLTOVR     FILE(INITPWD) LVL(*JOB)                      
             MONMSG     MSGID(CPF0000)                               
return                                                               
erreur:                                                              
             SNDUSRMSG  MSG('Réinitialisation de mot de passe pour' +
                          *BCAT &USER *BCAT ', actuellement +        
                          impossible') MSGTYPE(*INFO)                
             MONMSG     MSGID(CPF0000)                               
endpgm                                                               

La seule spécificité est de choisir l’unité écran d’affichage, pour qu’elle soit éligible elle doit être à la mire de connexion.

La commande pour habiller

             CMD        PROMPT('Réinitialisation de PWD')           
             PARM       KWD(UNITE) TYPE(*NAME) LEN(10) MIN(1) +     
                          PROMPT('Unité écran')                     
             PARM       KWD(PROFIL) TYPE(*NAME) LEN(10) MIN(1) +    
                          PROMPT('Profil utilisateur')              

le lancement job source:

La saisie sur le job cible :

Sur un changement de mot de passe, il peut être important d’avoir un suivi ?

Bien sur, vous pouvez ajouter des contrôles …

Le job cible qui tourne en batch !

Donc pas de possibilité d’ATTN Request , et messages d’erreurs dans QSYSOPR

Remarques :

Vous pouvez choisir l’utilisateur de lancement, mais QSECOFR est interdit dans un SBMJOB
Simple mais efficace, mais difficilement généralisable, on doit avoir un OVRDBF par DSPF

Intéressant pour des demandes ponctuelles

Dans les CLP vous pouvez indiquer directement l’unité sur la commande SNDRCVF

, , , Contrôler le nombre de paramètres passés à un programme CL – %PARMS() / CEETSTA
presence_flagSortie*INTVariable de retour : 1 ou 0
arg_numEntrée*INTPosition de la variable à tester

Remarques

Le compte des paramètres pour la arg_num commence à 1
La valeur de retour est un *INT pas un *LGL

Pour plus de détails

Documentation IBM – %PARMS() : https://www.ibm.com/docs/en/i/7.5?topic=procedure-parms-built-in-function
Documentation IBM – CEETSTA : https://www.ibm.com/docs/api/v1/content/ssw_ibm_i_75/apis/CEETSTA.htm
sinus cosinus tangentes
, Utilisation de la souris dans un DSPF

Vous voulez utiliser la souris dans un dspf sur dans un de vos programmes
voici un exemple en CLLE:

DSPF :

A                                      DSPSIZ(24 80 *DS3)               
A                                      CA03(03)                         
A* EVENNEMENT SOURIS                                                    
A*          UNSHIFT  / LEFT / PRESS                                     
A          R FMT01                                                      
A*%%TS  SD  20231025  171347  QSECOFR     REL-V7R4M0  5770-WDS          
A                                      MOUBTN(*ULP ENTER)               
A                                      RTNCSRLOC(*MOUSE &L1 &C1 &L2 &C2)
A* RÉCUPÉRATION DU CURSEUR                                              
A            L1             3S 0H                                       
A            C1             3S 0H                                       
A            L2             3S 0H                                       
A            C2             3S 0H                                       
A                                  3 13'Tester la position de la souris'
A                                  5 13'En faisant un clic Gauche.'     
A*  BOUTON BAS DE PAGE                                                  
A            F1B            2Y 0B 23  2PSHBTNFLD                        
A                                      PSHBTNCHC(1 'F3=>Exit' CA03)

CLLE

pgm                                                               
dclf mouse                                                        
             DOUNTIL    COND(&IN03)                               
             SNDRCVF    RCDFMT(FMT01)                             
             if cond(*not &in03) then(do)                         
             SNDUSRMSG  MSG('Position du curseur ligne =' *BCAT + 
                          %CHAR(&L1) *BCAT 'et colonne =' *BCAT + 
                          %CHAR(&C1)) MSGTYPE(*INFO)              
             enddo                                                
             ENDDO                                                
endpgm                                                            

Remarque:

Vous devez compiler avec l’option ENHDSP(*YES)

, , Utiliser un SFL d’erreurs

C’est la possibilité d’avoir plusieurs messages d’erreur et de pouvoir paginer dessus

Vous pouvez programmer un sous fichier message, mais ca peut être un peu compliqué à réaliser.

Voici une solution simple, il suffit de mettre le mot clé ERRSFL au niveau fichier écran

Ci dessous un exemple avec son programme en CLLE

DSPF

     A* Exemple sous fichier d'erreurs
     A                                      DSPSIZ(24 80 *DS3)         
     A                                      ERRSFL                     
     A                                      CA03(03)                   
     A          R FMT01                                                
     A            ZONE1         10A  B 11 20                           
     A  41                                  ERRMSG('Erreur ZONE 1' 41) 
     A            ZONE2         10A  B 12 20                           
     A  42                                  ERRMSG('Erreur ZONE 2' 42) 
     A            ZONE3         10A  B 13 20                           
     A  43                                  ERRMSG('Erreur ZONE 3' 43) 
     A                                  6  8'Sous fichier d''erreur'   
     A                                      DSPATR(HI)                 
     A                                 11  8'Zone 1 :'                 
     A                                 12  8'Zone 2 :'                 
     A                                 13  8'Zone 3 :'                                                         

CLLE

/* Exemple sous fichier message d'erreur */       
PGM                                               
DCLF ERREUR                                       
dountil &in03                                     
             SNDRCVF    RCDFMT(FMT01)             
             IF         COND(*NOT &IN03) THEN(DO) 
 /* activation des indicateurs d'erreur */        
             CHGVAR &IN41 '1'                     
             CHGVAR &IN42 '1'                     
             CHGVAR &IN43 '1'                     
enddo                                             
enddo                                             
ENDPGM                                            

Remarque:

La seule limitation, c’est une seule erreur par zone, mais ca suffit dans 90 % des cas