Aller au contenu
QSNDDTAQ · QUSROBJD · QCMDEXC · QsnWrtDta · CL, RPG IV colonné, full free, SQL

Les API système, ce que le langage ne sait pas faire

Les deux familles d'API, programmes et procédures, le code erreur qu'elles partagent, puis quatre exemples : une file de données entre deux programmes, une commande lancée depuis le RPG, la description d'un objet et un écran 5250 écrit sans DSPF. En CL, en RPG IV colonné, en full free et en SQL, tout exécuté sur un IBM i 7.5.

2familles : programmes et procédures
7API appelées dans les exemples
7programmes CL et RPG exécutés
0DSPF pour l'écran écrit par QsnWrtDta

En une phrase

Une API système est un programme ou une procédure qu'IBM livre avec le système, et qu'on appelle depuis son propre programme pour faire ce qu'aucune instruction du langage ne fait : échanger des messages par une file de données, lire la description d'un objet, exécuter une commande, écrire sur l'écran.

Deux familles : les programmes et les procédures

La différence tient à la façon de les appeler. Une API programme est un objet *PGM de QSYS : on l'appelle par CALL, comme n'importe quel programme, depuis tous les langages. Une API procédure est une procédure exportée par un programme de service : il faut un programme ILE, qui la lie à la compilation.

FamilleObjetAppelLangagesExemples
API programme*PGM (OPM)CALL, ou un prototype EXTPGMTous, même le CLQSNDDTAQ, QRCVDTAQ, QCMDEXC, QUSROBJD
API procédureProcédure d'un *SRVPGM (ILE)Prototype EXTPROC, programme liéILE : RPG avec DFTACTGRP(*NO), C, CL ILEQsnWrtDta, QsnGetAID (QSNAPI)

Les noms le disent souvent : en majuscules (QSNDDTAQ) pour un programme, en casse mixte (QsnWrtDta) pour une procédure. En RPG, les deux s'appellent par un prototype : EXTPGM pour un programme, EXTPROC pour une procédure (voir PR et PI). Pour les procédures, pas besoin de déclarer le programme de service : sur la machine des exemples, QSNAPI est dans le répertoire de liage QUSAPIBD, que le compilateur consulte de lui-même.

Le code erreur, commun aux API

La plupart des API prennent en dernier paramètre une structure code erreur. Son premier champ décide de ce qui se passe en cas d'erreur :

PositionChampType RPGSensRôle
1Octets fournisint(10)EntréeTaille de la structure. 0 : l'erreur part en message d'exception. 8 ou plus : elle est rangée ici.
5Octets disponiblesint(10)Sortie0 : aucune erreur, le reste de la structure n'est pas modifié.
9Identifiantchar(7)SortieLe message, par exemple CPF9801.
16Réservéchar(1)
17Donnéeschar(*)SortieLes variables du message, par exemple le nom de l'objet.

Le piège classique : oublier d'initialiser les octets fournis. Une valeur au hasard fait croire à l'API que la structure est plus grande qu'elle n'est. D'où le inz(%size(codeErreur)) des exemples. Les deux comportements sont montrés plus bas, avec QUSROBJD.

Exemple 1 Une file de données

QSNDDTAQ et QRCVDTAQ : des commandes entre deux programmes

Une file de données (*DTAQ) fait passer des messages d'un programme à un autre, du même travail ou d'un autre : l'un dépose, l'autre retire, dans l'ordre d'arrivée. Ici, ENVOICL dépose trois commandes et un programme RPG les lit. La file a été créée par la commande CRTDTAQ, que lance le programme de l'exemple 2 :

CRTDTAQ DTAQ(JOBIAPI/COMMANDES) MAXLEN(50) TEXT('Commandes a traiter')

CL ENVOICL

/* ENVOICL : dépose trois commandes dans la file COMMANDES        */
/* par l'API QSNDDTAQ (un programme : on l'appelle par CALL).     */
             PGM
             DCL        VAR(&LONG) TYPE(*DEC) LEN(5 0) VALUE(50)
             DCL        VAR(&DATA) TYPE(*CHAR) LEN(50)

             CHGVAR     VAR(&DATA) VALUE('CDE-0001 ACM    3 x Clavier')
             CALL       PGM(QSNDDTAQ) PARM('COMMANDES' 'JOBIAPI' &LONG &DATA)
             CHGVAR     VAR(&DATA) VALUE('CDE-0002 BTP    1 x Ecran 27p')
             CALL       PGM(QSNDDTAQ) PARM('COMMANDES' 'JOBIAPI' &LONG &DATA)
             CHGVAR     VAR(&DATA) VALUE('CDE-0003 ACM   10 x Souris')
             CALL       PGM(QSNDDTAQ) PARM('COMMANDES' 'JOBIAPI' &LONG &DATA)

             SNDPGMMSG  MSG('3 commandes déposées dans COMMANDES')
             ENDPGM

RPG IV colonné RECOIT4

     H* RECOIT4 : lit les commandes en attente dans la file COMMANDES
     DLONGUEUR         S              5P 0
     DDONNEES          S             50A
     DATTENTE          S              5P 0 INZ(0)
     DNOMBRE           S             10I 0
     DTEXTE            S             52A
     C* CALL et PARM : l'appel d'un programme, a l'ancienne
     C* Attente 0 : rend la main tout de suite ; longueur 0 = file vide
     C                   DOU       LONGUEUR = 0
     C                   CALL      'QRCVDTAQ'
     C                   PARM      'COMMANDES'   FILE             10
     C                   PARM      'JOBIAPI'     BIB              10
     C                   PARM                    LONGUEUR
     C                   PARM                    DONNEES
     C                   PARM                    ATTENTE
     C                   IF        LONGUEUR > 0
     C                   EVAL      NOMBRE = NOMBRE + 1
     C     DONNEES       DSPLY
     C                   ENDIF
     C                   ENDDO
     C                   EVAL      TEXTE = 'Commandes lues : ' + %CHAR(NOMBRE)
     C     TEXTE         DSPLY
     C                   EVAL      *INLR = *ON

Full free RECOITF

**FREE
// RECOITF : lit les commandes en attente dans la file COMMANDES
dcl-pr QRCVDTAQ extpgm('QRCVDTAQ');
  file char(10) const;
  bibliotheque char(10) const;
  longueur packed(5:0);
  donnees char(50);
  attente packed(5:0) const;
end-pr;

dcl-s longueur packed(5:0);
dcl-s donnees char(50);
dcl-s nombre int(10);

// Attente 0 : l'API rend la main tout de suite ; longueur 0 = file vide
dow '1';
  QRCVDTAQ('COMMANDES' : 'JOBIAPI' : longueur : donnees : 0);
  if longueur = 0;
    leave;
  endif;
  nombre += 1;
  dsply %subst(donnees : 1 : longueur);
enddo;
dsply ('Commandes lues : ' + %char(nombre));
*inlr = *on;
CALL 'QRCVDTAQ' et ses PARM
En colonné, l'appel d'un programme à l'ancienne : un PARM par paramètre, dans l'ordre de la documentation. Les littéraux 'COMMANDES' et 'JOBIAPI' vont dans des zones de 10 caractères, définies sur la ligne du PARM.
dcl-pr QRCVDTAQ extpgm('QRCVDTAQ');
En full free, un prototype : le compilateur vérifie le nombre et le type des paramètres. Le mot-clé const marque ceux que l'API ne modifie pas : on peut alors passer des littéraux.
longueur packed(5:0) et attente packed(5:0)
Les types de la documentation, à respecter : Packed(5,0). Une attente de 0 rend la main tout de suite, avec une longueur de 0 si la file est vide ; négative, l'API attend sans fin ; positive, elle attend ce nombre de secondes.
CALL QCMD
ADDLIBLE JOBIAPI
CALL ENVOICL
CALL RECOITF
CALL ENVOICL
CALL RECOIT4
Écran Entrée de commandes : CALL ENVOICL affiche 3 commandes déposées dans COMMANDES, puis CALL RECOITF affiche CDE-0001 ACM 3 x Clavier, CDE-0002 BTP 1 x Ecran 27p, CDE-0003 ACM 10 x Souris et Commandes lues : 3
ENVOICL dépose les trois commandes, RECOITF les retire dans l'ordre d'arrivée.
Écran Entrée de commandes : après un second CALL ENVOICL, CALL RECOIT4 affiche les trois mêmes commandes et Commandes lues : 3
RECOIT4, la version colonnée, lit de la même façon. Après la lecture, la file est vide.

La même file, vue et utilisée en SQL

Avant la lecture, juste après ENVOICL, QSYS2.DATA_QUEUE_ENTRIES montre le contenu de la file sans rien retirer :

SELECT ORDINAL_POSITION, MESSAGE_DATA
  FROM TABLE(QSYS2.DATA_QUEUE_ENTRIES(DATA_QUEUE => 'COMMANDES',
                                     DATA_QUEUE_LIBRARY => 'JOBIAPI'))
ORDINAL_POSITIONMESSAGE_DATA
1CDE-0001 ACM    3 x Clavier
2CDE-0002 BTP    1 x Ecran 27p
3CDE-0003 ACM   10 x Souris
SELECT DATA_QUEUE_TYPE, MAXIMUM_MESSAGE_LENGTH, SEQUENCE, CURRENT_MESSAGES
  FROM QSYS2.DATA_QUEUE_INFO
 WHERE DATA_QUEUE_LIBRARY = 'JOBIAPI'
DATA_QUEUE_TYPEMAXIMUM_MESSAGE_LENGTHSEQUENCECURRENT_MESSAGES
STANDARD50FIFO3

Les procédures QSYS2.SEND_DATA_QUEUE et QSYS2.RECEIVE_DATA_QUEUE font le travail de QSNDDTAQ et de QRCVDTAQ :

CALL QSYS2.SEND_DATA_QUEUE(MESSAGE_DATA => 'CDE-0004 BTP    2 x Casque',
                           DATA_QUEUE => 'COMMANDES',
                           DATA_QUEUE_LIBRARY => 'JOBIAPI')
SELECT MESSAGE_DATA
  FROM TABLE(QSYS2.RECEIVE_DATA_QUEUE(DATA_QUEUE => 'COMMANDES',
                                     DATA_QUEUE_LIBRARY => 'JOBIAPI'))
MESSAGE_DATA
CDE-0004 BTP    2 x Casque

RECEIVE_DATA_QUEUE retire le message : DATA_QUEUE_ENTRIES ne rend ensuite plus aucune ligne. Différence avec ENVOICL : SEND_DATA_QUEUE a déposé exactement la longueur du texte, 26 caractères, alors que QSNDDTAQ en dépose 50, la longueur passée en paramètre.

Exemple 2 Une commande depuis le RPG

QCMDEXC : exécuter une commande CL

Le RPG n'a pas d'instruction pour lancer une commande CL : QCMDEXC le fait. Deux paramètres : la commande, puis sa longueur en packed(15:5). CMDF crée la file de l'exemple 1 :

**FREE
// CMDF : cree la file COMMANDES par l'API QCMDEXC
dcl-pr QCMDEXC extpgm('QCMDEXC');
  commande char(3000) const options(*varsize);
  longueur packed(15:5) const;
end-pr;

// Statut du programme : identifiant du dernier message d'erreur
dcl-ds etat psds qualified;
  message char(7) pos(40);
end-ds;

dcl-s commande varchar(200);

commande = 'CRTDTAQ DTAQ(JOBIAPI/COMMANDES) MAXLEN(50) '
         + 'TEXT(''Commandes a traiter'')';
monitor;
  QCMDEXC(commande : %len(commande));
  dsply 'File COMMANDES creee';
on-error;
  dsply ('CRTDTAQ refuse : ' + etat.message);
endmon;
*inlr = *on;
commande char(3000) const options(*varsize)
La commande est passée telle quelle ; sa vraie longueur est donnée par le second paramètre, %len(commande).
monitor; … on-error;
Une commande qui échoue envoie son message d'erreur au programme. MONITOR l'intercepte, et l'identifiant du message se lit dans la structure d'état du programme (psds, positions 40 à 46).
Écran Entrée de commandes, messages détaillés : le premier CALL CMDF affiche Objet COMMANDES, type *DTAQ, créé dans la bibliothèque JOBIAPI et DSPLY File COMMANDES creee ; le second affiche L'objet COMMANDES de type *DTAQ existe déjà et DSPLY CRTDTAQ refuse : CPF9870
Premier appel : la file est créée. Second appel : CRTDTAQ échoue avec CPF9870, et le programme continue.

En SQL, la procédure QSYS2.QCMDEXC rend le même service.

Exemple 3 Le code erreur en pratique

QUSROBJD : la description d'un objet

QUSROBJD remplit une zone, le récepteur, avec la description d'un objet, selon un format : OBJD0100 pour l'essentiel, OBJD0200 pour davantage de champs, dont l'attribut et le texte. Le programme décrit le format par une structure, aux positions de la documentation :

**FREE
// OBJDF : description d'un objet par l'API QUSROBJD
dcl-pi *n;
  objet char(10);
  type char(10);
end-pi;

dcl-pr QUSROBJD extpgm('QUSROBJD');
  recepteur char(32767) options(*varsize);
  longueur int(10) const;
  format char(8) const;
  nomQualifie char(20) const;
  typeObjet char(10) const;
  erreur likeds(codeErreur);
end-pr;

// Debut du format OBJD0200, aux positions donnees par la documentation
dcl-ds objd0200 qualified;
  octetsRendus int(10);
  octetsDispo int(10);
  nom char(10);
  bibliotheque char(10);
  type char(10);
  bibRetour char(10);
  asp int(10);
  proprietaire char(10);
  domaine char(2);
  creation char(13);
  modification char(13);
  attribut char(10);
  texte char(50);
end-ds;

// Code erreur : octets fournis > 0, l'API y range l'erreur
// au lieu d'envoyer un message d'exception
dcl-ds codeErreur qualified;
  fournis int(10) inz(%size(codeErreur));
  disponibles int(10) inz(0);
  message char(7);
  *n char(1);
  donnees char(100);
end-ds;

QUSROBJD(objd0200 : %size(objd0200) : 'OBJD0200'
        : objet + '*LIBL' : type : codeErreur);
if codeErreur.disponibles > 0;
  dsply ('Erreur ' + codeErreur.message + ' sur ' + %trim(objet));
else;
  dsply (%trim(objd0200.bibRetour) + '/' + %trim(objd0200.nom)
        + ' proprietaire ' + objd0200.proprietaire);
  dsply objd0200.texte;
endif;
*inlr = *on;

La même API, avec un code erreur dont les octets fournis valent 0 :

**FREE
// OBJEXCF : QUSROBJD avec un code erreur de 0 octet fourni
dcl-pi *n;
  objet char(10);
  type char(10);
end-pi;

dcl-pr QUSROBJD extpgm('QUSROBJD');
  recepteur char(32767) options(*varsize);
  longueur int(10) const;
  format char(8) const;
  nomQualifie char(20) const;
  typeObjet char(10) const;
  erreur likeds(codeErreur);
end-pr;

dcl-ds etat psds qualified;
  message char(7) pos(40);
end-ds;

dcl-s recepteur char(100);

// Octets fournis = 0 : l'API envoie l'erreur en message d'exception
dcl-ds codeErreur qualified;
  fournis int(10) inz(0);
  disponibles int(10) inz(0);
end-ds;

monitor;
  QUSROBJD(recepteur : %size(recepteur) : 'OBJD0100'
          : objet + '*LIBL' : type : codeErreur);
  dsply ('Objet trouve : ' + %trim(objet));
on-error;
  dsply ('Exception ' + etat.message + ', statut ' + %char(%status));
endmon;
*inlr = *on;
CALL OBJDF PARM(COMMANDES '*DTAQ')
CALL OBJDF PARM(INCONNUE '*DTAQ')
CALL OBJEXCF PARM(INCONNUE '*DTAQ')
Écran Entrée de commandes : OBJDF sur COMMANDES affiche JOBIAPI/COMMANDES proprietaire SAKADM et Commandes a traiter ; OBJDF sur INCONNUE affiche Erreur CPF9801 sur INCONNUE ; OBJEXCF sur INCONNUE affiche le message Objet INCONNUE non trouvé dans la bibliothèque *LIBL puis Exception CPF9801, statut 202
Avec 116 octets fournis, l'erreur CPF9801 est rangée dans la structure, sans message. Avec 0, le même CPF9801 part en exception et apparaît dans l'historique du travail.

Le programme passe *LIBL comme bibliothèque : celle où l'objet a été trouvé revient dans bibRetour, ici JOBIAPI. Le texte affiché est celui donné à CRTDTAQ.

Exemple 4 Une API procédure

QsnWrtDta : écrire sur l'écran sans DSPF

Les API DSM (Dynamic Screen Manager) pilotent l'écran 5250 directement : effacer, écrire un texte à une ligne et une colonne, attendre une touche. Ce sont des procédures du programme de service QSNAPI : le programme est ILE, d'où dftactgrp(*no), et les prototypes utilisent EXTPROC.

**FREE
// ECRANF : ecrit sur l'ecran 5250 avec les API DSM (procedures ILE)
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-ds codeErreur qualified template;
  fournis int(10);
  disponibles int(10);
  message char(7);
  *n char(1);
end-ds;

dcl-pr QsnClrScr int(10) extproc('QsnClrScr');
  mode char(1) const options(*omit);
  tampon int(10) const options(*omit);
  environnement int(10) const options(*omit);
  erreur likeds(codeErreur) options(*omit);
end-pr;

dcl-pr QsnWrtDta int(10) extproc('QsnWrtDta');
  donnees char(132) const options(*varsize);
  longueur int(10) const;
  zone int(10) const options(*omit);
  ligne int(10) const;
  colonne int(10) const;
  attributDebut char(1) const options(*omit);
  attributFin char(1) const options(*omit);
  couleurDebut char(1) const options(*omit);
  couleurFin char(1) const options(*omit);
  tampon int(10) const options(*omit);
  environnement int(10) const options(*omit);
  erreur likeds(codeErreur) options(*omit);
end-pr;

dcl-pr QsnGetAID char(1) extproc('QsnGetAID');
  touche char(1) options(*omit);
  tampon int(10) const options(*omit);
  environnement int(10) const options(*omit);
  erreur likeds(codeErreur) options(*omit);
end-pr;

// Attributs 5250 : 20 normal (vert), 21 inverse, 22 blanc,
// 30 turquoise, 32 jaune, 28 rouge ; sur un ecran couleur,
// c'est l'attribut de couleur qui compte
dcl-c NORMAL x'20';
dcl-c BLANC x'22';
dcl-c INVERSE x'21';
dcl-c TURQUOISE x'30';
dcl-c JAUNE x'32';
dcl-c ROUGE x'28';

dcl-s texte varchar(80);
dcl-s touche char(1);

// Mode '0' : effacer l'ecran et passer en 24 x 80
QsnClrScr('0' : *omit : *omit : *omit);

texte = 'Ecran ecrit par QsnWrtDta';
QsnWrtDta(texte : %len(texte) : 0 : 2 : 27
         : BLANC : NORMAL : BLANC : NORMAL : *omit : *omit : *omit);
texte = ' Pas de DSPF : le programme place lui-meme chaque texte ';
QsnWrtDta(texte : %len(texte) : 0 : 5 : 11
         : INVERSE : NORMAL : INVERSE : NORMAL : *omit : *omit : *omit);
texte = 'Ligne 8, colonne 11, en jaune';
QsnWrtDta(texte : %len(texte) : 0 : 8 : 11
         : NORMAL : NORMAL : JAUNE : NORMAL : *omit : *omit : *omit);
texte = 'Ligne 10, colonne 30, en rouge';
QsnWrtDta(texte : %len(texte) : 0 : 10 : 30
         : NORMAL : NORMAL : ROUGE : NORMAL : *omit : *omit : *omit);
texte = 'Appuyez sur Entree ou sur F3';
QsnWrtDta(texte : %len(texte) : 0 : 22 : 2
         : NORMAL : NORMAL : TURQUOISE : NORMAL : *omit : *omit : *omit);

// QsnGetAID attend une touche et rend son code AID
touche = QsnGetAID(*omit : *omit : *omit : *omit);
if touche = x'33';
  dsply 'Touche lue : F3';
elseif touche = x'F1';
  dsply 'Touche lue : Entree';
else;
  dsply 'Touche lue : une autre';
endif;
*inlr = *on;
options(*omit)
Les paramètres facultatifs des API DSM (tampon de commandes, environnement, code erreur) sont omis : l'API prend alors l'écran courant et ses valeurs par défaut.
QsnWrtDta(texte : %len(texte) : 0 : ligne : colonne : …)
Le texte, sa longueur, 0 pour « pas d'identifiant de zone » (le texte se place alors par ligne et colonne), la ligne et la colonne, puis les attributs de début et de fin : monochrome, puis couleur. Sur un écran couleur, c'est l'attribut de couleur qui compte : x'21' en couleur donne la vidéo inverse.
QsnGetAID
Attend une touche et rend son code AID : x'F1' pour Entrée, x'33' pour F3.
Écran 5250 écrit par ECRANF : titre blanc Ecran ecrit par QsnWrtDta en ligne 2, bandeau vert en vidéo inverse en ligne 5, texte jaune en ligne 8 colonne 11, texte rouge en ligne 10 colonne 30, invite turquoise en ligne 22
L'écran d'ECRANF : chaque texte est à la ligne et à la colonne demandées. Après F3, le programme affiche Touche lue : F3.

Pour un vrai écran de saisie, un DSPF reste plus simple à écrire et à maintenir. DSM sert aux outils qui construisent leur écran à l'exécution.

Les messages relevés

MessageAPICe qu'on voitCause
CPF9870QCMDEXCL'objet COMMANDES de type *DTAQ existe déjà dans la bibliothèque JOBIAPI.CMDF appelé une seconde fois : CRTDTAQ échoue, MONITOR intercepte le message.
CPF9801QUSROBJD, code erreur de 116 octetsAucun message : l'identifiant est rangé dans la structure.Objet absent. Le programme lit codeErreur.message et continue.
CPF9801QUSROBJD, code erreur de 0 octetObjet INCONNUE non trouvé dans la bibliothèque *LIBL.Le même objet absent, mais en exception : MONITOR l'intercepte (statut 00202) ; sans lui, le programme serait interrompu par l'erreur.

Sources

Les exemples ont été exécutés sur un IBM i 7.5 (voir la méthode). Les règles viennent de ces sources, consultées le 26 octobre 2026 :

  1. Send Data Queue (QSNDDTAQ) API, IBM, IBM i 7.5. Paramètres de QSNDDTAQ : nom de la file, bibliothèque, longueur en Packed(5,0), données.
  2. Receive Data Queue (QRCVDTAQ) API, IBM, IBM i 7.5. Temps d'attente : négatif sans fin, 0 sans attente (longueur rendue à 0), positif en secondes ; longueur reçue jamais supérieure au MAXLEN de CRTDTAQ.
  3. Error code parameter format, IBM, IBM i 7.5. Format ERRC0100 : octets fournis, octets disponibles, identifiant (7), réservé, données ; octets fournis à 0 : exception ; 8 ou plus : erreur rangée dans la structure.
  4. Retrieve Object Description (QUSROBJD) API, IBM, IBM i 7.5. Paramètres de QUSROBJD et format OBJD0200 (attribut étendu en position 91, texte en 101).
  5. Execute Command (QCMDEXC) API, IBM, IBM i 7.5. La commande et sa longueur en Packed(15,5).
  6. Write Data (QsnWrtDta) API, IBM, IBM i 7.5. Données, longueur, zone, ligne, colonne, attributs de début et de fin (monochrome et couleur).
  7. SEND_DATA_QUEUE, SEND_DATA_QUEUE_BINARY, SEND_DATA_QUEUE_UTF8, IBM, IBM i 7.5. Procédures SQL équivalentes à QSNDDTAQ.
  8. RECEIVE_DATA_QUEUE table function, IBM, IBM i 7.5. Fonction SQL équivalente à QRCVDTAQ, qui retire le message par défaut.
  9. DATA_QUEUE_ENTRIES table function, IBM, IBM i 7.5. Lecture du contenu d'une file sans le retirer.

Questions fréquentes

Qu'est-ce qu'une API système sur IBM i ?

Un programme ou une procédure qu'IBM livre avec le système, et qu'on appelle depuis son propre programme pour faire ce qu'aucune instruction du langage ne fait : déposer un message dans une file de données, lire la description d'un objet, exécuter une commande, écrire sur l'écran.

Quelle différence entre QSNDDTAQ et QsnWrtDta ?

QSNDDTAQ est une API programme (*PGM) : on l'appelle par CALL, depuis n'importe quel langage, même en CL. QsnWrtDta est une API procédure : elle est dans le programme de service QSNAPI, et on l'appelle comme une procédure, depuis un programme ILE (en RPG, DFTACTGRP(*NO)). Sur l'IBM i 7.5 des exemples, QSNAPI est dans le répertoire de liage QUSAPIBD, que le compilateur consulte de lui-même : aucun BNDDIR à déclarer.

À quoi sert le paramètre code erreur ?

La plupart des API le prennent en dernier paramètre. Si son premier champ (octets fournis) vaut 0, l'erreur est envoyée en message d'exception (CPF9801 pour un objet absent). S'il vaut 8 ou plus, l'API range l'erreur dans la structure, sans exception : les octets disponibles sont alors différents de 0 et l'identifiant du message est renseigné.

Comment lire une file de données sans attendre ?

Avec QRCVDTAQ et un temps d'attente de 0 : l'API rend la main tout de suite, et la longueur reçue vaut 0 si la file est vide. Avec une valeur négative, l'API attend sans fin ; avec une valeur positive, elle attend ce nombre de secondes.

Peut-on utiliser une file de données en SQL ?

Oui : QSYS2.SEND_DATA_QUEUE dépose un message, QSYS2.RECEIVE_DATA_QUEUE le retire, et QSYS2.DATA_QUEUE_ENTRIES montre le contenu sans rien retirer. Sur IBM i 7.5, SEND_DATA_QUEUE a déposé exactement la longueur du texte, sans blancs de complément.

Comment exécuter une commande CL depuis un programme RPG ?

Avec l'API QCMDEXC : la commande en premier paramètre, sa longueur en packed(15:5) en second. Une commande qui échoue envoie son message d'erreur au programme : on l'intercepte par MONITOR.