COBOL et hypercube (même si le hypercube n'est pas le terme le plus adapté)
COBOL et hypercube, quelle drôle d'idée.
Un hypercube est "une représentation abstraite d'informations multidimensionnelles" nous dit Wiki, définition qui ne nous aide pas beaucoup, pour ne pas dire pas du tout. Quand on vous a expliqué l'hypercube, on a ajouté "et je n'arrive pas à imaginer ce qu'est un hypercube".
Alors, revoyons la définition. Mais, d'abord, un exemple compréhensible d'hypercube : la commode.
Une commode est un meuble à tiroirs, imaginez que les tiroirs contiennent des boites à bijoux, ces boites sont compartimentées, chaque compartiment va contenir une montre ou un collier. Pour peu qu'il y ait plusieurs meubles dans la pièce, une bijouterie par exemple, vous ajoutez un niveau.
Vous avez une représentation plus claire d'un hypercube.
Une table indicée par année, mois, jour, genre et province devient plus claire si on la compare à une commode.
La définition devient "Un hypercube est un cube qui contient un cube ou un hypercube".
COBOL est limité à 3 indices.
Oui.
On revient à la première ligne : COBOL et hypercube, quelle drôle d'idée.
Impossible d'avoir plus de 3 indices ?
Une table est une donnée comme une autre, rien n'empêche de mettre une table dans une table, comme on met une boite dans un tiroir.
Un exemple pratique.
(pratique ne veut pas réel, le fichier que je vais utiliser est tout sauf réel, ce n'est pas l'objet de ce post).
Voyons le fichier suivant :
DT-NAISS (AAAAMMJJ ou blanc)
DT-DEC (AAAAMMJJ ou blanc)
GENRE
PROVINCE
et la demande :
Sortir un tableau donnant, par jour, le nombre de naissances ou de décès, par genre et par province.
La méthode habituelle est assez simple, on crée un record contenant les donnée auxquelles on ajoute un code (naissance ou décès) et on trie.
Simple.
Simple mais pas toujours rapide surtout si vos données sont nombreuses.
Utiliser un hypercube permet d'éviter le tri, le travail se ramenant à compter directement en mémoire.
Comment faire ?
Le problème est : ajouter 1 dans CTR(iAnnée, iMois, iJour, iGenre, iProvince, iNaissance/Décès).
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
01 TOUTES-LES-TABLES.
05 INDICES-ET-MAXIMA.
10 IANNEE PIC 9(5) COMP-3.
10 IMOIS PIC 9(5) COMP-3.
10 IJOUR PIC 9(5) COMP-3.
10 IGENRE PIC 9(5) COMP-3.
10 IPROV PIC 9(5) COMP-3.
10 INAIS-DEC PIC 9(5) COMP-3.
10 MAXANNEE PIC 9(5) COMP-3 VALUE 150.
10 MAXMOIS PIC 9(5) COMP-3 VALUE 12.
10 MAXJOUR PIC 9(5) COMP-3 VALUE 31.
10 MAXGENRE PIC 9(5) COMP-3 VALUE 2.
10 MAXPROV PIC 9(5) COMP-3 VALUE 11.
10 MAXNAIS-DEC PIC 9(5) COMP-3 VALUE 2.
10 ANNEE-REF PIC 9(5) COMP-3.
05 TABLE-CTRL-PRNT.
11 ANNEE OCCURS 150.
12 MOIS OCCURS 12.
13 JOUR OCCURS 31.
15 CTRL-PRNT PIC X.
05 TABLE-DES-COMPTEURS1.
11 ANNEE OCCURS 150.
12 MOIS OCCURS 12.
13 JOUR OCCURS 31.
15 DONNEES-DU-JOUR1 PIC X(66).
05 DONNEES-DU-JOUR.
11 GENRE OCCURS 2.
12 PROVINCE OCCURS 11.
15 CTR PIC 9(5) COMP-3. |
TABLE-CTRL-PRNT est nécessaire pour éviter l'impression de pages blanches. Le format de la table sera fonction du format d'impression, ici, une page par jour.
La table DONNEES-DU-JOUR a une longueur de 66 caractères (2 x 11 x 3), c'est cette longuer qui justifie le 66 de la PIC X(66) de DONNEES-DU-JOUR1.
Quant à ANNEE-REF, nécessaire au calcul de l'indice iAnnée, elle contiendra (année du jour + 1).
Procédure :
- Remplir IGENRE
- Remplir IPROV
- si NAISSANCE (niveau 88)
- INAIS-DEC = 1
- calculer IANNEE = ANNEE-REF - ANNEE-NAIS
- Si IANNEE > MAXANNEE message d'erreur (plus de 150 ans)
sinon
- remplir les indices iMois et iJour
- ajouter 1 au compteur
- si DECES(niveau 88)
- INAIS-DEC = 2
- calculer IANNEE = ANNEE-REF - ANNEE-DEC
- Si IANNEE > MAXANNEE message d'erreur (plus de 150 ans)
sinon
- remplir les indices iMois et iJour
- ajouter 1 au compteur
"Ajouter 1 au compteur" est une simple fonction :
Code:
1 2 3 4 5 6
| ADD-TO-CTR.
MOVE DONNEES-DU-JOUR1( IANNEE IMOIS IJOUR ) TO DONNEES-DU-JOUR
ADD 1 TO CTR ( IGENRE IPROV INAIS-DEC)
MOVE DONNEES-DU-JOUR TO DONNEES-DU-JOUR1( IANNEE IMOIS IJOUR )
MOVE '*' TO CTRL-PRNT ( IANNEE IMOIS IJOUR )
. |
Pour initialiser TABLE-DES-COMPTEURS1, il faut initialiser DONNEES-DU-JOUR et recopier la table dans DONNEES-DU-JOUR1 en incrémentant les indices.
Plus simple il n'y a pas.