COBOL - Flat to Indexed : transformation d'un fichier séquentiel en fichier séquentiel indexé

Présentation
Transformation d'un fichier séquentiel en fichier séquentiel indexé dédié au compilateur COBOL associé.

Deux sources sont mises à disposition :
- L'une avec seulement la transformation "normal" vers "indexé"
- L'autre avec un tri interne COBOL

Ce code est très utile sous Windows ou Linux pour obtenir des formats de fichiers nativement disponibles sur z/OS ou System i.
Nos ressources disponibles
Pour que l'indexation soit réellement efficace il est conseillé de trier, mais sur certains systèmes des programmes plus optimisés sont disponibles (DFSORT sur z/OS par exemple).
L'indexation d'un fichier peut "aussi" être naturelle via le format d'enregistrement : toujours sur z/OS, des VSAM de type KSDS (Key Sequenced DataSet) permettent d'indexer à l'écriture et COBOL sera en mesure d'utiliser ces index.

L'intérêt de ce programme se situe surtout dans le fait que les systèmes d'exploitations moins spécialisés ne proposent pas ces options, et qu'il devient donc nécessaire de laisser COBOL (et surtout son compilateur) générer un fichier indexé avec le format adapté à celui-ci.

Le fichier utilisé dans le code est fourni en exemple.

Attention aux niveaux des variables en WORKING-STORAGE SECTION !
Mes 2 compilateurs (OpenCOBOL 1.1 et TinyCOBOL) obligent à utiliser des niveaux 01, 66 ou 77 pour les structures ou variables simples.
Si vous aviez l'habitude d'utiliser d'autres niveaux avec d'autres compilateurs : n'hésitez pas à modifier mon code.

Merci à Hédhili Jaïdane, el_slapper, Pico----- et Luc Orient pour leurs conseils.
Détails
Catégories : Codes sources Cobol
Voir tous les téléchargements de l'auteur
Licence : BSD
Date de mise en ligne : 19 mars 2014




Avatar de escartefigue escartefigue - Expert confirmé https://www.developpez.com
le 23/06/2015 à 16:52
Je découvre tardivement ce post, si ce petit programme est sans doute utile pour les développeurs linux ou Windows, il est dommage que le source ne respectent pas les préconisations suivantes :

- Ne pas décrire les fichiers en FD mais seulement un filler + la clef qui est obligatoire si fichier indexé.
Cette habitude, une fois prise, évite que lors de maintenances, le développeur utilise ses zones dédiées à l'OS et qui sont source d'abend
en cas d'utilisation avant ou après ouverture des fichiers. Sans compter que le contenu des zones FD est inaccessible des outils de debugging,
et qu'il n'est pas formaté en cas de fichier de format variable

- Faire un read into c'est très bien, mais la zone réceptrice doit être en working storage
je doute qu'en l'état, le compilateur accepte, mais si ca passait à la compil, on perd tout intérêt d'un read into !

- Utiliser des file status, c'est très bien, mais alors pourquoi gérer une fin de fichier manuellement par un "AT END" autant aller jusqu'au bout de la démarche
et utiliser la valeur FS="10" qui est alimentée automatiquement par l'OS alors qu'on peut oublier le move manuel lors du AT END

- Initialiser la zone réceptrice d'un read into avant lecture ne sert à rien, le read into s'en chargera

- c'est dommage, en cas d'erreur grave, de faire un stop run plutôt qu'un cancel, de même, si clef en double, il est judicieux d'afficher non seulement
la valeur de cette clef, comme c'est le cas, mais aussi le rang de l'enregistrement, ce qui évite de chercher dans un fichier parfois très volumineux.

- tant qu'à faire de donner des noms parlants aux paragraphes, ce qui est très bien, il faut que ça corresponde au contenu, or, le paragraphe 200-OPEN-RATE
fait non seulement les open, mais aussi l'appel à la procédure principale, puis les close...

- il ne faut pas considérer tout statut différent de zéro comme une erreur lors d'un open : les valeur "97" (VSAM) et "41" sont acceptables à l'open
le plus simple est d'afficher un message + le FS si différent de zéro lors de l'open sans planter, puis de planter lors du read ou write si KO
(en affichant a nouveau un message et le file status)

- des balises de début et fin de working sont toujours les bienvenues en cas de plantage (01 filler pic x(nn) value 'deb working monprog")

- enfin, mais la je chipote, c'est dommage de déclarer des variables locales d'un ou deux octets sur des lvl 01 qui s'alignent sur 16, on charge inutilement la WSS
autant regrouper sous un 01 filler.

Je me doute que ce petit programme a été écrit rapidement pour rendre service, mes remarques ne sont donc pas une attaque en règle envers celui qui fait l'effort de proposer cet outil, mais plutôt des conseils à destination des développeurs peu expérimentés.
Avatar de Luc Orient Luc Orient - Membre émérite https://www.developpez.com
le 28/06/2015 à 17:25
Citation Envoyé par escartefigue  Voir le message
...
- Ne pas décrire les fichiers en FD mais seulement un filler + la clef qui est obligatoire si fichier indexé.
Cette habitude, une fois prise, évite que lors de maintenances, le développeur utilise ses zones dédiées à l'OS et qui sont source d'abend
en cas d'utilisation avant ou après ouverture des fichiers. Sans compter que le contenu des zones FD est inaccessible des outils de debugging,
et qu'il n'est pas formaté en cas de fichier de format variable

- Faire un read into c'est très bien, mais la zone réceptrice doit être en working storage
je doute qu'en l'état, le compilateur accepte, mais si ca passait à la compil, on perd tout intérêt d'un read into !

En rien convaincu par cette affirmation ( la première surtout ) qui gagnerait a être étayé par quelques références techniques ...

Je ne vois pas en quoi ça serait mieux de faire des READ INTO plutôt que des READ simples ... Mais je ne demande qu'à changer d'avis ...
Avatar de escartefigue escartefigue - Expert confirmé https://www.developpez.com
le 29/06/2015 à 8:56
bonjour,

Les avantages sont multiples :
- en cas d'utilisation d'un debugger, les données lues sont accessibles, alors que la FD ne l'est pas
- si l'on utilise des fichiers de format variable, les données sont automatiquement formatées correctement
- la zone WSS est accessible quelque soit la phase d'exécution du programme, alors que si l'on utilise une zone FD avant ou après open, le cancel est garanti
- si l'on fait un read simple, puis un move, on réinvente ce que fait très bien COBOL grace au read into, on ajoute inutilement une instruction, mais surtout il faut s'assurer que le move est immédiat, pour etre sur de rendre dispo les données lues aux outils de debugging
- en cas de dump, c'est plus facile de retrouver ses petits

Faire un read sans utiliser into est donc une erreur

Il en va de même pour le write : write from est recommandé, pour les mêmes raisons
Avatar de Luc Orient Luc Orient - Membre émérite https://www.developpez.com
le 29/06/2015 à 11:32
Citation Envoyé par escartefigue  Voir le message
bonjour,

Les avantages sont multiples :
- en cas d'utilisation d'un debugger, les données lues sont accessibles, alors que la FD ne l'est pas

tu as une référence technique à nous donner ?

- si l'on utilise des fichiers de format variable, les données sont automatiquement formatées correctement

je ne comprends pas l'argument ... dans tous les cas les données sont formatées comme la description du fichier ... bien sûr si celle ci est fausse ... mais c'est un autre débat ...

- la zone WSS est accessible quelque soit la phase d'exécution du programme, alors que si l'on utilise une zone FD avant ou après open, le cancel est garanti

la zone de FD est accessible après un READ, exécuté sans erreur bien sûr, et le reste jusqu'au READ suivant ... je ne vois que du très logique là ...

- si l'on fait un read simple, puis un move, on réinvente ce que fait très bien COBOL grace au read into, on ajoute inutilement une instruction, mais surtout il faut s'assurer que le move est immédiat, pour etre sur de rendre dispo les données lues aux outils de debugging - en cas de dump, c'est plus facile de retrouver ses petits

effectivement ... si je ne fais pas de READ INTO ce n'est pas pour faire un MOVE après ...

Faire un read sans utiliser into est donc une erreur

hélas toujours pas convaincu ...
Avatar de escartefigue escartefigue - Expert confirmé https://www.developpez.com
le 29/06/2015 à 13:59
Citation Envoyé par Luc Orient  Voir le message
tu as une référence technique à nous donner ?

La référence technique n'est pas la question, il suffit de lancer un outil de débug (intertest, xpeditor, trace master, ou autre) et de chercher à visualiser l'enregistrement lu
Si read into, la WSS contient le record, sinon, tu as les yeux pour pleurer

Citation Envoyé par Luc Orient  Voir le message
je ne comprends pas l'argument ... dans tous les cas les données sont formatées comme la description du fichier ... bien sûr si celle ci est fausse ... mais c'est un autre débat ...

Non, pas si la taille des enregistrements varie, la FD ne délimite pas les enregistrements car il s'agit d'un adressage des données du buffer I/O de Z/OS et pas d'un stockage dans la zone programme, on peut avoir dans la FD plusieurs records contigus, si on utilise la FD, on peut avoir donc un débord de l'enregistrement suivant
Il suffit de faire un read, puis un display de la FD pour s'en rendre compte

Citation Envoyé par Luc Orient  Voir le message
la zone de FD est accessible après un READ, exécuté sans erreur bien sûr, et le reste jusqu'au READ suivant ... je ne vois que du très logique là ...

Je n'ai pas parlé du READ, mais de l'OPEN et du CLOSE, les zones de FD, puisqu'elles sont externes au programmes ne sont ni accessibles avant open, ni après close

Citation Envoyé par Luc Orient  Voir le message
effectivement ... si je ne fais pas de READ INTO ce n'est pas pour faire un MOVE après ...

Et ce faisant, tu crées des difficultés en cas de besoin de debugging (via outil ou dans un dump), puisque tu ne permets pas au développeur de retrouver facilement le contenu de l'enregistrement traité
Avatar de Luc Orient Luc Orient - Membre émérite https://www.developpez.com
le 29/06/2015 à 17:31
Citation Envoyé par escartefigue  Voir le message
La référence technique n'est pas la question ...

Comme je ne programme plus de manière intensive, je n'utilise pas ce genre d'outils. Sur notre site nous disposons de produit DEBUG TOOL d'IBM et j'ai eu beau parcourir la documentation et je n'ai retrouvé aucune information sur le sujet. Mais peut être ai je mal cherché ...

Non, pas si la taille des enregistrements varie, la FD ne délimite pas les enregistrements car il s'agit d'un adressage des données du buffer I/O de Z/OS et pas d'un stockage dans la zone programme, on peut avoir dans la FD plusieurs records contigus, si on utilise la FD, on peut avoir donc un débord de l'enregistrement suivant
Il suffit de faire un read, puis un display de la FD pour s'en rendre compte

Je ne vois toujours pas où se situe le problème. Même si c'est un peu délicat en COBOL, il est toujours possible de récupérer la longueur effective de l'enregistrement en cours de lecture pour un fichier variable. Après ce n'est plus qu'une question de programmation correcte.

Je n'ai pas parlé du READ, mais de l'OPEN et du CLOSE, les zones de FD, puisqu'elles sont externes au programmes ne sont ni accessibles avant open, ni après close

Je ne vois pas l'intérêt de vouloir accéder à un enregistrement de fichier avant l'instruction OPEN.
Avatar de escartefigue escartefigue - Expert confirmé https://www.developpez.com
le 30/06/2015 à 9:24
Fais seulement le test suivant :

- création d'un fichier variable avec quelques enregistrements, chacun d'une longueur différente
- création d'un petit programme qui fait juste un read into jusqu'à fin de fichier
- à chaque read, display de la zone WSS chargée par le into, et display de la zone FD
- compare les 2 display
- terminaison du programme par cancel

tu verras que la zone FD ne contient non pas 1 mais plusieurs records
tu verras que la zone WSS au contraire sera proprement découpée
tu constateras que dans le dump, post cancel, on retrouve facilement l'enregistrement du plantage (en l'occurrence le dernier)
tu constateras à l'inverse que la zone FD ne peut pas être retrouvée dans le dump, donc résolution d'incident impossible

Imagine maintenant la difficulté à faire du débug si tu n'as pas utilisé le INTO
(encore une fois on se contrefout de l'outil de débug utilisé, puisque ce n'est pas lié à l'outil)

Enfin, il est effectivement peu probable qu'un développeur utilise une zone FD avant Open, par contre, post close c'est déjà beaucoup plus probable, quoi qu'il en soit les codes les plus surprenants sont légion, on est jamais à l'abri d'une mauvaise surprise (notamment sur les plates formes de développement off shore où les développeurs sont payés a coups de lance pierre)

En résumé, on peut planter des clous avec un manche de pelle, mais c'est tellement plus facile avec un bon marteau
Avatar de Darkzinus Darkzinus - Expert éminent https://www.developpez.com
le 30/06/2015 à 13:49
Citation Envoyé par escartefigue  Voir le message
Fais seulement le test suivant :

- création d'un fichier variable avec quelques enregistrements, chacun d'une longueur différente
- création d'un petit programme qui fait juste un read into jusqu'à fin de fichier
- à chaque read, display de la zone WSS chargée par le into, et display de la zone FD
- compare les 2 display
- terminaison du programme par cancel

tu verras que la zone FD ne contient non pas 1 mais plusieurs records
tu verras que la zone WSS au contraire sera proprement découpée
tu constateras que dans le dump, post cancel, on retrouve facilement l'enregistrement du plantage (en l'occurrence le dernier)
tu constateras à l'inverse que la zone FD ne peut pas être retrouvée dans le dump, donc résolution d'incident impossible

Imagine maintenant la difficulté à faire du débug si tu n'as pas utilisé le INTO
(encore une fois on se contrefout de l'outil de débug utilisé, puisque ce n'est pas lié à l'outil)

Enfin, il est effectivement peu probable qu'un développeur utilise une zone FD avant Open, par contre, post close c'est déjà beaucoup plus probable, quoi qu'il en soit les codes les plus surprenants sont légion, on est jamais à l'abri d'une mauvaise surprise (notamment sur les plates formes de développement off shore où les développeurs sont payés a coups de lance pierre)

En résumé, on peut planter des clous avec un manche de pelle, mais c'est tellement plus facile avec un bon marteau

J'ai pour ma part déjà rencontré des programmes mal codés avec la description en FD et une mauvaise utilisation du format VB occasionnant du "faux" VB avec les octets de définition de longueur toujours alimentés avec la valeur maximale du format VB. Et le problème que tu mentionnes avec la zone FD complétée avec plusieurs enregistrements.
Après même sans READ into avec un depending on dans la FD et un MOVE dans une zone réceptrice en working on ne constate pas de soucis.
Avatar de escartefigue escartefigue - Expert confirmé https://www.developpez.com
le 30/06/2015 à 19:25
Citation Envoyé par Darkzinus  Voir le message
J'ai pour ma part déjà rencontré des programmes mal codés avec la description en FD et une mauvaise utilisation du format VB occasionnant du "faux" VB avec les octets de définition de longueur toujours alimentés avec la valeur maximale du format VB. Et le problème que tu mentionnes avec la zone FD complétée avec plusieurs enregistrements.
Après même sans READ into avec un depending on dans la FD et un MOVE dans une zone réceptrice en working on ne constate pas de soucis.

Tout à fait d'accord, et le read into a l'avantage de forcer le move simultanément au read, ce qui évite les mauvaises surprises

CQFD
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.
Contacter le responsable de la rubrique Accueil