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 :

Test pour trouver la fin d'un tableau


Sujet :

Cobol

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 6
    Points
    6
    Par défaut Test pour trouver la fin d'un tableau
    Bonjour,

    j'ai un petit soucis, qui doit être tout bète je pense ...

    J'ai un tableau, ou il y a 10 ou moins de 10 éléments... Donc pour le parcourir, je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PERFORM Traitement1 VARYING i FROM 1 BY 1 UNTIL i > 10.
    Cela ne permet pas de terminer le test si il y a moins de 10 éléments, et donc ca plante, alors j'avais pensé à rajouter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PERFORM Traitement1 VARYING i FROM 1 BY 1 UNTIL i > 11 OR FiVentesNomSerie(i) = " ".
    Mais il me marque comme erreur :" Malformed subscript"

    Quelqu'un aurrait une solution ?

    Merci

    Max

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 362
    Points : 419
    Points
    419
    Par défaut
    Bonjour,

    Pour analyser l'erreur de compilation, il faudrait avoir la description des données en WS.

    Néanmoins, la manière dont tu codes cette fin de boucle pose au moins trois problèmes :
    • C'est i > 10 et non i > 11 qu'il faudrait tester, car quand i = 11, tu es déjà en dehors du tableau.
    • Les tests mélant "i > limite" et "ELEMENT(i)" sont dangereux car dans une condition avec "OR", le compilateur ne garanti en général pas l'ordre d'évaluation des deux partie de l'expression booléenne. Que se passera-t-il selon toi si i = 11 et que tu testes ELEMENT(i), et si par malheur cette zone est en COMP-3 ?
    • Il est fortement recommandé de parenthèser les expression booléennes, tu peux avoir de très mauvaises surprises sinon.


    Le mieux à mon avis dans le cas qui te préoccupe est de gérer une variable "WS-NB-ELEM-TAB" qui contiendra le nombre réel d'éléments présents dans le tableau. Tu peux alors coder :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    PERFORM TRAITEMENT1
    VARYING IND-TAB
       FROM 1 BY 1
      UNTIL IND-TAB > WS-NB-ELEM-TAB

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Mais, alors comment savoir quelle valeur mettre dans WS-NB-ELEM-TAB ? Car la longueur est variable ! En fait c'est un fichier .seq qui entre dans le programme et parfois il y a 4 enregistrements, parfois 7, enfin cela dépend ... Le fichier qui entre dans le prog est le suivant : http://files.igfofo.be/VENTES.SEQ

    Le détail des données est celui-ci contre :

    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
           FILE SECTION.
          **************
           FD FiVentes.
          *
          *D‚claration des variables du fichier d'entr‚ FiVentes
          *
           01 FiVentesDelegue.
               02 FiVentesNumDel                   pic 9(3).
               02 FiVentesNomDel                   pic x(30).
               02 FiVentesAdresseDel               pic x(30).
    
           01 FiVentesCollection.
               02 FiVentesNumDelSecond             pic 9(3).
               02 FiVentesCodeCol                  pic x(4).
               02 FiVentesNomCol                   pic x(15).
    
           01 FiVentesSerie.
               02 FiVentesNumDelThird              pic 9(3).
               02 FiVentesCodeColSecond            pic 9(3).
               02 FiVentesNomSerie                 pic x(21).
               02 FiVentesTab.
                   03 FiVentesCellTab OCCURS 10.
                       04 FiVentesTabNomTit        pic x(30).
                       04 FiVentesTabQuantTit      pic 9(3).
    Ca peut peut-être vous aider ...

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    En fait, la difficulté viens du fait que tu ne connais pas le nombre d'enregistrements contenus dans ton fichier séquentiel ?

    il suffit de les compter
    Si tu dois retrouver le nombre de ventes de la collection 001 de ton délégué 001:

    On vas utiliser le status associé au fichier dans la clause select:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT Fic-Ventes ASSIGN 'VENTES.SEQ'
              ORGANISATION IS SEQUENTIAL
              ACCESS MODE IS SEQUENTIAL
              FILE STATUS IS W-STATUS
    .
    EN WORKING-STORAGE SECTION:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    77 W-STATUS         PIC XX.
    77 W-COMPTEUR     PIC 99.
    01 W-BUFFER.
        05 W-NUM-DEL    PIC X(3).
        05 W-CODE         PIC X.
        05 W-NUM-COLL  PIC X(3).
    En PROCEDURE DIVISION:
    (il faudras au préalable te "placer" sur le bon numero de délégué)

    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
    OPEN FIC-VENTES.
    On se place sur le bon délégué
    READ NEXT INTO BUFFER.
    PERFORM UNTIL W-NUM-DEL = '001' OR STA='10'
       READ NEXT INTO BUFFER
    END-PERFORM.
    
    On se place sur la bonne collection
    PERFORM UNTIL W-NUM-COLL = '001' OR STA='10'
       READ NEXT INTO BUFFER
    END-PERFORM.
    
    On compte
    MOVE 0 TO W-COMPTEUR.
    READ NEXT INTO BUFFER
    PERFORM UNTIL W-NUM-DEL NOT = '001'
               OR W-NUM-COLL NOT= '001'
               OR W-STATUS = 10
       ADD 1 TO W-COMPTEUR
       READ NEXT INTO W-BUFFER
    END-PERFORM.
    CLOSE FIC-VENTES.
    Et voilà, dans W-COMPTEUR, tu as le nombre d'éléments qui corresponds a tes critères ( délégué = '001' et collection='001' dans l'exemple ci-dessus )

    Un file status = 10 indique un End Of File.
    Il faudras le traiter dans le code ci-dessus dans le cas ou tu rencontre un End of File avant d'avoir trouvé le délégué et la collection

  5. #5
    Membre confirmé Avatar de Homer-ac
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    449
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 449
    Points : 586
    Points
    586
    Par défaut
    solution usuelle simple, positionner un indicateur de fin via un niveau 88
    on peut aussi forcer un indice à l'extérieur, ça marche mais c'est moins clean
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    A la lecture coder :  READ....
                                        at end     (ou test file status)
                                          MOVE 99 to I
    Ou plus propre parce que plus clair : SET FINI to TRUE
                                        not at end perform TRAITER-LU  
                          END-READ

    On peut coder Perform ... UNTIL I > 10 or FINI
    FINI étant un niveau 88 value '9' par exemple, après un indicateur de fin défini en PIC X value space.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 362
    Points : 419
    Points
    419
    Par défaut
    Et pour ce qui est de ton erreur de compilation, FiVentesNomSerie n'est pas dans le tableau, donc pas occursée.

    N'aurais-tu pas confondu avec FiVentesTabNomTit ?

    Dernière (?) chose : si tu veux tester qu'une zone en X(21) ou X(30) est à blanc, le plus simple et propre est de tester :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IF FiVentesTabNomTit (IND-TAB) = SPACE

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 362
    Points : 419
    Points
    419
    Par défaut
    Citation Envoyé par Homer-ac Voir le message
    FINI étant un niveau 88 value '9' par exemple, après un indicateur de fin défini en PIC X value space.
    Tout-à-fait d'accord avec l'utilisation d'un niveau 88, c'est très explicite et facile à lire.

    Par contre, il me semble préférable d'éviter au maximum les clauses "VALUE", à l'exception évidemment des constantes. Autant définir un couple de valeurs, telles que FINI VALUE 'F', EN-COURS VALUE 'E' et initialiser par un :

    si l'OPEN s'est bien déroulé.

    En effet, sur un batch, c'est exactement équivalent à un MOVE en initialisation. Par contre, dans un module appelé plusieurs fois, la valeur initiale n'est pas restaurée lors des appels suivant l'appel initial, d'où un risque. Une clause VALUE peut alors (doit uniquement ?) permettre de distinguer l'appel initial du module d'un autre.

    Bien sûr, je parle là des noms conditions en général, on parcours rarement plusieurs fois le même fichier dans un programme.

  8. #8
    Membre confirmé Avatar de Homer-ac
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    449
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 449
    Points : 586
    Points
    586
    Par défaut
    Sans rapport avec la question (la réponse de FREMEN167 est la bonne), mais puisqu'il s'agit de gestion d'indice, j'en profite pour signaler pour ceux qui utilisent Enterprise Cobol, que la gestion d'un tableau faisant varier un index est environ 3 fois plus rapide qu'avec un indice. Ici, occurs 10 pour une seule utilisation, peu importe, mais pour des traitements récursifs conséquents, ça peu produire des gains significatifs via des modifs sommes toutes assez simples.

  9. #9
    Membre confirmé Avatar de Homer-ac
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    449
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 449
    Points : 586
    Points
    586
    Par défaut
    Pour fremen167 (on se croise dans ces réponses) : d'accord à 100 pour cent. Je voulais juste faire simple dans la réponse en question.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 362
    Points : 419
    Points
    419
    Par défaut
    Citation Envoyé par Homer-ac Voir le message
    Pour fremen167 (on se croise dans ces réponses) : d'accord à 100 pour cent. Je voulais juste faire simple dans la réponse en question.
    Il faut dire que pour trouver un désaccord entre nous dans ce forum, j'ai l'impression qu'il va falloir se lever tôt

  11. #11
    Membre confirmé Avatar de Homer-ac
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    449
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 449
    Points : 586
    Points
    586
    Par défaut
    Les expériences diverges et les divergences font l'expérience
    Allez, puisque j'en étais resté au chapitres des performances, un petit résumé :
    COBOL II génère du code réentrant à la différence de COBOL 1.
    En conséquence, les données fixes de gestion pour COBOL IBM s'articulent autour d'un bloc de contrôle : la TGT et la Working Storage Section est allouée dynamiquement à l'initialisation du programme au premier appel (pour chaque TCB = tache en MVS). Le code en Procédure Division reste intègre (donc réentrant) et COBOL commence par faire un move en Working de toutes les values spécifiées. Il n'y a donc aucun gain à mettre des values plutôt que d'initialiser soit même ses données dans un paragraphe d'initialisation par exemple.
    Etant entendu que le COBOL appelé dans l'EXEC Batch est lui mème considéré comme un module (on peut donc faire un Goback, notion d'Enclave L.E.), il est beaucoup plus simple et fiable de raisonner systématiquement en programmation modulaire. Donc, encore une fois, tt à fait d'accord avec la remarque sur l'initialisation des données déclinées en niveaux 88.

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Han merci pour toutes vos réponses

    Un peu du mal parfois a décrypter lol mais ca a été

    merci beaucoup

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Trouver la fin d'un tableau dynamique
    Par Addjira dans le forum C
    Réponses: 3
    Dernier message: 08/04/2015, 10h54
  2. Réponses: 8
    Dernier message: 10/04/2014, 00h03

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