Un peu d'histoire
La direction C2 de l'O.C.R., direction qui s'occupe du transport de personnes (OM & BC, Bus - Cars et Minibus) sera la première direction à étaler ses paiements sur l'année.
Jusque là, la perception était organisée annuellement, le gros travail commençant en octobre par la formation des listes, pour se terminer en janvier par la clôture des paiements. Le reste de l'année étant occupé par l'exploitation du fichier, listes et statistiques diverses étant fournies au Ministre, à la direction ou à l'extérieur.
C'est en 1988 que les modifications des programmes sont prévues, nouveau dessin de fichier, création de la moulinette et adaptation de 150 programmes sont nécessaires. Délais généreusement offert par l'administration pour ce faire : 3 mois.
3 mois sont un délai un peu juste.
Heureusement, les programmeurs savaient le travail à faire, certains
ayant participé aux réunions de travail préliminaires à la création de
l'A.R. obligatoire, le fichier est
dessiné avant l'annonce officielle du travail, la moulinette écrite et
testée avant que ce dessin soit officiellement accepté.
L'idée m'est venue, je ne sais plus trop comment, de saucissonner les programmes ; j'utilisais déjà les paramètres pour les recherches, cette idée s'est vite imposée comme la seule qui permette de garantir un travail rapide.
- 147 sélections différentes mais limitées à 6 ou 7 champs ;
- une clef de tri unique ;
- une quinzaine de formats de mise en page pour les listes ;
- une dizaine de mise en page pour les « statistiques ».
On ramènera toutes ces valeurs à :
- 6 ou 7 champs de recherche ;
- deux programmes de sélection, avec et sans tri ;
- une quinzaine de programmes d'impression de listes ;
- une dizaine de programmes d'impression de « statistiques ».
25 programmes à écrire au lieu de 147, on a déjà bien gagné sa journée.
Structurer
Programme structuré
Les principaux objectifs de la programmation structurée sont les suivants :
- le développement modulaire du programme ;
- la facilité du codage ;
- la rapidité du codage ;
- la facilité du débogage ;
- la facilité de la maintenance.
Source : Université Laval, Formation1-cobol, Immed Jarras (pdf)
Application structurée
Les principaux objectifs de la structuration d'une application sont les suivants :
- le développement modulaire du programme ;
- la facilité du codage ;
- la rapidité du codage ;
- la facilité du débogage ;
- la facilité de la maintenance ;
- l'augmentation des capacités d'exploitation du fichier.
Les objectifs sont identiques à un détail près : structurer une application augmente la capacité d'interroger le fichier de base.
Au travail
Fichier
Étaler le travail sur l'année au lieu de le conserver concentré sur 3 mois ne peut se faire qu'à la condition de remplacer le paiement annuel à date fixe par un paiement annuel à une date anniversaire, la date d'immatriculation par exemple. C'est ce qui a été fait.
Second changement important, une première à l'O.C.R., si le trop perçu n'est pas (encore) remboursé, il est déduit des futures sommes à payer. Sous certaines conditions, bien sûr.
C'est le premier travail à effectuer.
Le nouveau fichier comportera des dates (demande de paiement, rappel éventuel, paiement, validité de l'autorisation, etc.) et des montants (demandé, payé, solde éventuel, etc.) que l'ancien ne connaissait pas. An 2000 oblige, les dates sont déjà prévues en 8 caractères. Dernière particularité de la description du fichier, elle est plus longue que le fichier lui-même… La normalisation des noms est possible grâce à l'appel d'une routine ASSEMBLER après quelques MOVE. Pour éviter cette douzaine d'instructions, le fichier est dessiné avec, à la fin, les zones nécessaires au CALL et les 32 caractères indispensables à la réponses.
Moulinette
La moulinette, simple outil de transformation de format, doit prévoir la somme à payer. C'est, à peu près, le seul calcul.
C'est le second travail à effectuer.
Et si le dessin du fichier n'est pas accepté, tu auras travaillé
pour rien.
Non.
À moins que je sois totalement con, ce que je ne pense pas du tout
(même si c'est possible), le dessin proposé correspond à la demande
telle que je l'ai comprise. Et si j'ai mal compris, tout ne sera pas à
refaire.
Explications.
Il n'y aura pas d'item inutile puisqu'ils viennent de l'ancien
dessin.
Il pourrait en manquer ?
Oui.
Si c'est le cas, il faut modifier le dessin du fichier et écraser
l'ancienne version par la nouvelle, modifier la moulinette et compiler
les programmes déjà écrits. C'est tout.
La zone manquante n'a jamais été utilisée (sinon, je me serais aperçu
de son absence), ça s'arrête là, le programme déjà écrit tournera avec
le nouveau dessin.
Dessiner le fichier, programmer la moulinette, OK, on peut commencer sans attendre la réunion sur le dessin.
Programmes
Pour réduire le nombre de programmes à écrire, il faut examiner la structure des programmes existants. Cette structure est assez simple et, généralement, standard.
|
LST | RPT | STA | VIR |
---|---|---|---|---|
utilisé dans C2 | O | N | O | N |
sélectionner | O | O | O | O |
trier | O | O | N/O | O |
imprimer | O | O | O | O |
Le tableau est clair, en dehors des statistiques qui n'imposent pas un tri, les étapes d'un programme sont les mêmes pour tous, on imprime après avoir trié ce qu'on a sélectionné.
Pourquoi ne pas lier VIR et LST ?
Les virements sont une triple impression, la liste, la facture et le
bulletin lui-même, la partie PRNT sera totalement différente.
À l'O.C.R., le Report de COBOL n'était pas utilisé, c'est dommage, quant aux virements, ils étaient imprimés aux Finances.
Structurer l'application, gagner du temps en simplifiant grandement
le travail, consistera à séparer la sélection, le tri et l'impression.
C'est simple.
Reste à le faire.
Le code qui suit ne respecte pas les colonnes de COBOL et ce, simplement parce que LaTeX n'a pas les 80 colonnes nécessaires.
C2STA01
147 programmes d'exploitation à écrire et le premier à y passer est
un programme de statistiques. Avant même le programme de sélection.
Pourquoi ?
La réponse tient en peu de mots :
- les statistiques n'imposent pas de tri ;
- les statistiques s'impriment sur peu de pages ;
- le dessin du fichier n'est pas encore arrêté.
Ça vous semble bizarre ?
Pas à moi.
Une dizaine de formats de mise en page pour les statistiques doivent
se ramener à une dizaine de programmes d'impression.
Une dizaine de programmes d'impression, cela signifie que certaines
données ne peuvent être programmées, elles devront être variables et,
partant, être paramétrées.
- Le titre de l'impression ;
- le nom du destinataire / demandeur du travail ;
- la langue de la demande.
Le premier programme écrit le sera avec deux idées bien différentes en tête, chaque idée étant traitée au bon moment :
- avoir une apparence correcte, sans égard aux résultats affichés ;
- avoir des résultats exacts, l'apparence n'est plus un souci.
Titre de l'impression
Ophain-Bois-Seigneur-Isaac-lez-Nivelles est un nom de commune un peu plus long que Huy. Si l'impression veut être agréable à l’œil, il faut centrer le titre, « Immatriculations à Huy » ne se place pas au même endroit que pour l'autre commune.
Code programme, code carte, il reste environ 72 caractères pour le titre. Il suffit de compter le nombre de caractères blancs à l'arrière du titre pour en savoir la longueur. Si la zone dans laquelle on a recopié la carte est une table on centre facilement sur la ligne d'impression du titre (L02-TITRE) et on souligne de la même manière et en même temps (L03-TITRE).
05 TITRE-WS PIC X(72) VALUE 'C2STA01'.
05 FILLER REDEFINES TITRE-WS.
10 CARACTERE-WS PIC X OCCURS 72.
05 L2.
10 FILLER PIC X.
10 FILLER PIC X(30) VALUE SPACE.
10 L02-CARACTERE PIC X OCCURS 72.
TITRE-WS
est initialisé avec le nom du programme pour le
cas où la carte titre manquerait.
Nom du destinataire
J'ai toujours eu pour habitude de mettre mon nom sur les
impressions, histoire d'éviter de voir mes tests partir par la poste
en direction d'un client. L'endroit prédestiné pour ça, la première
ligne, L01-NOM
, initialisé avec nom, local et n° de
téléphone, verra son contenu remplacé par celui du demandeur. Si la
carte est manquante, le résultat me sera envoyé, le client recherché,
le batch relancé après correction.
Ma ligne de titre, L01
standard.
05 L01.
10 FILLER PIC X.
10 L01-NOM PIC X(96)
VALUE 'BRISCHRI - A L*ETAGE - 6511'.
10 L01-DATE PIC X(28).
10 L01-PAGE PIC -(6)9.
10 FILLER PIC X VALUE '-'.
Ceux qui se demandent pourquoi tous mes programmes contiennent la ligne
TRANSFORM L01-NOM FROM '*' TO QUOTE
devraient avoir compris maintenant : dans L01-NOM
les
apostrophes sont remplacées par des astérisques, ça évite de compter
la longueur de la zone avant l'apostrophe, d'ajouter un FILLER
PIC X VALUE QUOTE
et de terminer par ce qu'il reste des 96
caractères.
Langue de la demande
La Belgique a la chance d'être un pays polyglotte où la langue de chacun est respectée. Les langues nationales sont, par ordre alphabétique, l'allemand, le français et le néerlandais, pour ne pas compliquer les choses, on y ajoutera l'anglais.
Demander à savoir la langue du demandeur n'est pas une coquetterie,
la langue est nécessaire pour remplir correctement L01-DATE
et initialiser les titres de colonnes. L01-DATE
est
rempli à l'aide d'une routine ASSEMBLER :
CALL routine-date USING(L01-DATE,RL)
Sans RL
, pas de date en long (plus exactement, elle
serait en FR, pas gênant pour un francophone, pas grave pour un
germanophone ou un anglophone mais il y aura réunion d'un comité de
crise si le destinataire est anversois).
Sans RL
, pas de titre de colonne. Les titres sont dans
une table et la bonne ligne est recopiée sur L04-TITRE
,
tout simplement.
Nom du destinataire et langue de la demande sont sur la même carte paramètre.
Reste
La suite est beaucoup plus simple, c'est de la programmation
standard, faire en sorte que le résultat affiché soit bien celui
escompté. Ce premier programme servira de modèle pour tous les autres,
aussi bien pour la série C2STAnn
que C2LST01
.
L'écriture de C2STA02
attendra, il y a des choses plus
urgentes.
C2LST01
Une liste simple, la plus simple possible, sans rupture.
Ne pas avoir de saut de page parce qu'on change de commune ou de
constructeur.
Surtout, ne pas oublier de signaler aux opérateurs qu'il ne s'agit que
d'un test, qu'il ne faut surtout pas imprimer. Le reste est un travail
normal, il faudra veiller à traduire les noms de colonne
(heureusement, une des traductrices a compris l'idée, elle m'a traduit
la plupart des noms des champs, pour nommer les colonne j'ai un point
de départ superbe, quel que soit le programme, les colonnes auront le
même intitulé si elles contiennent la même valeur).
C2LST01
sera le modèle de base de tous les C2LSTnn
.
C2SEL
La sélection est la partie la plus simple : on compare l'enregistrement à certains critères, on conserve ou non selon le résultat de la comparaison.
Lorsque les critères sont des paramètres sur carte, il faut d'abord gérer les cartes, enregistrer les paramètres, signaler qu'il y en a trop, imprimer la liste en fin de gestion des cartes. Pas trop compliqué, il faut être organisé. Selon que le paramètre sera divisible (le code INS d'une commune correspond à une commune mais permet de savoir la province et l'arrondissement de la commune) ou non (le code postal ne vous dira rien quant à la position de la commune), son enregistrement sera plus ou moins simple, mais rien de vraiment complexe, plus tard, au moment des sélections, on aura la même chose, ce sera +/- simple.
Code postal
01 TOUS-LES-PARAMETRES.
...
05 TABLE-CODES-POSTAUX.
10 CTR-POST PIC 9(5) COMP-3 VALUE 0.
10 MAX-POST PIC 9(5) COMP-3 VALUE 5.
10 TABLE-CPOST.
11 FILLER OCCURS 5.
15 T-CPOST PIC X(4).
MAX-POST
et la longueur de la table sont identique, si
OCCURS 5
passait à 6, il faudrait modifier la valeur de MAX-POST
en la passant à 6 elle aussi.
Enregistrement
Ajouter 1 à CTR-POST
, si on obtient plus que la valeur
de MAX-POST
, il faut traiter l'erreur (message à la
console, -1 – ce qui permet de continuer le travail – et on passe à la
carte suivante), sinon, on enregistre le code postal dans T-CPOST(CTR-POST)
.
Fin d'enregistrement
Lorsque les paramètres de recherche sont enregistrés, on repasse par toutes les tables, la valeur de CTR devient celle de MAX (si la table est vide, MAX sera égal à zéro, inutile de lancer la recherche sur le paramètre).
Recherche
IF A_CONSERVER AND MAX-POST GREATER THAN 0
SET A_REJETER TO TRUE
MOVE 1 TO CTR-POST
PERFORM UNTIL CTR-POST > MAX-POST
IF CPOST-C2 = T-CPOST(CTR-POST)
SET A_CONSERVER TO TRUE
ADD MAX-POST TO CTR-POST
ENDIF
ADD 1 TO CTR-POST
END-PERFORM
ENDIF
Code INS
01 TOUS-LES-PARAMETRES.
...
05 TABLE-CODES-INS.
10 CTR-INS PIC 9(5) COMP-3 VALUE 0.
10 MAX-INS PIC 9(5) COMP-3 VALUE 5.
10 TABLE-CINS.
11 FILLER OCCURS 5.
15 T-TYP-INS PIC X.
15 T-COMM-INS.
20 T-ARROND-INS.
25 T-PROV-INS PIC X.
25 F-ARROND-INS PIC X.
20 F-COMM-INS PIC XXX.
Le premier caractère du code est le code de la province, les deux
premiers ensemble forment le code de l'arrondissement, le tout est le
code, unique, de la commune.
Pour plus d'informations sur les codes INS des communes, voir le site
Statbel, la Belgique en chiffres .
Rechercher sur ce code ne se fait pas de la même manière que pour un
code postal : la recherche doit pouvoir se faire sur une partie du
code.
Pour ce faire, il faudra définir le code INS comme étant un groupe. Il
faudra interroger les morceaux qui peuvent être vides, non remplis,
d'où les FILLER nommés (F-ARROND-INS
et F-COMM-INS
)
Enregistrement
MOVE INS-CARD TO T-COMM-INS(CTR-INS)
MOVE '1' TO T-TYP-INS(CTR-INS)
IF F-COMM-INS(CTR-INS) = SPACE
MOVE '2' TO T-TYP-INS(CTR-INS)
IF F-ARROND-INS(CTR-INS) = SPACE
MOVE '3' TO T-TYP-INS(CTR-INS)
ENDIF
ENDIF
Recherche
IF A_CONSERVER AND MAX-INS GREATER THAN 0
SET A_REJETER TO TRUE
MOVE INS-C2 TO INS-WS
MOVE 1 TO CTR-INS
PERFORM UNTIL CTR-INS > MAX-INS
IF T-TYP-INS(CTR-INS) = "1" AND (T-COMM-INS(CTR-INS) = COMM-WS)
PERFORM INS_OK
ELSE IF T-TYP-INS(CTR-INS) = "2" AND (T-ARROND-INS(CTR-INS) = ARROND-WS)
PERFORM INS_OK
ELSE T-TYP-INS(CTR-INS) = "3" AND (T-PROV-INS(CTR-INS) = PROV-WS)
PERFORM INS_OK
ENDIF
ADD 1 TO CTR-INS
END-PERFORM
ENDIF
...
INS_OK.
SET A_CONSERVER TO TRUE
ADD MAX-INS TO CTR-INS
.
C2SRT
C2SRT
est simple puisqu'il n'y a qu'une seule clef de
tri, malgré ça, on va paramétrer le choix du tri… comme si plusieurs
étaient possible, imposer l'option 1 en cas d'absence de choix (ce qui
sera le cas tant qu'une seconde clef n'est pas nécessaire) et ne pas
donner de clef à l'option 2, ça permettra à celui qui reprend le
travail de savoir ce qu'il a à faire (et, surtout, montrer que le
traitement paramétré est prêt).
PROCEDURE DIVISION.
PERFORM INITIALISATION
IF CLE-TRI = "1"
PERFORM TRI-1
ELSE IF CLE-TRI = "2"
PERFORM TRI-2
ENDIF
STOP RUN
.
TRI-1.
SORT SD-C2
ON ASCENDING KEY
INS-C2
CPOST-C2
RL-C2
NOM_NORMALISE-C2
NOM-C2
USING FIC-IN GIVING FIC-OUT
.
TRI-2.
SORT SD-C2
ON ASCENDING KEY
RL-C2
NOM_NORMALISE-C2
NOM-C2
USING FIC-IN GIVING FIC-OUT
.
C2SRT
n'a jamais été écrit, la clef a été enregistrée
et mise en œuvre dans C2SEL02
.