IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Cobol Discussion :

Question TABLE & Fichiers Indexés + Recherche


Sujet :

Cobol

  1. #1
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut Question TABLE & Fichiers Indexés + Recherche
    Rebonjour !

    Alors cette fois j'ai poussé le vice un peu plus loin que tout à l'heure...

    Cette fois je me suis construit 2 fichiers :

    ACCT.DAT
    Mr.Patron 0012000.00 LDD
    Mr.Employe 0000042.00 Cpt.
    Mr.Patron 0000100.00 LA
    RATE.DAT
    LA 001.25 22950 Livret A
    LB 000.00 00000 Livret B
    LJ 001.25 01600 Livret Jeune
    LLB 001.25 22950 Livret Bleu
    LDD 001.25 12000 Livret de Developpement Durable
    CEL 000.63 15300 Compte Epargne Logement
    PEL 002.11 61200 Pret Epargne Logement
    LEP 001.75 07700 Livret Epargne Populaire
    LEE 000.75 00000 Livret Epargne
    Vous l'aurez deviné...
    Cette fois je vais essayer de faire des simili-jointures !
    J'ai recherché un peu quelques méthodes, et je suis tombé sur les fichiers indexés et les tables.

    Mes questions :
    1) Est-il possible de créer des tables COBOL avec des fichiers ? Ou s'agit-il de structures dédiées à la récupération de tables de bases de données ?
    2) Est-il possible de passer un fichier windowsien "normal" en fichier "indexé" sous COBOL avec une colonne comme clé ? Si oui : quel est le mot clé pour faire une recherche/extraction ? Sur zOS/MVS, seul un VSAM peut être utilisé pour cela ? Ou un QSAM peut suffire ?
    3) Ces 2 méthodes sont-elles les seules disponibles pour résoudre mon problème (si on oublie le classique parcours de fichier RATE.DAT à chaque fois que je lis un enregistrement du fichier ACCT.DAT) ?
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  2. #2
    Expert confirmé
    Homme Profil pro
    ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Inscrit en
    Juin 2007
    Messages
    2 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 096
    Points : 4 155
    Points
    4 155
    Par défaut
    Citation Envoyé par Metalman Voir le message
    Rebonjour !
    ...
    Bonjour.

    0) Je ne suis pas tellement pour matérialiser le point décimal par la ',' ou le '.' dans les zones numériques stockées dans les fichiers, ni pour les espaces de séparation des zones.
    Mes questions :
    1) Est-il possible de créer des tables COBOL avec des fichiers ? Ou s'agit-il de structures dédiées à la récupération de tables de bases de données ?
    - A vrai dire les tables ou les fichiers ne sont pas propres à Cobol, sauf en ce qui concerne les fichiers indexés utilisés par les programmes Cobol sur les plateformes micro à cause de la gestion des index qui est faite par les routines Cobol et non par l'OS.
    - Sur les AS/400 et compagnie, les notions de table ou de fichier désignent la même chose, et on peut indifféremment utiliser du SQL embarqué ou les instructions classiques d'I/O pour accéder aux tables/fichiers.
    - Par contre, quand on a un des tables SGBDR (DB2), on doit utiliser le SQL embarqué pour y accéder (en dehors des AS/400 et compagnie)
    2) Est-il possible de passer un fichier windowsien "normal" en fichier "indexé" sous COBOL avec une colonne comme clé ? Si oui : quel est le mot clé pour faire une recherche/extraction ?
    Oui mais pas directement, il faut copier ton fichier texte séquentiel (consécutif) dans un fichier indexé déclaré comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                SELECT FICHIER ASSIGN DISK
                            ORGANIZATION INDEXED
                            RECORD KEY MAZONECLE OF FICHIER-RD.
    où MAZONECLE est obligatoirement une zone du 01 du FD de FICHIER.
    Tu peux déclarer en même temps une ALTERNATE RECORD KEY pour définir un index secondaire sur le fichier.
    Sur zOS/MVS, seul un VSAM peut être utilisé pour cela ? Ou un QSAM peut suffire ?
    Je laisse nos amis des mainsframes y répondre.
    3) Ces 2 méthodes sont-elles les seules disponibles pour résoudre mon problème (si on oublie le classique parcours de fichier RATE.DAT à chaque fois que je lis un enregistrement du fichier ACCT.DAT) ?
    Si DB2, utiliser SQL embarqué et définir une jointure.

  3. #3
    Membre expert
    Homme Profil pro
    Retraité
    Inscrit en
    Octobre 2005
    Messages
    1 473
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 473
    Points : 3 283
    Points
    3 283
    Par défaut
    Citation Envoyé par Hédhili Jaïdane Voir le message
    ...Je laisse nos amis des mainsframes y répondre.
    Oui. Sur z/OS, un fichier avec clé est forcément un fichier VSAM. C'est un KSDS (Key Sequenced Data Set).

    Remarque :
    Il existe une "vieille" technologie de fichiers avec clé, c'est ISAM (Indexed Sequential Acces Method). Mais cette dernière est à proscrire (inutilisable depuis z/OS 1.7).

  4. #4
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Merci pour tous vos conseils !

    J'ai commencé à faire un "autre" programme qui transforme mes 2 fichiers en fichiers indexés par COBOL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    	IDENTIFICATION DIVISION.
    	PROGRAM-ID. REORG.
    
    
    	ENVIRONMENT DIVISION.
    	CONFIGURATION SECTION.
    	SOURCE-COMPUTER. PC-I686.
    	OBJECT-COMPUTER. PC-I686.
    
    	INPUT-OUTPUT SECTION.
    	FILE-CONTROL.
    		SELECT ACCT-DATA		ASSIGN TO DISK "ACCT.DAT"
    		       ORGANIZATION IS LINE SEQUENTIAL
    			   FILE STATUS IS ST-ACCT-IN.
       		SELECT RATE-DATA		ASSIGN TO DISK "RATE.DAT"
    		       ORGANIZATION IS LINE SEQUENTIAL
    			   FILE STATUS IS ST-RATE-IN.
    		SELECT ACCT-DATA-OUT	ASSIGN TO DISK "ACCT-KEY.DAT"
                   ORGANIZATION INDEXED
                   RECORD KEY TYPE-OUT OF ACCT-DATA-OUT
    			   FILE STATUS IS ST-ACCT-OUT.
       		SELECT RATE-DATA-OUT	ASSIGN TO DISK "RATE-KEY.DAT"
                   ORGANIZATION INDEXED
                   RECORD KEY TYPE-ACCT-OUT OF RATE-DATA-OUT
    			   FILE STATUS IS ST-RATE-OUT.
    
    	DATA DIVISION.
    	FILE SECTION.
     *    * Account analyzed
    	FD  ACCT-DATA.
    	01  ACCT-RECORD.
    	    05	OWNER-NAME-IN		PICTURE X(20).
    		05				PICTURE X(1).
    		05	SAVING-IN			PICTURE 9(7).
    		05				PICTURE X(1).
    		05	TYPE-IN		PICTURE X(20).
     *    * Rate File
    	FD  RATE-DATA.
    	01  RATE-RECORD.
    	    05	TYPE-ACCT-IN		PICTURE X(4).
    		05				PICTURE X(1).
    		05	RATE-IN				PICTURE 9(3),9(2).
    		05				PICTURE X(1).
    	    05	MAX-SAVING-IN		PICTURE 9(5).
    	    05				PICTURE X(1).
    		05	DESCRIPTION-IN		PICTURE X(32).
    
     *    * Account analyzed with key
    	FD  ACCT-DATA-OUT.
    	01  ACCT-OUT-RECORD.
    	    05	OWNER-NAME-OUT		PICTURE X(20).
    		05	SAVING-OUT			PICTURE 9(7).
    	01  TYPE-OUT				PICTURE X(20).
     *    * Rate File with key
    	FD  RATE-DATA-OUT.
    	01	TYPE-ACCT-OUT			PICTURE X(4).
    	01  RATE-OUT-RECORD.  
    		05	RATE-OUT			PICTURE 9(3),9(2).
    	    05	MAX-SAVING-OUT		PICTURE 9(5).
    		05	DESCRIPTION-OUT		PICTURE X(32).
    
    	WORKING-STORAGE SECTION.
    	01  ARE-THERE-MORE-RECORDS	PICTURE XXX VALUE 'YES'.
    	77  CURRENT-NAME			PICTURE X(20).
    	77  CURRENT-ENTRIES			PICTURE 999.
    	01  ST-ACCT-IN				PIC X(02)   VALUE SPACES.
    		88	ST-ACCT-IN-SUCCESS				VALUE '00'.
    		88	ST-ACCT-IN-EOF					VALUE '10'.
    	01  ST-RATE-IN				PIC X(02)   VALUE SPACES.
    		88	ST-RATE-IN-SUCCESS				VALUE '00'.
    		88	ST-RATE-IN-EOF					VALUE '10'.
    	01  ST-ACCT-OUT				PIC X(02)   VALUE SPACES.
    		88	ST-ACCT-OUT-SUCCESS				VALUE '00'.
    		88	ST-ACCT-OUT-EOF					VALUE '10'.
    	01  ST-RATE-OUT				PIC X(02)   VALUE SPACES.
    		88	ST-RATE-OUT-SUCCESS				VALUE '00'.
    		88	ST-RATE-OUT-EOF					VALUE '10'.
    	01  IS-FIRST-ENTRY			PICTURE XXX VALUE 'YES'.
    	    88 NOT-FIRST-ENTRY					VALUE 'NO '.
    
    
    	PROCEDURE DIVISION.
    	100-MAIN-MODULE.
    		INITIALIZE ST-ACCT-IN ST-RATE-IN ST-ACCT-OUT ST-RATE-OUT
    		PERFORM 200-COPY-ACCT
    		PERFORM 300-COPY-RATE
    		STOP RUN.
    		
    	110-ERROR-EXIT.
    		EXIT.
    		STOP RUN.
    		
    	200-COPY-ACCT.
    	    MOVE 'YES' TO IS-FIRST-ENTRY
    		OPEN INPUT ACCT-DATA
    		     OUTPUT ACCT-DATA-OUT.
     		IF ST-ACCT-IN-SUCCESS AND ST-ACCT-OUT-SUCCESS
     			DISPLAY "ACCT OPEN SUCCESSFUL"
     		ELSE
     			DISPLAY "ACCT OPEN FAILED"
     			GO TO 110-ERROR-EXIT
     		END-IF.
    		READ ACCT-DATA INTO ACCT-RECORD
    		     AT END
    			  MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
    		END-READ.
    		PERFORM 210-WRITE-ACCT
    			UNTIL ARE-THERE-MORE-RECORDS = 'NO'.
    		CLOSE ACCT-DATA
    		      ACCT-DATA-OUT.
    
    	210-WRITE-ACCT.
    		MOVE OWNER-NAME-IN TO OWNER-NAME-OUT.
    		MOVE SAVING-IN TO SAVING-OUT.
    		MOVE TYPE-IN TO TYPE-OUT.
    		WRITE ACCT-OUT-RECORD
    		WRITE TYPE-OUT
    		READ ACCT-DATA INTO ACCT-RECORD
    		     AT END
    			  MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
    		END-READ.
     *    *		  DISPLAY "Name temp : " NAME-ST
    
    	300-COPY-RATE.
    	    MOVE 'YES' TO IS-FIRST-ENTRY
    		OPEN INPUT RATE-DATA
    		     OUTPUT RATE-DATA-OUT.
     		IF ST-RATE-IN-SUCCESS AND ST-RATE-OUT-SUCCESS
     			DISPLAY "RATE OPEN SUCCESSFUL"
     		ELSE
     			DISPLAY "RATE OPEN FAILED"
     			GO TO 110-ERROR-EXIT
     		END-IF.
    		READ RATE-DATA INTO RATE-RECORD
    		     AT END
    			  MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
    		END-READ.
    		PERFORM 310-WRITE-RATE
    			UNTIL ARE-THERE-MORE-RECORDS = 'NO'.
    	    CLOSE RATE-DATA
    			  RATE-DATA-OUT.
    		
    	310-WRITE-RATE.
    		MOVE TYPE-ACCT-IN TO TYPE-ACCT-OUT.
    		MOVE RATE-IN TO RATE-OUT.
    		MOVE MAX-SAVING-IN TO MAX-SAVING-OUT.
    		MOVE DESCRIPTION-IN TO DESCRIPTION-OUT.
    		WRITE TYPE-ACCT-OUT
    		WRITE RATE-OUT-RECORD
    		READ RATE-DATA INTO RATE-RECORD
    		     AT END
    			  MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
    		END-READ.
     *    *		  DISPLAY "Name temp : " NAME-ST
    		
    	END PROGRAM INTERETS.
    Vous vous en doutez, ça ne marche pas.
    ACCT OPEN FAILED

    Et là... je suis sûr que c'est lié à un de mes arguments ou déclaration...
    Mais je ne sais pas trop trop ! :s
    [je compile sur tinycobol au bureau, et opencobol chez moi... et parfois sur le COBOL dispo sur le Z !]

    EDIT : en scrollant je viens de voir que je n'ai pas modifié le FILE-CONTROL....
    Je reteste.
    EDIT2 : c'est corrigé, même erreur qu'avant
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  5. #5
    Expert confirmé
    Homme Profil pro
    ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Inscrit en
    Juin 2007
    Messages
    2 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 096
    Points : 4 155
    Points
    4 155
    Par défaut
    Bonjour.

    - Je me permets de te faire remarquer que ton programme est un brouillon et que j'ai du mal à bien le lire même s'il ne fait que quelques lignes, aucune indentation, alignement des niveaux, etc...

    - dans la déclaration MAZONECLE OF FICHIER-RD, il faut remplacer MAZONE par le nom de la zone (élémentaire ou groupe) qui constitue la clé du fichier. Cette zone doit exister dans le premier niveau 01 du fichier qui est juste sous son FD. J'avais ajouté "OF FICHIER-RD" pour qualifier cette zone clé si des fois on voudrait utiliser les mêmes noms de zones pour les fichiers en entrée et en sortie lors de la copie d'indexation.

    - Même si je ne suis pas contre l'utilisation des GO TO, il fortement conseillé de l'utiliser et strictement interdit d'utiliser un GO TO à l'intérieur d'un pavé de paragraphes sous le contrôle d'un PERSORM ou d'un SORT/MERGE quand ce GO TO renvoie à l'extérieur de ce pavé.

    - je suis étonné que tu aies un OPEN FAILED alors que ton programme ne doit pas compiler à cause de MAZONE non définie (et FICHIER-RD)

    - Quand on écrit dans un fichier indexé en sortie séquentielle, il faut que les enregistrements écrits soient dans l'ordre de la clé, sinon ça marche pas.
    Généralement on ouvre un fichier séquentiel indexé en INPUT-OUTPUT et on déclare un ACCESS DYNAMIC ou RANDOM, si on n'indique pas le type d'accès, il est SEQUENTIAL par défaut. Une lecture de vérification de l'existence de la clé avant l'écriture de l'enregistrement est plus que souhaitée.

    - Je me permets de vivement te conseiller d'avoir un minimum de docs sous la main.

  6. #6
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    J'ai fais l'EDIT pour le MAZONE.
    En effet c'est étonnant que le compilateur n'ait rien dit pour ça.

    J'ai mis 2 GOTO exclusivement pour quitter si ça échoue (je n'ai pas encore trouvé d'équivelent au RETURN en C), donc normalement il n'y aura pas de problème avec ça (et je suis beaucoup plus habitué à appeler des fonctions + while/for + if plutôt qu'à faire des PERFORM )

    Moi-même je trouve le code assez laid....
    On va décomplexifier (vu que j'ai dupliqué du code pour traiter les 2 fichiers).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    	IDENTIFICATION DIVISION.
    	PROGRAM-ID. REORG.
    
    
    	ENVIRONMENT DIVISION.
    	CONFIGURATION SECTION.
    	SOURCE-COMPUTER. PC-I686.
    	OBJECT-COMPUTER. PC-I686.
    
    	INPUT-OUTPUT SECTION.
    	FILE-CONTROL.
    		SELECT ACCT-DATA		ASSIGN TO DISK "ACCT.DAT"
    			ORGANIZATION IS LINE SEQUENTIAL
    			FILE STATUS IS ST-ACCT-IN.
    		SELECT ACCT-DATA-OUT	ASSIGN TO DISK "ACCT-KEY.DAT"
    			ORGANIZATION INDEXED
    			RECORD KEY TYPE-OUT OF ACCT-DATA-OUT
    			FILE STATUS IS ST-ACCT-OUT.
    
    	DATA DIVISION.
    	FILE SECTION.
     *    * Account analyzed
    	FD  ACCT-DATA.
    	01  ACCT-RECORD.
    	  05	OWNER-NAME-IN		PICTURE X(20).
    	  05				PICTURE X(1).
    	  05	SAVING-IN			PICTURE 9(7).
    	  05				PICTURE X(1).
    	  05	TYPE-IN		PICTURE X(20).
    
     *    * Account analyzed with key
    	FD  ACCT-DATA-OUT.
    	01  ACCT-OUT-RECORD.
    	  05	OWNER-NAME-OUT		PICTURE X(20).
    	  05	SAVING-OUT			PICTURE 9(7).
    	01  TYPE-OUT				PICTURE X(20).
    
    	WORKING-STORAGE SECTION.
    	01  ARE-THERE-MORE-RECORDS	PICTURE XXX VALUE 'YES'.
    	77  CURRENT-NAME			PICTURE X(20).
    	77  CURRENT-ENTRIES			PICTURE 999.
    	01  ST-ACCT-IN				PIC X(02)   VALUE SPACES.
    	  88	ST-ACCT-IN-SUCCESS				VALUE '00'.
    	  88	ST-ACCT-IN-EOF					VALUE '10'.
    	01  ST-ACCT-OUT				PIC X(02)   VALUE SPACES.
    	  88	ST-ACCT-OUT-SUCCESS				VALUE '00'.
    	  88	ST-ACCT-OUT-EOF					VALUE '10'.
    	01  IS-FIRST-ENTRY			PICTURE XXX VALUE 'YES'.
    	  88 NOT-FIRST-ENTRY					VALUE 'NO '.
    
    
    	PROCEDURE DIVISION.
    	100-MAIN-MODULE.
    	  INITIALIZE ST-ACCT-IN ST-ACCT-OUT
    	  PERFORM 200-COPY-ACCT
    	  STOP RUN.
    		
    	110-ERROR-EXIT.
    	  EXIT.
    	  STOP RUN.
    		
    	200-COPY-ACCT.
    	  MOVE 'YES' TO IS-FIRST-ENTRY
    	  OPEN INPUT ACCT-DATA
    	          OUTPUT ACCT-DATA-OUT.
    	  IF ST-ACCT-IN-SUCCESS AND ST-ACCT-OUT-SUCCESS
    		DISPLAY "ACCT OPEN SUCCESSFUL"
    	  ELSE
     		DISPLAY "ACCT OPEN FAILED"
     		GO TO 110-ERROR-EXIT
     	  END-IF.
    	  READ ACCT-DATA INTO ACCT-RECORD
    		AT END MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
    	  END-READ.
    	  PERFORM 210-WRITE-ACCT
    		UNTIL ARE-THERE-MORE-RECORDS = 'NO'.
    	  CLOSE ACCT-DATA
    	            ACCT-DATA-OUT.
    
    	210-WRITE-ACCT.
    	  MOVE OWNER-NAME-IN TO OWNER-NAME-OUT.
    	  MOVE SAVING-IN TO SAVING-OUT.
    	  MOVE TYPE-IN TO TYPE-OUT.
    	  WRITE ACCT-OUT-RECORD
    	  WRITE TYPE-OUT
    	  READ ACCT-DATA INTO ACCT-RECORD
    		AT END MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
    	  END-READ.
     *    *  DISPLAY "Name temp : " NAME-ST
    
    	END PROGRAM INTERETS.
    Voilà, le but c'est de transformer un fichier séquentiel simple en séquentiel indexé.
    Donc écrire depuis un 1er fichier vers un 2e.

    - Quand on écrit dans un fichier indexé en sortie séquentielle, il faut que les enregistrements écrits soient dans l'ordre de la clé, sinon ça marche pas.
    Généralement on ouvre un fichier séquentiel indexé en INPUT-OUTPUT et on déclare un ACCESS DYNAMIC ou RANDOM, si on n'indique pas le type d'accès, il est SEQUENTIAL par défaut. Une lecture de vérification de l'existence de la clé avant l'écriture de l'enregistrement est plus que souhaitée.
    Dans l'ordre de la clé ?
    Ici j'ai écrit dans le FILE CONTROL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RECORD KEY TYPE-OUT OF ACCT-DATA-OUT
    Et en FILE DESCRIPTOR :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	FD  ACCT-DATA-OUT.
    	01  ACCT-OUT-RECORD.
    	  05	OWNER-NAME-OUT		PICTURE X(20).
    	  05	SAVING-OUT			PICTURE 9(7).
    	01  TYPE-OUT				PICTURE X(20).
    Il faut bel et bien indiquer l'image mémoire précise qui sert de clé ? (TYPE-OUT)
    Je l'ai mis en 01, mais il faut peut être "aussi" la mettre en 1er ?

    Les options RANDOM, DYNAMIC, ... ne sont pas très utiles dans mon cas où il s'agit "uniquement" d'écriture ?
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  7. #7
    Expert confirmé
    Homme Profil pro
    ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Inscrit en
    Juin 2007
    Messages
    2 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 096
    Points : 4 155
    Points
    4 155
    Par défaut
    Voila un exemple pour le fichier le plus intéressant à indexer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
               SELECT RATE-DATA ASSIGN TO DISK "RATE.DAT"
                      ORGANIZATION IS LINE SEQUENTIAL
                      FILE STATUS IS ST-RATE-IN.
               SELECT RATE-DATA-OUT ASSIGN TO DISK "RATE-KEY.DAT"
                      ORGANIZATION INDEXED
                      ACCESS RANDOM
                      RECORD KEY TYPE-ACCT-OUT
                      FILE STATUS IS ST-RATE-OUT.
    
           DATA DIVISION.
           FILE SECTION.
           FD  RATE-DATA.
           01  RATE-RECORD.
               05  TYPE-ACCT-IN        PIC X(4).
               05  FILLER              PIC X.
               05  RATE-IN             PIC 9(3),9(2).
               05  FILLER              PIC X.
               05  MAX-SAVING-IN       PIC 9(5).
               05  FILLER              PIC X.
               05  DESCRIPTION-IN      PICTURE X(32).
           FD  RATE-DATA-OUT.
           01  RATE-DATA-OUT-RECORD.
               05  TYPE-ACCT-OUT       PIC X(4).
               05  RATE-OUT            PIC 999V99.
               05  MAX-SAVING-OUT      PIC 9(5).
               05  DESCRIPTION-OUT     PIC X(32).
    .../...     
    
               MOVE TYPE-ACCT-IN    TO TYPE-ACCT-OUT.
               MOVE RATE-IN         TO RATE-OUT.
               MOVE MAX-SAVING-IN   TO MAX-SAVING-OUT. 
               MOVE DESCRIPTION-IN  TO DESCRIPTION-OUT. 
               WRITE RATE-DATA-OUT INVALID STOP "CLE DOUBLE : " TYPE-ACCT-IN.
    .../...
    La zone clé (RECORD KEY) doit être dans le 01 (faire partie) et non pas le 01 lui même.

  8. #8
    Expert éminent sénior
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    6 803
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 6 803
    Points : 32 058
    Points
    32 058
    Par défaut
    un exemple de GOTO de sortie bien codé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    100-MON-PARAGRAPHE.
        ...
        IF ERREUR 
            GO TO 100-MON-PARAGRAPHE-FIN
        END-IF
        ...
    100-MON-PARAGRAPHE-FIN.
        EXIT.
    
    101-MON-PARAGRAPHE-SUIVANT.
    Et, si on veut l’appeler avec ceinture et bretelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PERFORM 100-MON-PARAGRAPHE
       THRU 100-MON-PARAGRAPHE-FIN

    C'est verbeux et bourrin, mais ça marche dans absolument tous les cas.
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

  9. #9
    Expert confirmé
    Homme Profil pro
    ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Inscrit en
    Juin 2007
    Messages
    2 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 096
    Points : 4 155
    Points
    4 155
    Par défaut
    Bonjour el_slapper et +1.

    En effet, c'est généralement ce qu'on fait quand on se trouve coincé, mais on aurait aussi pu faire un PERFORM 110-ERROR-EXIT à la place de GO TO 110-ERROR-EXIT puisque 110-ERROR-EXIT contient à sa fin un STOP RUN.

  10. #10
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Wahou.

    Merci pour ce que vous faites !

    Voici le code qui fonctionne pour transformer un fichier séquentiel en séquentiel indexé sur Windows avec tinycobol (pour OpenCOBOL/GNU Cobol il faudra sûrement modifier un peu les espaces et points) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    	IDENTIFICATION DIVISION.
    	PROGRAM-ID. REORG.
    
    
    	ENVIRONMENT DIVISION.
    	CONFIGURATION SECTION.
    	SOURCE-COMPUTER. PC-I686.
    	OBJECT-COMPUTER. PC-I686.
    
    	INPUT-OUTPUT SECTION.
    	FILE-CONTROL.
       		SELECT RATE-DATA		ASSIGN TO DISK "RATE.DAT"
                      ORGANIZATION IS LINE SEQUENTIAL
                      FILE STATUS IS ST-RATE-IN.
       		SELECT RATE-DATA-OUT	ASSIGN TO DISK "RATE-KEY.DAT"
                      ORGANIZATION INDEXED
                      ACCESS RANDOM
                      RECORD KEY TYPE-ACCT-OUT
                      FILE STATUS IS ST-RATE-OUT.
    
    	DATA DIVISION.
    	FILE SECTION.
     *    * Account analyzed
           FD  RATE-DATA.
           01  RATE-RECORD.
               05  TYPE-ACCT-IN        PIC X(4).
               05  FILLER              PIC X.
               05  RATE-IN             PIC 9(3),9(2).
               05  FILLER              PIC X.
               05  MAX-SAVING-IN       PIC 9(5).
               05  FILLER              PIC X.
               05  DESCRIPTION-IN      PIC X(32).
     *    * Account analyzed with key
    	   FD  RATE-DATA-OUT.
           01  RATE-DATA-OUT-RECORD.
               05  TYPE-ACCT-OUT       PIC X(4).
               05  RATE-OUT            PIC 999V99.
               05  MAX-SAVING-OUT      PIC 9(5).
               05  DESCRIPTION-OUT     PIC X(32).
    
    	WORKING-STORAGE SECTION.
        77  CURRENT-NAME			PIC X(32).
        77  CURRENT-ENTRIES			PIC 999.
        01  ST-RATE-IN				PIC X(02)   VALUE SPACES.
            88	ST-RATE-IN-SUCCESS				VALUE '00'.
            88	ST-RATE-IN-EOF					VALUE '10'.
        01  ST-RATE-OUT				PIC X(02)   VALUE SPACES.
            88	ST-RATE-OUT-SUCCESS				VALUE '00'.
            88	ST-RATE-OUT-EOF					VALUE '10'.
        01  ARE-THERE-MORE-RECORDS	PIC XXX     VALUE 'YES'.
        01  IS-FIRST-ENTRY			PIC XXX     VALUE 'YES'.
            88 NOT-FIRST-ENTRY					VALUE 'NO '.
    
    
    	PROCEDURE DIVISION.
    	100-MAIN-MODULE.
    	  INITIALIZE ST-RATE-IN ST-RATE-OUT
    	  PERFORM 200-OPEN-RATE
    	  STOP RUN.
    		
    	110-ERROR-EXIT.
    	  EXIT.
    	  STOP RUN.
    		
    	200-OPEN-RATE.
    	  MOVE 'YES' TO IS-FIRST-ENTRY
    	  OPEN INPUT RATE-DATA
    	       OUTPUT RATE-DATA-OUT.
          IF ST-RATE-IN-SUCCESS AND ST-RATE-OUT-SUCCESS
            DISPLAY "RATE OPEN SUCCESSFUL"
          ELSE
            DISPLAY "RATE OPEN FAILED"
            PERFORM 110-ERROR-EXIT
          END-IF.
    	  PERFORM 210-COPY-RATE
    	  CLOSE RATE-DATA
    	            RATE-DATA-OUT.
    
        210-COPY-RATE.
    	  READ RATE-DATA INTO RATE-RECORD
    		AT END MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
    	  END-READ.
    	  PERFORM 220-WRITE-RATE
    		UNTIL ARE-THERE-MORE-RECORDS = 'NO'.
    
    	220-WRITE-RATE.
          MOVE TYPE-ACCT-IN   TO TYPE-ACCT-OUT.
          MOVE RATE-IN        TO RATE-OUT.
          MOVE MAX-SAVING-IN  TO MAX-SAVING-OUT. 
          MOVE DESCRIPTION-IN TO DESCRIPTION-OUT. 
          WRITE RATE-DATA-OUT-RECORD
    	    INVALID PERFORM 230-ERROR-KEY.
    	  READ RATE-DATA INTO RATE-RECORD
    		AT END MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
    	  END-READ.
    
    	230-ERROR-KEY.
    	  DISPLAY "CLE DOUBLE : " TYPE-ACCT-IN.
    	  STOP RUN.
    	  
    	END PROGRAM REORG.
    Tinycobol étant trop permissif, le programme compilait malgré un RECORD KEY TYPE-ACCT-OUT où au lieu de TYPE-ACCT-OUT on met n'importe quoi.
    Par contre à l'exécution, l'ouverture échouait.

    Bref, voici le fichier d'exemple lié à cela :
    LA 001.25 22950 Livret A
    LB 000.00 00000 Livret B
    LJ 001.25 01600 Livret Jeune
    LLB 001.25 22950 Livret Bleu
    LDD 001.25 12000 Livret de Developpement Durable
    CEL 000.63 15300 Compte Epargne Logement
    PEL 002.11 61200 Pret Epargne Logement
    LEP 001.75 07700 Livret Epargne Populaire
    LEE 000.75 00000 Livret Epargne
    Sur Windows, cela m'a généré 2 fichiers :
    RATE-KEY.DAT.dat
    RATE-KEY.DAT.idx

    Je vais pouvoir reprendre l'autre partie importante : la jointure/récupération de l'index pour une recherche.

    Merci encore de votre patience.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  11. #11
    Expert confirmé
    Homme Profil pro
    ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Inscrit en
    Juin 2007
    Messages
    2 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : ANCIEN Consultant/Formateur/Développeur AS/400, iSeries, System i et Cobol
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 096
    Points : 4 155
    Points
    4 155
    Par défaut
    Citation Envoyé par Metalman Voir le message
    ...

    Sur Windows, cela m'a généré 2 fichiers :
    RATE-KEY.DAT.dat
    RATE-KEY.DAT.idx
    Bonjour.

    C'est normal

    Je vais pouvoir reprendre l'autre partie importante : la jointure/récupération de l'index pour une recherche.

    Merci encore de votre patience.
    Pas de quoi. Bonne continuation et bon courage.

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 138
    Points : 266
    Points
    266
    Par défaut
    Bonjour,

    Je viens de lire la discussion qui est très intéressante et j'ai tické sur :
    Citation Envoyé par Metalman Voir le message
    Wahou.
    Je vais pouvoir reprendre l'autre partie importante : la jointure/récupération de l'index pour une recherche.
    Merci encore de votre patience.
    Parce qu'en fait si on reprend le post initial tu poses 3 questions :

    Citation Envoyé par Metalman
    Mes questions :
    1) Est-il possible de créer des tables COBOL avec des fichiers ? Ou s'agit-il de structures dédiées à la récupération de tables de bases de données ?
    2) Est-il possible de passer un fichier windowsien "normal" en fichier "indexé" sous COBOL avec une colonne comme clé ? Si oui : quel est le mot clé pour faire une recherche/extraction ? Sur zOS/MVS, seul un VSAM peut être utilisé pour cela ? Ou un QSAM peut suffire ?
    3) Ces 2 méthodes sont-elles les seules disponibles pour résoudre mon problème (si on oublie le classique parcours de fichier RATE.DAT à chaque fois que je lis un enregistrement du fichier ACCT.DAT) ?
    J'apporterai pour réponses :

    1) Oui il est possible de créer des tables COBOL avec des fichiers ou même avec toute sorte de données, cependant ce seront des tables à plat "nativement" non indexées, mais il existe des astuces pour simuler une table indexée en working. Solution à utiliser avec parcimonie par contre...

    2) Oui, tu viens de le démontrer Metalman, et merci pour tout ce détail qui pourra sûrement nous resservir.

    3) Non ! il existe d'autres méthodes !

    Et c'est sur ce troisième point que je voudrais m'attarder. En effet, en fait la problématique initiale est "comment faire une jointure entre 2 fichiers en COBOL ?"

    Etant issu du monde mainframe en banque/finance, je peux dire que la jointure de fichier est une problématique si récurrente que ce n'est plus vraiment un problème mais une base... je l'ai fait en cobol, pac, pl1, hlasm... et c'est tellement courant qu'en fait sur zOs c'est faisable rien qu'en appelant icetool (la boite à outils ultime pour le traitement de données livrée de base...)

    J'utilise depuis toujours la même méthode "d'appareillage" (ou de "synchro" pour les pacbasiens, ou de "join" pour ceux issus des "nti") des fichiers et cela n'implique aucun index ni accès direct, tout est fait séquentiellement (c'est celle utilisée par les sgbds d'après ce qu'on m'a dit)
    Et même par expérience dès que tu as de la volumétrie importante, l'utilisation de fichier indexé n'est pertinente que dans très rare cas d'un point de vue performance (certes sur l'exemple tu ne verrais pas de différence mais sur des millions de lignes c'est autres choses)
    Et pour voir, j'ai chercher un peu sur google, et étrangement même en sachant ce que je cherchais, je n'ai pas trouvé de description de cette méthode... à croire qu'elle ne se transmet que de bouche de coboliste à oreille de coboliste...

    Donc pour rentrer dans le vif du sujet, la jointure nécessite quelques prérequis :
    1. Les fichiers doivent être triés sur la clé de jointure. C'est à faire avant donc...
    2. Au moins un des fichiers doit avoir l'unicité sur la clé de jointure (c'est le cas de ton rate.dat). Sans ça, tu ne pourras jamais le faire quelque soit la méthode...


    Ensuite en pseudo code avec tes noms de fichiers ça donne (que tu peux transcrire en n'importe quel langage) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    init :
       lire acct
       si acct-eof alors acct-cle = high-value
       lire rate
       si rate-eof alors rate-cle = high-value
    
    traitement:
       si acct-cle == high-value && rate-cle == high-value alors
          go to fin
    
       si acct-cle < rate-cle alors
          lire acct
          si acct-eof alors acct-cle = high-value
          go to traitement
    
       si acct-cle > rate-cle alors
          lire rate
          si rate-eof alors rate-cle = high-value
          go to traitement
    
       si acct-cle == rate-cle alors
          constituer data-sortie
          ecrire sortie
          lire acct
          si acct-eof alors acct-cle = high-value
          go to traitement
    
    fin:
       TADAAAA
    Bon malheureusement, je n'ai plus le temps de détailler, j'essaye de repasser ce soir ou demain pour plus d'explication. (je laisse quand même sans explication, parce que ce n'est pas compliqué à comprendre)

  13. #13
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Ouais, sur mainframe il y a tout ce qu'il faut pour trier "avant" !
    Je voulais le faire sans pour vraiment toucher aux notions COBOL de tables, etc...
    Bon c'est vrai que dans la réalité on va plutôt utiliser les outils optimisés, je l'admets...

    Les index sont si peu utiles sur les grands volumes "en général" ?...
    J'aurais vraiment cru le contraire.
    C'est lié au fait qu'il y aurait trop de déplacements aléatoires en mémoire/disque pour atteindre à chaque fois la donnée recherchée, au lieu de faire 2 tris définitifs et des accès en parallèles/proches ? (sur les 2 fichiers à joindre)

    A propos de l'algo :
    J'avais cru lire ça dans un autre topic, et je suis toujours bloqué sur la signification du "high-value" (valeur haute ? plus grande valeur de clé ?).
    Et quand vous dites :
    Les fichiers doivent être triés sur la clé de jointure. C'est à faire avant donc...
    C'est bien "organisé" de la plus petite à la plus grande valeur de clé ?

    PS : (Je suis dans le même environnement que vous en ce moment ! Mais j'essaye de voir un peu en dehors de ce que je suis exclusivement censé faire en mission)

    EDIT : D'ailleurs, j'espère qu'une section "codes sources COBOL" est dispo ici pour mettre les sources en ligne ailleurs que dans un topic... comme ça on aurait "aussi" une base de bouts de codes dispos (le tri interne, et cette conversion par exemples (grâce à Hédhili surtout)).
    Voire, d'avoir quelques JCL aussi ! (parce que la doc IBM est complète, mais un peu trop quand on veut faire quelque chose de simple)
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  14. #14
    Membre actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 138
    Points : 266
    Points
    266
    Par défaut
    hop là petit passage entre 2 réunions

    Citation Envoyé par Metalman Voir le message
    Les index sont si peu utiles sur les grands volumes "en général" ?...
    J'aurais vraiment cru le contraire.
    C'est lié au fait qu'il y aurait trop de déplacements aléatoires en mémoire/disque pour atteindre à chaque fois la donnée recherchée, au lieu de faire 2 tris définitifs et des accès en parallèles/proches ? (sur les 2 fichiers à joindre)
    En fait c'est juste que dans la plupart des cas les index pourrissent les performances à cause principalement des accès disques comme tu l'as dit (mais bon dans certains cas à la marge, c'est bien quand même)
    De plus la découpe des traitements permets de faciliter la reprise en cas de plantage : si les tris sont fait avant et que ton traitement plante tu peux le relancer sans refaire tout le tri avant.

    Citation Envoyé par Metalman Voir le message
    A propos de l'algo :
    J'avais cru lire ça dans un autre topic, et je suis toujours bloqué sur la signification du "high-value" (valeur haute ? plus grande valeur de clé ?).
    High-value correspond à la plus haute valeur que peut prendre la variable c'est à dire des 1 à tous les bits : sur un octets ça donne 1111 1111 ou en hexa : FF.
    L'opposé existe : Low-value = 0000 0000.

    L'intérêt de ces données est que pour la première il n’existe rien de plus grand et rien de plus petit pour la seconde (dans le contexte machine)

    Citation Envoyé par Metalman Voir le message
    Et quand vous dites :

    "Les fichiers doivent être triés sur la clé de jointure. C'est à faire avant donc... "

    C'est bien "organisé" de la plus petite à la plus grande valeur de clé ?
    Oui, en effet je n'ai pas précisé, my bad...

  15. #15
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Pour le tri, c'est moi qui n'avait pas compris qu'il fallait trier... et bref... passons !

    High-value/Low-value : valeur maximum/minimum en octet atteignable parla variable.... ok.

    Accès disques trop lents, ouf j'ai bien retenu mes cours !
    Et j'avais oublié la reprise sur erreur, en effet !
    Quand une entrée crash pour une raison X ou Y... c'est en effet beaucoup plus simple et court de reprendre dessus directement.

    ---------

    Pour ma "jointure"/table, j'ai trouvé ce lien : IBM - Exemple SEARCH

    Et j'ai commencé à taper ceci comme code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    	IDENTIFICATION DIVISION.
    	PROGRAM-ID. INTERETS.
    
    
    	ENVIRONMENT DIVISION.
    	CONFIGURATION SECTION.
    	SOURCE-COMPUTER. PC-I686.
    	OBJECT-COMPUTER. PC-I686.
    
    	INPUT-OUTPUT SECTION.
    	FILE-CONTROL.
    		SELECT ACCT-DATA-IN		ASSIGN TO DISK "ACCT.DAT"
                      ORGANIZATION IS LINE SEQUENTIAL
                      FILE STATUS IS ST-ACCT-IN.
       		SELECT RATE-DATA		ASSIGN TO DISK "RATE-KEY.DAT"
                      ORGANIZATION INDEXED
                      ACCESS RANDOM
                      RECORD KEY TYPE-ACCT
                      FILE STATUS IS ST-RATE.
    		SELECT ACCT-DATA-OUT	ASSIGN TO DISK "ACCT-OUT.DAT"
    		          ORGANIZATION IS LINE SEQUENTIAL
    				  FILE STATUS IS ST-ACCT-OUT.
    		SELECT TOTAL-DATA		ASSIGN TO DISK "TOTAL.DAT"
    		          ORGANIZATION IS LINE SEQUENTIAL
    				  FILE STATUS IS ST-TOTAL.
    
    	DATA DIVISION.
    	FILE SECTION.
     *    * Account analyzed
    	FD  ACCT-DATA-IN.
    	  01  ACCT-DATA-IN-RECORD.
    	    05	OWNER-NAME-IN		PIC X(20).
    		05  FILLER				PIC X.
    		05	SAVING-IN			PIC 9(7).
    		05  FILLER				PIC X.
    		05	DESCRIPTION-IN		PIC X(20).
     *    * Rate analyzed with key
    	FD  RATE-DATA.
          01  RATE-DATA-RECORD.
            05  TYPE-ACCT           PIC X(4).
            05  RATE                PIC 999V99.
            05  MAX-SAVING          PIC 9(5).
            05  DESCRIPTION         PIC X(32).
     *    * Updated Account
    	FD  ACCT-DATA-OUT.
    	  01  ACCT-DATA-OUT-RECORD.
    	    05	OWNER-NAME-OUT		PIC X(20).
    		05  FILLER				PIC X.
    		05	SAVING-OUT			PIC 9(7).
    		05  FILLER				PIC X.
    		05	DESCRIPTION-OUT		PIC X(20).
     *    * Total per Owner
    	FD  TOTAL-DATA.
    	  01  PRINT-REC.
    	    05	NAME-OUT			PIC X(20).
    		05  FILLER				PIC X(10).
    	    05	TOTAL-OUT			PIC Z(7).9(2).
    
    	WORKING-STORAGE SECTION.
        77  CUR-NAME				PIC X(32).
        77  CUR-ENTRIES				PIC 999.
    	77  CUR-FUND				PIC Z(7).9(2).
        01  ST-ACCT-IN				PIC X(02)   VALUE SPACES.
            88	ST-ACCT-IN-SUCCESS				VALUE '00'.
            88	ST-ACCT-IN-EOF					VALUE '10'.
        01  ST-ACCT-OUT				PIC X(02)   VALUE SPACES.
            88	ST-ACCT-OUT-SUCCESS				VALUE '00'.
            88	ST-ACCT-OUT-EOF					VALUE '10'.
        01  ST-RATE					PIC X(02)   VALUE SPACES.
            88	ST-RATE-SUCCESS					VALUE '00'.
            88	ST-RATE-EOF						VALUE '10'.
        01  ST-TOTAL				PIC X(02)   VALUE SPACES.
            88	ST-TOTAL-SUCCESS				VALUE '00'.
            88	ST-TOTAL-EOF					VALUE '10'.
        01  ARE-THERE-MORE-RECORDS	PIC X       VALUE 'Y'.
        01  IS-FIRST-ENTRY			PIC X       VALUE 'Y'.
            88  NOT-FIRST-ENTRY					VALUE 'N'.
    	01  CRT-ITER				PIC 99.
    	01  TABLE-RATE			OCCURS 9 TIMES
    							ASCENDING KEY ST-TYPE6-CCT
    							INDEXED BY MY-INDEX.
    		05  CRT-TYPE-ACCT		PIC X(4).
    		05  CRT-RATE			PIC 999V99.
    		05  CRT-MAX-SAVING		PIC 9(5).
    		05  CRT-DESCRIPTION		PIC X(32).
    
    	PROCEDURE DIVISION.
    	100-MAIN-MODULE.
    	  INITIALIZE ST-ACCT-IN ST-ACCT-OUT ST-RATE ST-TOTAL CRT-ITER
    	  MOVE HIGH-VALUES TO TABLE-RATE.
    	  PERFORM 200-LOAD-TABLE
    	  PERFORM 300-OPEN-ACCT
    	  STOP RUN.
    		
    	110-ERROR-EXIT.
    	  EXIT.
    	  STOP RUN.
    	 
    	200-LOAD-TABLE.
    	  OPEN INPUT RATE-DATA.
    	  IF ST-RATE-SUCCESS
    	    PERFORM 220-READ-RATE.
    	    PERFORM 210-LOAD-RATE.
    	      VARYING CRT-ITER FROM 1 BY 1 UNTIL CRT-ITER > 9
    	      OR ARE-THERE-MORE-RECORDS = 'N'.
    	    CLOSE RATE-DATA.
    	  ELSE
            DISPLAY 'RATE OPEN FAILED'.
            PERFORM 110-ERROR-EXIT.
    	  END-IF.
    
    	210-LOAD-RATE.
          MOVE RATE-DATA-RECORD TO TABLE-RATE (CRT-INDEX).
    	  PERFORM 220-READ-RATE.
    	  
    	220-READ-RATE.
     	  READ RATE-DATA
    	    AT END MOVE 'N' TO ARE-THERE-MORE-RECORDS.
    	 
    	300-OPEN-ACCT.
    	  MOVE 'Y' TO IS-FIRST-ENTRY.
    	  OPEN INPUT ACCT-DATA-IN
    	       OUTPUT ACCT-DATA-OUT.
          IF ST-ACCT-IN-SUCCESS AND ST-ACCT-OUT-SUCCESS
            DISPLAY 'ACCT OPEN SUCCESSFUL'.
          ELSE
            DISPLAY 'ACCT OPEN FAILED'.
            PERFORM 110-ERROR-EXIT.
          END-IF.
    	  PERFORM 210-PROCESSING-ACCT
    	  CLOSE ACCT-DATA-IN
    	        ACCT-DATA-OUT.
    	  
    	  
    	END PROGRAM INTERETS.
    Et... après avoir fini la partie 200 (chargement du fichier indexé en table) je me pose ces questions :
    1) Seul un fichier indexé peut entrer dans une table ? Parce que la méthode du READ input/MOVE TO tab[x++]... ça pourrait fonctionner avec un séquentiel tout simple, non ?
    Il y aurait une autre méthode en UN verbe pour charger le fichier dans une table ?
    Ou je suis à côté de la plaque et je devrais plutôt chercher le verbe qui sert à chercher dans le fichier ? (je pense que c'est cette solution que je devrais utiliser après avoir créé un fichier indexé...)
    Quel serait-il dans ce cas ?

    2) Quand je vais ouvrir mon fichier avec les comptes, je vais le lire séquentiellement...
    Le verbe SEARCH fait-il des sauts aléatoires dans le tableau ?
    Parce que d'après l'exemple IBM, ça ressemble grandement à un PERFORM UNTIL EOF sur les valeurs du tableau...
    Leur exemple m'a un peu perdu...
    Ils chargent une ligne d'un fichier, recherchent une valeur dans le tableau (en testant tout le tableau ?), écrivent le résultat, puis relisent une entrée.
    Le verbe SEARCH effectue de lui-même l'ensemble de la recherche ?
    (1 SEARCH = 1 PERFORM avec condition de sortie, etc... "en gros" ?)

    Merci de votre aid e!
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  16. #16
    Membre actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 138
    Points : 266
    Points
    266
    Par défaut
    Petites remarques sur le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     *    * Account analyzed
    	FD  ACCT-DATA-IN.
    	  01  ACCT-DATA-IN-RECORD.
    	    05	OWNER-NAME-IN		PIC X(20).
    		05  FILLER				PIC X.
    		05	SAVING-IN			PIC 9(7).
    		05  FILLER				PIC X.
    		05	DESCRIPTION-IN		PIC X(20).
    L'indentation porte à confusion : soit c'est mal indenté soit tu as une erreur de niveaux. Si les niveaux sont bons techniquement ça marche, mais la lisibilité en prend un coup.(et même remarque pour les autres fichiers)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        77  CUR-ENTRIES				PIC 999.
    	77  CUR-FUND				PIC Z(7).9(2).
    Même chose, c'est d'autant plus déroutant en 77.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        01  ST-ACCT-IN				PIC X(02)   VALUE SPACES.
            88	ST-ACCT-IN-SUCCESS				VALUE '00'.
            88	ST-ACCT-IN-EOF					VALUE '10'.
        01  ST-ACCT-OUT				PIC X(02)   VALUE SPACES.
            88	ST-ACCT-OUT-SUCCESS				VALUE '00'.
            88	ST-ACCT-OUT-EOF					VALUE '10'.
    Les puristes diront qu'un niveau 01 non groupe caylemal !
    Techniquement là aussi cela fonctionne. Cependant toujours pour la lisibilité, le 77 serait mieux.
    De plus avoir un 01 qui traine ça ouvre le chemin à des erreurs dues à des fausses manipulation : par exemple si tu colles une ligne 05 en dessous (d'un point de vue code, ça peut-être 10 lignes de commentaires plus bas...) par copier coller foireux, avec un 01 ça compile et tu vas avoir un potentiellement des bugs ou du code mort alors qu'avec un 77 la compilation plante directement et tu peux dois sécuriser ton code.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    	200-LOAD-TABLE.
    	  OPEN INPUT RATE-DATA.
    	  IF ST-RATE-SUCCESS
    	    PERFORM 220-READ-RATE.
    	    PERFORM 210-LOAD-RATE.
    	      VARYING CRT-ITER FROM 1 BY 1 UNTIL CRT-ITER > 9
    	      OR ARE-THERE-MORE-RECORDS = 'N'.
    	    CLOSE RATE-DATA.
    	  ELSE
            DISPLAY 'RATE OPEN FAILED'.
            PERFORM 110-ERROR-EXIT.
    	  END-IF.
    
    	210-LOAD-RATE.
          MOVE RATE-DATA-RECORD TO TABLE-RATE (CRT-INDEX).
    	  PERFORM 220-READ-RATE.
    	  
    	220-READ-RATE.
     	  READ RATE-DATA
    	    AT END MOVE 'N' TO ARE-THERE-MORE-RECORDS.
    Certes il faut structurer le code, cependant je pense vraiment qu'on arrive facilement à de la "sur-structuration" : un perform pour une seule ligne c'est à mon avis contre productif, le code devient très vite lourd...


    Citation Envoyé par Metalman Voir le message
    1) Seul un fichier indexé peut entrer dans une table ? Parce que la méthode du READ input/MOVE TO tab[x++]... ça pourrait fonctionner avec un séquentiel tout simple, non ?
    Il y aurait une autre méthode en UN verbe pour charger le fichier dans une table ?
    Ou je suis à côté de la plaque et je devrais plutôt chercher le verbe qui sert à chercher dans le fichier ? (je pense que c'est cette solution que je devrais utiliser après avoir créé un fichier indexé...)
    Quel serait-il dans ce cas ?
    C'est du cobol : tu peux te faire tatouer MOVE sur la fesse droite !
    Il n'y a malheureusement pas de verbe magique (enfin pas à ma connaissance), le cobol étant assez bas niveau tout doit être fait à la main. Il existe des fonctions intrinsèques mais qui dépendent du compilo et du paramétrage... donc bon, c'est à proscrire en apprentissage, après tu peux les utiliser quand tu as les spécifications précises de ton environnement de dev sachant que le code sera donc spécifique et pas totalement intéropérable.

    Ensuite ton rate-data est en access random donc ton read n'est pas un read sequentiel mais un accès direct. Donc sur ton read, le système va aller chercher l'enregistrement qui correspond à la clé qui est renseignée dans TYPE-ACCT, qui en l’occurrence n'est pas initialisée donc qui doit contenir ce qu'il y avait dans la mémoire à cette endroit au chargement du programme soit plus communément ce qu'on appelle "de la merde". Dans ce cas (je considère que le contenu ne correspond à aucune clé du fichier), le système doit jeter une exception INVALIDE KEY qui doit être gérée.
    La lecture des fichiers en access random est différente des accès séquentiel, il faut regarder la doc détaillé de l'instruction READ
    http://publib.boulder.ibm.com/infoce...2Frlpsread.htm

    Citation Envoyé par Metalman Voir le message
    2) Quand je vais ouvrir mon fichier avec les comptes, je vais le lire séquentiellement...
    Le verbe SEARCH fait-il des sauts aléatoires dans le tableau ?
    Parce que d'après l'exemple IBM, ça ressemble grandement à un PERFORM UNTIL EOF sur les valeurs du tableau...
    Leur exemple m'a un peu perdu...
    Ils chargent une ligne d'un fichier, recherchent une valeur dans le tableau (en testant tout le tableau ?), écrivent le résultat, puis relisent une entrée.
    Le verbe SEARCH effectue de lui-même l'ensemble de la recherche ?
    (1 SEARCH = 1 PERFORM avec condition de sortie, etc... "en gros" ?)

    Merci de votre aid e!
    Honnêtement, pendant mes premières années de cobol à chaque fois que j'ai demandé comment je mettais un search, on m'a répondu "touche pas à ça p'tit con !"
    Après quelques recherches j'ai compris pourquoi : l'instruction n'est que dans très rare cas "optimimum", et donc la plupart du temps ça te plombe considérablement les performances. La méthode utilisée en réel par l'instruction dépend du compilateur (n'ayant pas mis les mains dans le cambouis depuis plus de 5 ans, les compilo le gère peut-être mieux en fait... à vérifier). Je ne l'ai que très rarement utilisée (par contre j'ai fais multitude de fonction de rechercher à la mimine...) et donc là de tête, je ne sais plus du tout quels sont ses arguments et comment elle fonctionne...

  17. #17
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Pour l'indentation :
    Je code sur notepad++... et malheureusement... une tabulation ou 5 espaces donnent le même résultat... du coup "j'oublie" de remettre au même niveau avant de poster ici...

    Un 01 non groupe ?
    Pour les WORKING-STORAGE je devrais faire un 77 suivi de 88 en dessous ?
    Dans le livre que j'avais, je n'ai pas très bien compris les nombre pour cela...
    Je sais que plus la valeur est petite, plus il s'agit de la représentation d'une structure, plus le nombre est grand, plus on rentre dans les détails de la structure jusqu'à la valeur exacte.
    Il est vrai que j'ai eu des problèmes de compilation avec les 77 et 88, du coup j'ai mis des 01, 05... comme dans la section FILE.

    Bon... en regardant le code affiché par dev.net... c'est vrai que c'est dégueulasse l'indentation que ça génère.
    Le coup des labels pour une ligne, je l'ai tiré de la doc IBM en exemple (ça me paraissait bien ?)

    Ok..
    MOVE 'MOVE' TO FESSE-DROITE.
    Aïe !
    Bien reçu !

    Et plus sérieusement : le label 300 est encore en travail.
    Mais merci de me préciser qu'en faisant SEARCH avec un ACCESS RANDOM ça ira directement à la bonne ligne.

    OK, donc mieux vaut utiliser votre algo plus haut pour les cas réels.
    (mais comme mon but c'est de taper et faire fonctionner au moins une fois chaque "spécificité" COBOL... je vais copier la méthode IBM de recherche, puis j'essayerai de modifier le code pour utiliser la recherche "manuelle" !)
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  18. #18
    Expert éminent sénior
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    6 803
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 6 803
    Points : 32 058
    Points
    32 058
    Par défaut
    Si tu as un problème avec les niveaux 77, tu peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    01  WS-DONNEES-DIVERSES
        05  ST-ACCT-IN			PIC X(02)       VALUE SPACES.
            88	ST-ACCT-IN-SUCCESS			VALUE '00'.
            88	ST-ACCT-IN-EOF				VALUE '10'.
        05  ST-ACCT-OUT			PIC X(02)       VALUE SPACES.
            88	ST-ACCT-OUT-SUCCESS			VALUE '00'.
            88	ST-ACCT-OUT-EOF				VALUE '10'.
    voire appeler le 01 ST-ACCT, ou 01 ACCES-FICHIER..... Enfin bref, n'importe quoi, mais ça doit être un nom de groupe, et ne pas avoir de définition.

    Mais un niveau 01 qui contient directement une définition de données, c'est mal vu. Parce que le gars qui vient derrière toi n'aura pas l'habitude, tout simplement. Ça n'est pas mal en tant que tel, ça marche très bien, c'est juste anti-standard. Donc ça posera des problèmes plus tard - parce que le mainteneur sera surpris et risquera de faire des bêtises.


    Pour reprendre au départ, les niveaux, de 01 à 49, c'est purement hiérarchique, de la racine (01) aux branches les plus éloignées. Ensuite, c'est réservé. 66, ce sont des renommages(à proscrire, d'ailleurs, je n'en ai jamais vu), 77, ce sont des données seules, sans hiérarchie, et 88, ce sont des labels(j'adoooore les niveaux 88, bien plus puissants que les enums des langages "modernes").

    On a tendance aussi à mettre directement le deuxième niveau à 05 au lieu de 02 pour pouvoir insérer des niveaux intermédiaires en cas de besoin à la maintenance. C'est rarement utile, mais, là aussi, c'est standard. Et il arrive quand même que ça puisse servir.
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

  19. #19
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    OK ! Donc par convention :

    01 : nom d'une structure

    05-49 : membre d'une structure (pouvant accueillir une valeur)

    77 : variable seule

    88 : label/enum COBOL (j'en avais parlé avec un ami qui ne comprenait pas l'intérêt par rapport aux enums C, mais je suis d'accord avec vous : c'est en effet un cran au dessus) ou membre d'une structure locale

    J'ai tout réindenté, et en effet c'était le bordel mon fichier !
    Je vais suivre ces conventions pour mon exemple.

    -----

    EDIT : En essayant de respecter ces conventions, je me retrouve évidemment avec les problèmes de "field not subordinate".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
           IDENTIFICATION DIVISION.
           PROGRAM-ID. INTERETS.
    
           ENVIRONMENT DIVISION.
           CONFIGURATION SECTION.
           SOURCE-COMPUTER. PC-I686.
           OBJECT-COMPUTER. PC-I686.
    
           INPUT-OUTPUT SECTION.
           FILE-CONTROL.
             SELECT ACCT-DATA-IN  ASSIGN TO DISK "ACCT.DAT"
                    ORGANIZATION IS LINE SEQUENTIAL
                    FILE STATUS IS ST-ACCT-IN.
             SELECT RATE-DATA     ASSIGN TO DISK "RATE-KEY.DAT"
                    ORGANIZATION INDEXED
                    ACCESS RANDOM
                    RECORD KEY TYPE-ACCT
                    FILE STATUS IS ST-RATE.
             SELECT ACCT-DATA-OUT ASSIGN TO DISK "ACCT-OUT.DAT"
                    ORGANIZATION IS LINE SEQUENTIAL
                    FILE STATUS IS ST-ACCT-OUT.
             SELECT TOTAL-DATA    ASSIGN TO DISK "TOTAL.DAT"
                    ORGANIZATION IS LINE SEQUENTIAL
                    FILE STATUS IS ST-TOTAL.
    
           DATA DIVISION.
           FILE SECTION.
     *    * Account analyzed
           FD  ACCT-DATA-IN.
           01  ACCT-DATA-IN-RECORD.
               05  OWNER-NAME-IN        PIC X(20).
               05   FILLER              PIC X.
               05  SAVING-IN            PIC 9(7).
               05   FILLER              PIC X.
               05  ACCT-TYPE-IN         PIC X(4).
               05   FILLER              PIC X.
               05  DESCRIPTION-IN       PIC X(20).
    
     *    * Rate analyzed with key
           FD  RATE-DATA.
           01  RATE-DATA-RECORD.
               05  TYPE-ACCT            PIC X(4).
               05  RATE                 PIC 999V99.
               05  MAX-SAVING           PIC 9(5).
               05  DESCRIPTION          PIC X(32).
    
     *    * Updated Account
           FD  ACCT-DATA-OUT.
           01  ACCT-DATA-OUT-RECORD.
               05  OWNER-NAME-OUT       PIC X(20).
               05   FILLER              PIC X.
               05  SAVING-OUT           PIC 9(7).
               05   FILLER              PIC X.
               05  ACCT-TYPE-OUT        PIC X(4).
               05   FILLER              PIC X.
               05  DESCRIPTION-OUT      PIC X(20).
    
     *    * Total per Owner
           FD  TOTAL-DATA.
           01  PRINT-REC.
               05  NAME-OUT             PIC X(20).
               05   FILLER              PIC X(10).
               05  TOTAL-OUT            PIC Z(7).9(2).
    
           WORKING-STORAGE SECTION.
           77  CUR-NAME                 PIC X(32).
           77  CUR-ENTRIES              PIC 999.
           77  CUR-FUND                 PIC Z(7).9(2).
           77  CUR-PERCENTAGE           PIC 9V9(5).
           77  CUR-ITER                 PIC 99.
           77  ARE-THERE-MORE-RECORDS   PIC X           VALUE 'Y'.
    
           05  ST-ACCT-IN               PIC X(02)       VALUE SPACES.
               88  ST-ACCT-IN-SUCCESS                   VALUE '00'.
               88  ST-ACCT-IN-EOF                       VALUE '10'.
    
           05  ST-ACCT-OUT              PIC X(02)       VALUE SPACES.
               88  ST-ACCT-OUT-SUCCESS                  VALUE '00'.
               88  ST-ACCT-OUT-EOF                      VALUE '10'.
    
           05  ST-RATE                  PIC X(02)       VALUE SPACES.
               88  ST-RATE-SUCCESS                      VALUE '00'.
               88  ST-RATE-EOF                          VALUE '10'.
    
           05  ST-TOTAL                 PIC X(02)       VALUE SPACES.
               88  ST-TOTAL-SUCCESS                     VALUE '00'.
               88  ST-TOTAL-EOF                         VALUE '10'.
    
           05  IS-FIRST-ENTRY           PIC X           VALUE 'Y'.
               88  NOT-FIRST-ENTRY                      VALUE 'N'.
    
           05  TABLE-RATE           OCCURS 9 TIMES
                                    ASCENDING KEY CUR-TYPE-ACCT
                                    INDEXED BY MY-INDEX.
               88  CUR-TYPE-ACCT        PIC X(4).
               88  CUR-RATE             PIC 999V99.
               88  CUR-MAX-SAVING       PIC 9(5).
               88  CUR-DESCRIPTION      PIC X(32).
    
           PROCEDURE DIVISION.
           100-MAIN-MODULE.
             INITIALIZE ST-ACCT-IN ST-ACCT-OUT ST-RATE ST-TOTAL CUR-ITER.
             MOVE HIGH-VALUES TO TABLE-RATE.
             PERFORM 200-LOAD-TABLE.
             PERFORM 300-OPEN-ACCT.
             STOP RUN.
    
           110-ERROR-EXIT.
             EXIT.
             STOP RUN.
    interets_tinycobol.cob: 101: error: field not subordinate to any other: TABLE-RATE, on or before 'PROCEDURE'
    interets_tinycobol.cob: 105: error: identifier 'TABLE-RATE' must be subscripted or indexed, on or before '.'
    Ce qui m'embête beaucoup...
    Autant quand il y avait un 77 entre deux 05, je comprends que ça gène...
    Mais là...
    Mais l'exemple IBM utilise un 01 (que je peux mettre en 05 et décaler le reste) pour contenir le reste...
    Peut être que...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    01  PRODUCT-TABLE.
         05  INVENTORY-NUMBERS         OCCURS 50 TIMES
                                       ASCENDING KEY ITEM-NUMBER
                                       INDEXED BY INDEX-1.
                 07  ITEM-NUMBER       PIC 9(4).
                 07  ITEM-DESCRIPTION  PIC X(26).
                 07  ITEM-COST         PIC 9(8)V99.
    -----

    EDIT 2 : J'ai regardé les sources de tinyCobol... et en effet ça vient de lui :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      /********** locate level 01 field **************/
      for (sy=curr_field;sy->parent!=NULL;sy=sy->parent);
      if (sy->level != 1 && sy->level != 77 && sy->level != 66) {
         yyerror("field not subordinate to any other: %s",sy->name);
      }
    S'il ne trouve pas de 01, 77 ou 66... il n'en veut pas.
    Et en effet, si je corrige la ligne 92 en mettant un "01" au lieu d'un 05, ça fonctionne [et il faut faire de même pour les valeurs avant].

    Bref, le compilateur tinyCobol est donc moyen-moyen pour certaines choses...
    Mais c'est le seul que je puisse utiliser là où je travaille avec Windows... (j'évite de taper ça en prod' si vous voyez ce que je veux dire... )
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  20. #20
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Bon, cette fois je bloque sur de la syntaxe alors que j'ai vérifié avec 2 autres sites web.

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
           IDENTIFICATION DIVISION.
           PROGRAM-ID. INTERETS.
    
           ENVIRONMENT DIVISION.
           CONFIGURATION SECTION.
           SOURCE-COMPUTER. PC-I686.
           OBJECT-COMPUTER. PC-I686.
    
           INPUT-OUTPUT SECTION.
           FILE-CONTROL.
             SELECT ACCT-DATA-IN  ASSIGN TO DISK "ACCT.DAT"
                    ORGANIZATION IS LINE SEQUENTIAL
                    FILE STATUS IS ST-ACCT-IN.
             SELECT RATE-DATA     ASSIGN TO DISK "RATE-KEY.DAT"
                    ORGANIZATION INDEXED
                    ACCESS RANDOM
                    RECORD KEY TYPE-ACCT
                    FILE STATUS IS ST-RATE.
             SELECT ACCT-DATA-OUT ASSIGN TO DISK "ACCT-OUT.DAT"
                    ORGANIZATION IS LINE SEQUENTIAL
                    FILE STATUS IS ST-ACCT-OUT.
             SELECT TOTAL-DATA    ASSIGN TO DISK "TOTAL.DAT"
                    ORGANIZATION IS LINE SEQUENTIAL
                    FILE STATUS IS ST-TOTAL.
    
           DATA DIVISION.
           FILE SECTION.
     *    * Account analyzed
           FD  ACCT-DATA-IN.
           01  ACCT-DATA-IN-RECORD.
               05  OWNER-NAME-IN        PIC X(20).
               05   FILLER              PIC X.
               05  SAVING-IN            PIC 9(7).
               05   FILLER              PIC X.
               05  ACCT-TYPE-IN         PIC X(4).
               05   FILLER              PIC X.
               05  DESCRIPTION-IN       PIC X(20).
    
     *    * Rate analyzed with key
           FD  RATE-DATA.
           01  RATE-DATA-RECORD.
               05  TYPE-ACCT            PIC X(4).
               05  RATE                 PIC 999V99.
               05  MAX-SAVING           PIC 9(5).
               05  DESCRIPTION          PIC X(32).
    
     *    * Updated Account
           FD  ACCT-DATA-OUT.
           01  ACCT-DATA-OUT-RECORD.
               05  OWNER-NAME-OUT       PIC X(20).
               05   FILLER              PIC X.
               05  SAVING-OUT           PIC 9(7).
               05   FILLER              PIC X.
               05  ACCT-TYPE-OUT        PIC X(4).
               05   FILLER              PIC X.
               05  DESCRIPTION-OUT      PIC X(20).
    
     *    * Total per Owner
           FD  TOTAL-DATA.
           01  PRINT-REC.
               05  NAME-OUT             PIC X(20).
               05   FILLER              PIC X(10).
               05  TOTAL-OUT            PIC Z(7).9(2).
    
           WORKING-STORAGE SECTION.
           77  CUR-NAME                 PIC X(32).
           77  CUR-ENTRIES              PIC 999.
           77  CUR-FUND                 PIC Z(7).9(2).
           77  CUR-PERCENTAGE           PIC 9V9(5).
           77  CUR-ITER                 PIC 99.
           77  ARE-THERE-MORE-RECORDS   PIC X           VALUE 'Y'.
    
           01  ST-ACCT-IN               PIC X(02)       VALUE SPACES.
               88  ST-ACCT-IN-SUCCESS                   VALUE '00'.
               88  ST-ACCT-IN-EOF                       VALUE '10'.
    
           01  ST-ACCT-OUT              PIC X(02)       VALUE SPACES.
               88  ST-ACCT-OUT-SUCCESS                  VALUE '00'.
               88  ST-ACCT-OUT-EOF                      VALUE '10'.
    
           01  ST-RATE                  PIC X(02)       VALUE SPACES.
               88  ST-RATE-SUCCESS                      VALUE '00'.
               88  ST-RATE-EOF                          VALUE '10'.
    
           01  ST-TOTAL                 PIC X(02)       VALUE SPACES.
               88  ST-TOTAL-SUCCESS                     VALUE '00'.
               88  ST-TOTAL-EOF                         VALUE '10'.
    
           01  IS-FIRST-ENTRY           PIC X           VALUE 'Y'.
               88  NOT-FIRST-ENTRY                      VALUE 'N'.
    
           01  TABLE-RATE.
    	       07  TABLE-RATE-RECORD    OCCURS 9 TIMES
                                        ASCENDING KEY CUR-TYPE-ACCT
                                        INDEXED BY MY-INDEX.
                   88  CUR-TYPE-ACCT    PIC X(4).
                   88  CUR-RATE         PIC 999V99.
                   88  CUR-MAX-SAVING   PIC 9(5).
                   88  CUR-DESCRIPTION  PIC X(32).
    
           PROCEDURE DIVISION.
           100-MAIN-MODULE.
             INITIALIZE ST-ACCT-IN ST-ACCT-OUT ST-RATE ST-TOTAL CUR-ITER.
             MOVE HIGH-VALUES TO TABLE-RATE.
             PERFORM 200-LOAD-TABLE.
             PERFORM 300-OPEN-ACCT.
             STOP RUN.
    
           110-ERROR-EXIT.
             EXIT.
             STOP RUN.
    
           200-LOAD-TABLE.
             OPEN INPUT RATE-DATA.
             IF ST-RATE-SUCCESS
               DISPLAY 'RATE OPEN SUCCESS'
             ELSE
               DISPLAY 'RATE OPEN FAILED'
               PERFORM 110-ERROR-EXIT
             END-IF.
             READ RATE-DATA INTO RATE-DATA-RECORD.
     *    *   AT END MOVE 'N' TO ARE-THERE-MORE-RECORDS.
             PERFORM 210-LOAD-RATE
               VARYING CUR-ITER FROM 1 BY 1 UNTIL CUR-ITER > 9
               OR ARE-THERE-MORE-RECORDS = 'N'.
             CLOSE RATE-DATA.
    
           210-LOAD-RATE.
             MOVE RATE-DATA-RECORD TO TABLE-RATE-RECORD (CUR-ITER).
             READ RATE-DATA INTO RATE-DATA-RECORD.
     *    *    AT END MOVE 'N' TO ARE-THERE-MORE-RECORDS.
    
           300-OPEN-ACCT.
             MOVE 'Y' TO ARE-THERE-MORE-RECORDS.
             OPEN INPUT ACCT-DATA-IN
                  OUTPUT ACCT-DATA-OUT.
             IF ST-ACCT-IN-SUCCESS AND ST-ACCT-OUT-SUCCESS
               DISPLAY 'ACCT OPEN SUCCESSFUL'
             ELSE
               DISPLAY 'ACCT OPEN FAILED'
               PERFORM 110-ERROR-EXIT
             END-IF.
             PERFORM 310-PROCESSING-ACCT
             CLOSE ACCT-DATA-IN
                   ACCT-DATA-OUT.
    
           310-PROCESSING-ACCT.
             READ ACCT-DATA-IN INTO ACCT-DATA-IN-RECORD
               AT END MOVE 'N' TO ARE-THERE-MORE-RECORDS.
             PERFORM 320-SEARCH-RATE
               UNTIL ARE-THERE-MORE-RECORDS = 'N'.
    
           320-SEARCH-RATE.
             SET MY-INDEX TO 1.
             SEARCH TABLE-RATE-RECORD
     *    *  SEARCH ALL TABLE-RATE-RECORD
               AT END PERFORM 330-NOT-FOUND
               WHEN CUR-TYPE-ACCT (MY-INDEX) = ACCT-TYPE-IN
                 MOVE OWNER-NAME-IN TO CUR-NAME
                 DIVIDE CUR-RATE (MY-INDEX) BY 100 GIVING CUR-PERCENTAGE
                 MULTIPLY CUR-PERCENTAGE BY SAVING-IN GIVING CUR-FUND.
             PERFORM 340-WRITE-ACCT.
    
           330-NOT-FOUND.
             MOVE SAVING-IN TO SAVING-OUT.
    
           340-WRITE-ACCT.
             MOVE OWNER-NAME-IN TO OWNER-NAME-OUT.
             MOVE CUR-FUND TO SAVING-OUT.
             MOVE ACCT-TYPE-IN TO ACCT-TYPE-OUT.
             MOVE DESCRIPTION-IN TO DESCRIPTION-OUT.
             WRITE ACCT-DATA-OUT.
    
           END PROGRAM INTERETS.
    Et les erreurs :
    interets_tinycobol.cob: 158: error: syntax error, on or before 'CUR-TYPE-ACCT'
    interets_tinycobol.cob: 158: error: unknown or wrong statement, on or before 'CUR-TYPE-ACCT'
    interets_tinycobol.cob: 174: error: Identifier ACCT-DATA-OUT may not be used in WRITE statement, on or before '.'
    interets_tinycobol.cob: 174: error: Invalid picture in TABLE-RATE,type G,0,0, on or before 'END'
    Je vais vous avouer qu'avec le problème précédent + ce lien + IBM ILE COBOL
    Je ne vois plus du tout où peut se situer mon problème.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

Discussions similaires

  1. Question sur les fichiers indexés
    Par Johnny P. dans le forum Cobol
    Réponses: 4
    Dernier message: 05/04/2012, 17h24
  2. Réponses: 5
    Dernier message: 29/04/2011, 16h00
  3. fichier index table SAS
    Par reznac dans le forum SAS Base
    Réponses: 3
    Dernier message: 27/04/2011, 21h53
  4. recherche des tables liées à des index clustered
    Par lazzeroni dans le forum Administration
    Réponses: 1
    Dernier message: 28/02/2011, 15h35
  5. Recherche impossible dans un fichier indexé
    Par Msysteme dans le forum Windows Vista
    Réponses: 3
    Dernier message: 02/03/2009, 13h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo