Les sous-fichiers, une liste à l'écran sans écrire la pagination
Le principe du sous-fichier 5250, ses mots-clés DDS, les trois façons de le charger et pourquoi nous conseillons le sous-fichier statique. Puis un écran complet, construit sur un gabarit d'entreprise, et le même programme en RPG III, en RPG IV colonné et en full free, testé sur un IBM i 7.5.
En une phrase
Un sous-fichier est une liste d'enregistrements d'un même format que le programme écrit dans un fichier écran, ligne par ligne, puis affiche en une seule opération ; l'utilisateur la fait défiler, saisit des options, et le programme relit seulement les lignes modifiées.
Le principe
Un sous-fichier se décrit dans les DDS d'un écran par deux formats : le format du
sous-fichier (mot-clé SFL), qui décrit une ligne de la liste, et le format de contrôle
(SFLCTL), qui affiche la liste, la vide, et porte tout ce qui l'entoure. Un même écran
peut contenir plusieurs sous-fichiers, jusqu'à 12 actifs à la fois.
Les mots-clés DDS
| Mot-clé | Rôle | Ce qu'il faut savoir |
|---|---|---|
SFL | Format du sous-fichier | Une ligne de la liste (SFL1) : l'option, le code, le libellé et le stock. |
SFLCTL(SFL1) | Format de contrôle | SF1CTL affiche, vide et termine le sous-fichier, et porte l'en-tête. Ce qu'il affiche ne doit pas chevaucher les lignes du sous-fichier : ici, tout est au-dessus. |
SFLSIZ(0013) | Taille | Le nombre d'enregistrements prévu, 9999 au plus. Plus grand que SFLPAG : le système étend le sous-fichier et fait défiler les pages. |
SFLPAG(0012) | Page | Le nombre de lignes affichées à la fois. |
N31 SFLDSPCTL | Afficher le contrôle | L'en-tête s'affiche tant que 31 est éteint. |
N32 SFLDSP | Afficher les lignes | Les lignes s'affichent tant que 32 est éteint ; on l'allume quand la liste est vide. |
31 SFLCLR | Vider | Une écriture de SF1CTL avec 31 allumé vide le sous-fichier (et n'affiche rien, grâce à N31 et N32). |
90 SFLEND(*MORE) | Fin | « A suivre... » tant que 90 est éteint, « Fin » quand le programme l'allume en fin de fichier. |
RANG … SFLRCDNBR | Page à afficher | Une zone cachée : la page affichée est celle qui contient ce rang. |
Les opérations RPG
| Opération | Ce qu'elle fait |
|---|---|
SFILE(SFL1:RANG) | Relie le format SFL1 à la zone RANG, le rang de la ligne dans le sous-fichier. |
WRITE SFL1 | Écrit une ligne au rang RANG. |
WRITE SF1CTL | Avec 31 allumé : vide le sous-fichier. |
WRITE MSGSFLH, WRITE FKEY1 | Le sous-fichier de messages (ligne 24) et les touches de fonction (ligne 23), écrits avant le contrôle. |
EXFMT SF1CTL | Affiche le contrôle et le sous-fichier, puis attend la réponse. |
READC SFL1 | Lit la ligne modifiée suivante (une option saisie) et met son rang dans RANG. |
EXFMT FMT5 | L'option 5 : la fenêtre qui affiche l'article. |
Trois façons de le charger, une seule à retenir
- Le sous-fichier statique, chargé en une fois :
SFLSIZplus grand queSFLPAG(ici 13 pour 12), le programme écrit tous les enregistrements puis affiche. Le système étend le sous-fichier à mesure qu'on écrit, jusqu'à 9999, et fait défiler les pages tout seul, sans revenir au programme. - Le sous-fichier extensible : même DDS, mais le programme n'écrit qu'une page, et
le mot-clé
PAGEDOWNlui rend la main en fin de sous-fichier pour en ajouter une autre. - Le sous-fichier page à page :
SFLSIZégal àSFLPAG; le programme vide et recharge le sous-fichier à chaque touche Page suivante ou Page précédente, en gérant lui-même sa position dans le fichier.
Notre conseil : le statique
- Le code le plus court : une routine de chargement, une boucle de traitement, rien pour la pagination.
- Le plus sûr : pas de position à mémoriser d'une page à l'autre, pas de ligne perdue ni en double.
- Pour un gros fichier, la zone « Afficher à partir de » positionne la lecture (SETLL) et l'on charge à partir de là, plutôt que de passer au page à page.
L'écran : un gabarit, un seul DSPF pour les trois versions
L'écran suit un gabarit d'entreprise : chaque liste a la même disposition, les mêmes noms de formats et les mêmes indicateurs, d'un programme à l'autre.
| Où | Quoi |
|---|---|
| Ligne 1 | Le nom de l'écran à gauche, le titre en surbrillance au centre, la date à droite (DATE EDTCDE(Y)). |
| Ligne 2 | L'heure à droite (TIME). |
| Ligne 3 | La zone de positionnement « Afficher à partir de : », suivie de ce qu'il faut saisir. |
| Lignes 5 et 6 | La consigne « Indiquez vos options, puis appuyez sur ENTREE. » et la liste des options, en bleu. |
| Ligne 8 | Les titres de colonnes en surbrillance, « Opt » en colonne 2. |
| Lignes 9 à 20 | Les 12 lignes du sous-fichier, la zone d'option en colonne 2. |
| Ligne 23 | Les touches de fonction, en bleu, dans leur propre format (FKEY1). |
| Ligne 24 | Le sous-fichier de messages du programme (MSGSFLD, MSGSFLH). |
| Option 5 | Une fenêtre (FMT5) avec un titre et une bordure. |
La liste montre les 30 articles du fichier ARTICLE (le même PF que la page Coder en RPG III), 12 par page :
A* ARTSFL : les articles en sous-fichier statique
A DSPSIZ(24 80 *DS3)
A CA03(03 'Exit')
A CA05(05 'Réafficher')
A CA12(12 'Retour')
A* Une ligne du sous-fichier
A R SFL1 SFL
A OPT 1A I 9 2
A E1COD R O 9 7REFFLD(ARTICLR/ARTCOD ARTICLE)
A E1LIB R O 9 16REFFLD(ARTICLR/ARTLIB ARTICLE)
A E1STK R Y O 9 50REFFLD(ARTICLR/ARTSTK ARTICLE)
A EDTCDE(3)
A 51 COLOR(RED)
A* Le format de contrôle
A R SF1CTL SFLCTL(SFL1)
A SFLSIZ(0013)
A SFLPAG(0012)
A OVERLAY
A N31 SFLDSPCTL
A N32 SFLDSP
A 31 SFLCLR
A 90 SFLEND(*MORE)
A RANG 4S 0H SFLRCDNBR
A 1 2'ARTSFL'
A 1 25'Sous-fichier Articles - Statique'
A DSPATR(HI)
A 1 71DATE
A EDTCDE(Y)
A 2 71TIME
A 3 2'Afficher à partir de :'
A SCODE 5A B 3 25
A 3 34'(Code article)'
A 5 2'Indiquez vos options, puis appuyez-
A sur ENTREE.'
A COLOR(BLU)
A 6 3'5=Afficher'
A COLOR(BLU)
A 61 7 2'Aucun article à partir de ce code.'
A COLOR(RED)
A 8 2'Opt'
A DSPATR(HI)
A 8 7'Code'
A DSPATR(HI)
A 8 16'Libellé'
A DSPATR(HI)
A 8 50'Stock'
A DSPATR(HI)
A* Les touches de fonction
A R FKEY1
A OVERLAY
A 23 2'F3=Exit'
A COLOR(BLU)
A 23 13'F5=Réafficher'
A COLOR(BLU)
A* Option 5 : la fenêtre d'affichage
A R FMT5
A WINDOW(*DFT 9 44)
A WDWTITLE((*TEXT 'Affiche Article'))
A WDWBORDER((*COLOR YLW) (*DSPATR RI)-
A (*CHAR '<.>::<.>'))
A E5COD R O 3 14REFFLD(ARTICLR/ARTCOD ARTICLE)
A DSPATR(HI)
A E5LIB R O 4 14REFFLD(ARTICLR/ARTLIB ARTICLE)
A DSPATR(HI)
A E5STK R Y O 5 14REFFLD(ARTICLR/ARTSTK ARTICLE)
A EDTCDE(3)
A DSPATR(HI)
A 3 1'Code . . :'
A 4 1'Libellé . :'
A 5 1'Stock . . :'
A 7 1'Entrée ou F12=Retour'
A COLOR(BLU)
A* Le sous-fichier de messages, en ligne 24
A R MSGSFLD SFL
A SFLMSGRCD(24)
A MSGKEY SFLMSGKEY
A PGMPRC SFLPGMQ(10)
A R MSGSFLH HELP
A SFLDSPCTL
A SFLCTL(MSGSFLD)
A SFLPAG(0001)
A SFLSIZ(0002)
A SFLDSP
A SFLINZ
A N25 SFLEND
A PGMPRC SFLPGMQ(10)
E1COD R O 9 7REFFLD(ARTICLR/ARTCOD ARTICLE)- Les zones de la ligne portent un préfixe par format (E1 pour SFL1, E5 pour la fenêtre FMT5) et
prennent leur définition dans le PF par
REFFLD: le R en colonne 29. E1STK R Y O 9 50etEDTCDE(3)- Le stock, repris du PF mais affiché en type
Ypour pouvoir l'éditer ;51 COLOR(RED)le met en rouge quand il vaut zéro. SFLSIZ(0013)etSFLPAG(0012)- Une ligne de plus que la page : le sous-fichier est statique et le système l'agrandit au chargement.
RANG 4S 0H SFLRCDNBR- La même zone RANG sert de rang d'écriture (SFILE) et de page à afficher (SFLRCDNBR).
SCODE 5A B 3 25- La zone de positionnement « Afficher à partir de ».
61 … 'Aucun article à partir de ce code.'- Le message de liste vide, sur la ligne 7, libre (voir le piège plus bas).
R FMT5,WINDOW,WDWTITLE,WDWBORDER- La fenêtre de l'option 5, avec son titre et sa bordure.
R MSGSFLD … SFLPGMQ(10)etR MSGSFLH- Le sous-fichier des messages du programme, en ligne 24 : le programme met son nom dans
PGMPRCavant de l'écrire. Il fait partie du gabarit ; dans cet exemple, le programme n'envoie aucun message, la ligne 24 reste donc vide.
CRTDSPF FILE(JOBISFL/ARTSFL) SRCFILE(JOBISFL/QDDSSRC)
RPG III SFL3
En RPG III
FARTSFL CF E WORKSTN
F RANG KSFILE SFL1
FARTICLE IF E K DISK
C* SFL3 : les articles en sous-fichier statique
C MOVEL'SFL3' PGMPRC
C MOVE *BLANKS POS 5
C Z-ADD0 SAUV 40
C EXSR CHARGE
C* Boucle principale : F3 pour sortir
C *IN03 DOWEQ'0'
C WRITEMSGSFLH
C WRITEFKEY1
C EXFMTSF1CTL
C *IN03 IFEQ '0'
C* Afficher à partir d'un code : on recharge depuis ce code
C SCODE IFNE *BLANKS
C MOVE SCODE POS
C MOVE *BLANKS SCODE
C EXSR CHARGE
C ELSE
C* F5 : réafficher depuis le début
C *IN05 IFEQ '1'
C MOVE *BLANKS POS
C EXSR CHARGE
C ELSE
C* Entrée : traiter les options, puis recharger
C EXSR TRTOPT
C EXSR CHARGE
C SAUV IFGT 0
C *IN32 ANDEQ'0'
C Z-ADDSAUV RANG
C ENDIF
C ENDIF
C ENDIF
C ENDIF
C ENDDO
C SETON LR
C*
C* CHARGE : vider, puis charger tout le sous-fichier
C CHARGE BEGSR
C Z-ADD0 RANG
C SETON 31
C WRITESF1CTL
C SETOF 31
C SETOF 329061
C POS SETLLARTICLE
C READ ARTICLE 50
C *IN50 DOWEQ'0'
C RANG ANDLT9999
C ADD 1 RANG
C MOVE ARTCOD E1COD
C MOVE ARTLIB E1LIB
C Z-ADDARTSTK E1STK
C ARTSTK COMP 0 51
C WRITESFL1
C READ ARTICLE 50
C ENDDO
C *IN50 IFEQ '1'
C SETON 90
C ENDIF
C RANG IFEQ 0
C SETON 3261
C ELSE
C Z-ADD1 RANG
C ENDIF
C ENDSR
C*
C* TRTOPT : les lignes où une option a été saisie
C TRTOPT BEGSR
C Z-ADD0 SAUV
C READCSFL1 91
C *IN91 DOWEQ'0'
C OPT IFEQ '5'
C MOVE E1COD E5COD
C MOVE E1LIB E5LIB
C Z-ADDE1STK E5STK
C EXFMTFMT5
C ENDIF
C Z-ADDRANG SAUV
C READCSFL1 91
C ENDDO
C ENDSR
F RANG KSFILE SFL1- La continuation de la spécification F : la zone du rang en 47-52,
Ken 53,SFILEen 54-59, le format en 60-67. CHARGE BEGSR- Vider (31), éteindre 32, 90 et 61, se positionner par
SETLLsur le code saisi, puis écrire une ligne par article. En fin de fichier, 90 affiche « Fin » ; si rien n'a été écrit, 32 cache les lignes et 61 affiche le message. Sinon RANG revient à 1 : première page. *IN50 DOWEQ'0'etRANG ANDLT9999- On s'arrête à la fin du fichier ou à 9999 lignes, la limite d'un sous-fichier.
ARTSTK COMP 0 51- 51 (colonnes 58-59, « égal ») allumé si le stock est nul : la ligne s'affiche en rouge.
TRTOPT BEGSRREADClit les lignes où une option a été saisie ; l'option 5 ouvre la fenêtre FMT5. Le rang de la dernière ligne traitée est gardé dans SAUV.Z-ADDSAUV RANG- Après le rechargement, RANG reprend ce rang : l'écran revient sur la page où l'on travaillait.
CRTRPGPGM PGM(JOBISFL/SFL3) SRCFILE(JOBISFL/QRPGSRC)
RPG IV colonné SFL4
En RPG IV colonné
FARTSFL CF E WORKSTN SFILE(SFL1:RANG)
FARTICLE IF E K DISK
D* SFL4 : les articles en sous-fichier statique
DPOS S 5A
DSAUV S 4S 0
DSFLMAX C 9999
C EVAL PGMPRC = 'SFL4'
C EXSR CHARGE
C* Boucle principale : F3 pour sortir
C DOW NOT *IN03
C WRITE MSGSFLH
C WRITE FKEY1
C EXFMT SF1CTL
C SELECT
C WHEN *IN03
C LEAVE
C WHEN SCODE <> *BLANKS
C EVAL POS = SCODE
C EVAL SCODE = *BLANKS
C EXSR CHARGE
C WHEN *IN05
C EVAL POS = *BLANKS
C EXSR CHARGE
C OTHER
C EXSR TRTOPT
C EXSR CHARGE
C IF SAUV > 0 AND NOT *IN32
C EVAL RANG = SAUV
C ENDIF
C ENDSL
C ENDDO
C EVAL *INLR = *ON
C*
C* CHARGE : vider, puis charger tout le sous-fichier
C CHARGE BEGSR
C EVAL RANG = 0
C EVAL *IN31 = *ON
C WRITE SF1CTL
C EVAL *IN31 = *OFF
C EVAL *IN32 = *OFF
C EVAL *IN90 = *OFF
C EVAL *IN61 = *OFF
C POS SETLL ARTICLE
C READ ARTICLE
C DOW NOT %EOF(ARTICLE) AND RANG < SFLMAX
C EVAL RANG = RANG + 1
C EVAL E1COD = ARTCOD
C EVAL E1LIB = ARTLIB
C EVAL E1STK = ARTSTK
C EVAL *IN51 = (ARTSTK = 0)
C WRITE SFL1
C READ ARTICLE
C ENDDO
C EVAL *IN90 = %EOF(ARTICLE)
C IF RANG = 0
C EVAL *IN32 = *ON
C EVAL *IN61 = *ON
C ELSE
C EVAL RANG = 1
C ENDIF
C ENDSR
C*
C* TRTOPT : les lignes où une option a été saisie
C TRTOPT BEGSR
C EVAL SAUV = 0
C READC SFL1
C DOW NOT %EOF(ARTSFL)
C IF OPT = '5'
C EVAL E5COD = E1COD
C EVAL E5LIB = E1LIB
C EVAL E5STK = E1STK
C EXFMT FMT5
C ENDIF
C EVAL SAUV = RANG
C READC SFL1
C ENDDO
C ENDSR
WORKSTN SFILE(SFL1:RANG)- SFILE devient un mot-clé de la spécification F, en colonnes 44 à 80.
DSFLMAX C 9999- Une constante nommée pour la limite.
SELECT…WHEN…OTHER- Les trois cas de la boucle : un code saisi, F5, ou Entrée pour traiter les options.
EVAL *IN90 = %EOF(ARTICLE)- La fin du fichier se teste par
%EOF, sans indicateur sur le READ.
CRTBNDRPG PGM(JOBISFL/SFL4) SRCFILE(JOBISFL/QRPGLESRC)
Full free SFLF
En RPG full free
**FREE
// SFLF : les articles en sous-fichier statique
ctl-opt dftactgrp(*no) actgrp(*caller);
dcl-f ARTSFL workstn sfile(SFL1:RANG);
dcl-f ARTICLE keyed;
dcl-s pos char(5);
dcl-s sauv zoned(4:0);
dcl-c SFLMAX 9999;
dcl-c AFFICHER '5';
PGMPRC = 'SFLF';
charge();
// Boucle principale : F3 pour sortir
dow not *in03;
write MSGSFLH;
write FKEY1;
exfmt SF1CTL;
select;
when *in03;
leave;
// Afficher à partir d'un code : on recharge depuis ce code
when SCODE <> *blanks;
pos = SCODE;
clear SCODE;
charge();
// F5 : réafficher depuis le début
when *in05;
clear pos;
charge();
// Entrée : traiter les options, puis recharger
other;
trt_readc();
charge();
if sauv > 0 and not *in32;
RANG = sauv;
endif;
endsl;
enddo;
*inlr = *on;
// Vider, puis charger tout le sous-fichier
dcl-proc charge;
RANG = 0;
*in31 = *on;
write SF1CTL;
*in31 = *off;
*in32 = *off;
*in90 = *off;
*in61 = *off;
setll pos ARTICLE;
read ARTICLE;
dow not %eof(ARTICLE) and RANG < SFLMAX;
RANG += 1;
E1COD = ARTCOD;
E1LIB = ARTLIB;
E1STK = ARTSTK;
*in51 = (ARTSTK = 0);
write SFL1;
read ARTICLE;
enddo;
*in90 = %eof(ARTICLE);
if RANG = 0;
*in32 = *on;
*in61 = *on;
else;
RANG = 1;
endif;
end-proc;
// Les lignes où une option a été saisie
dcl-proc trt_readc;
sauv = 0;
readc SFL1;
dow not %eof(ARTSFL);
if OPT = AFFICHER;
E5COD = E1COD;
E5LIB = E1LIB;
E5STK = E1STK;
exfmt FMT5;
endif;
sauv = RANG;
readc SFL1;
enddo;
end-proc;
ctl-opt dftactgrp(*no) actgrp(*caller);- Indispensable ici : les routines sont des procédures (
dcl-proc), donc des appels liés, interdits avec le groupe d'activation par défaut. dcl-f ARTSFL workstn sfile(SFL1:RANG);- L'écran et son sous-fichier, en une déclaration.
dcl-proc charge;etdcl-proc trt_readc;- Les deux routines du RPG III, devenues des procédures.
dcl-c AFFICHER '5';- Les options en constantes nommées : le code se lit
if OPT = AFFICHER.
CRTBNDRPG PGM(JOBISFL/SFLF) SRCFILE(JOBISFL/QRPGLESRC)
Le résultat, identique pour les trois
SFL3, SFL4 et SFLF ont été appelés tour à tour avec le même scénario en huit étapes : première page, page suivante, option 5 sur A0016, fenêtre, retour, « Afficher à partir de » A0025, puis Z, puis F5. À chaque étape, les trois écrans sont identiques, au caractère près (date et heure mises à part).







Le piège : SFLMSG sur une liste vide
Le réflexe, pour signaler une liste vide, est un message de sous-fichier sur le format de contrôle :
61 SFLMSG('Vide'). Essayé ici, il ne s'affiche jamais. IBM l'écrit dans la référence
des DDS : SFLMSG n'est traité que si SFLDSP est en vigueur. Or, ce gabarit gère une
liste vide justement en coupant SFLDSP (indicateur 32). Le message est donc une constante du format de contrôle, conditionnée
par 61, sur une ligne libre au-dessus du sous-fichier.
Sources
Les exemples ont été compilés et exécutés sur un IBM i 7.5 (voir la méthode). Les mots-clés et les règles viennent de ces sources, consultées le 16 octobre 2026 :
- IBM i Programming : DDS for display files, IBM (PDF). SFL, SFLCTL, SFLSIZ (9999 au plus, extension automatique quand SFLSIZ diffère de SFLPAG), SFLPAG, SFLDSP, SFLDSPCTL, SFLCLR, SFLEND, SFLRCDNBR, OVERLAY ; le défilement fait par le système quand SFLPAG diffère de SFLSIZ, et PAGEDOWN pour rendre la main au programme ; SFLMSG traité seulement si SFLDSP est en vigueur.
- ILE RPG Programmer's Guide (SC09-2507-12), IBM, IBM i 7.5 (PDF). Le sous-fichier, groupe d'enregistrements écrit puis affiché en une opération ; deux formats ; jusqu'à 12 sous-fichiers actifs ; le mot-clé SFILE(format:zone) sur un fichier WORKSTN décrit en externe.
- ILE RPG Reference (SC09-2508-12), IBM, IBM i 7.5 (PDF). Les opérations WRITE, READC, UPDATE et EXFMT sur un fichier WORKSTN.
Questions fréquentes
Qu'est-ce qu'un sous-fichier sur IBM i ?
Un groupe d'enregistrements d'un même format, écrit dans un fichier écran puis affiché en une fois sous forme de liste. Il se décrit en DDS par deux formats : le format du sous-fichier (SFL), une ligne de la liste, et le format de contrôle (SFLCTL), qui l'affiche, le vide et porte l'en-tête.
Quelle différence entre SFLSIZ et SFLPAG ?
SFLPAG est le nombre de lignes affichées sur une page ; SFLSIZ le nombre d'enregistrements que le sous-fichier peut contenir, 9999 au plus. Quand SFLSIZ diffère de SFLPAG, le système étend le sous-fichier si on écrit au-delà de SFLSIZ, et fait défiler les pages lui-même.
Quel type de sous-fichier choisir ?
Le sous-fichier statique, chargé en une fois : SFLSIZ plus grand que SFLPAG, on écrit tous les enregistrements, et le système gère Page suivante et Page précédente sans revenir au programme. C'est le code le plus court et le plus sûr ; au-delà de quelques milliers de lignes, on ajoute une zone de positionnement plutôt que de changer de méthode.
Comment savoir quelles lignes l'utilisateur a modifiées ?
Avec READC (Read Changed) sur le format du sous-fichier : il lit seulement les enregistrements modifiés, et la zone du numéro d'enregistrement (déclarée par SFILE) reçoit leur rang.
Pourquoi SFLMSG n'affiche-t-il rien quand la liste est vide ?
Parce que SFLMSG et SFLMSGID ne sont traités que si SFLDSP est en vigueur. Une liste vide se gère en coupant SFLDSP : le message doit alors être une constante du format de contrôle, conditionnée par un indicateur, ou un message du programme dans le sous-fichier de messages.
Pourquoi le sous-fichier revient-il à la première page après Entrée ?
Parce que, sans indication, le système affiche la première page. Une zone cachée avec le mot-clé SFLRCDNBR dans le format de contrôle indique quelle page afficher : celle qui contient le numéro d'enregistrement donné.