2009-11-18 12 views
29

Le fichier d'entrée ont des dossiers comme: 8712351,8712353,8712353,8712354,8712356,8712352,8712355 8712352,8712355Comment les doublons peuvent-ils être supprimés d'un fichier en utilisant COBOL?

En utilisant COBOL je dois supprimer les doublons dans le fichier ci-dessus et d'écrire dans un fichier de sortie. I écrit une logique simple pour lire les enregistrements et écrire dans un fichier de sortie.

Où dois-je mettre la logique de suppression des doublons (par exemple, 8712353,8712352) du fichier ci-dessus. Voici la logique du programme:

IDENTIFICATION DIVISION. 
    PROGRAM-ID.RemoveDup. 
    ENVIRONMENT DIVISION. 
    INPUT-OUTPUT SECTION. 
    FILE-CONTROL. 
    SELECT INPUTFILEDUP ASSIGN TO 'C:\Cobol\INPUTFILEDUP.txt' 
      ORGANIZATION IS LINE SEQUENTIAL. 
    SELECT OUTFILEDUP ASSIGN TO 'C:\Cobol\OUTFILEDUP.txt' 
       ORGANIZATION IS LINE SEQUENTIAL. 

    DATA DIVISION. 

    FILE SECTION. 
    FD INPUTFILEDUP. 
    01 INPUTFILEDUPREC. 
     88 EOFINPUTFILEDUP VALUE HIGH-VALUES. 
     02 INPUTFILEID  PIC 9(07). 

    FD OUTFILEDUP. 
    01 OUTFILEDUPREC   PIC 9(07). 

    WORKING-STORAGE SECTION. 
    77 WS-VARIABLE   PIC 9(09). 
    77 REC-NOT-MATCH   PIC 9(01). 
    77 CUR-VARIABLE   PIC 9(09). 

    PROCEDURE DIVISION. 
    BEGIN. 
    OPEN INPUT INPUTFILEDUP 
    OPEN OUTPUT OUTFILEDUP 

    READ INPUTFILEDUP 
     AT END SET EOFINPUTFILEDUP TO TRUE 
    END-READ 
    PERFORM UNTIL (EOFINPUTFILEDUP) 
       WRITE OUTFILEDUPREC FROM INPUTFILEID 
       READ INPUTFILEDUP 
        AT END SET EOFINPUTFILEDUP TO TRUE 
          PERFORM UNTIL (EOFINPUTFILEDUP) 
    END-READ 
    END-PERFORM 
        CLOSE INPUTFILEDUP 
        CLOSE OUTFILEDUP 
    STOP RUN. 

Je triai le fichier d'entrée dans l'ordre croissant comme: 8712351,8712353,8712353,8712354,8712356,8712352,8712355,8712352,8712355 Et cela a fonctionné, ci-dessous est le code modifié:

Mais supposons que mon fichier ne soit pas dans l'ordre croissant ou décroissant l'endroit où j'ai besoin d'écrire la logique de tri avant de supprimer des dups. S'il vous plaît pouvez-vous mettre à jour mon code ci-dessous pour cela comme je l'ai essayé, mais pas RÉUSSI à faire cela si la structure de Fiel d'entrée est comme:

8712351,8712353,8712353,8712354,8712356,8712352,8712355,8712352,8712355

IDENTIFICATION DIVISION. 
    PROGRAM-ID.RemoveDup2. 
    ENVIRONMENT DIVISION. 
    INPUT-OUTPUT SECTION. 
    FILE-CONTROL. 
    SELECT INPUTFILEDUP ASSIGN TO 'C:\Cobol\INPUTFILEDUP.txt' 
      ORGANIZATION IS LINE SEQUENTIAL. 
    SELECT OUTFILEDUP ASSIGN TO 'C:\Cobol\OUTFILEDUP.txt' 
       ORGANIZATION IS LINE SEQUENTIAL. 

    DATA DIVISION. 

    FILE SECTION. 
    FD INPUTFILEDUP. 
    01 INPUTFILEDUPREC. 
     88 EOFINPUTFILEDUP VALUE HIGH-VALUES. 
     02 INPUTFILEID  PIC 9(07). 

    FD OUTFILEDUP. 
    01 OUTFILEDUPREC   PIC 9(07). 

    WORKING-STORAGE SECTION. 
    77 WS-VARIABLE   PIC 9(09) VALUE ZERO. 
    77 REC-NOT-MATCH   PIC 9(01). 
    77 CUR-VARIABLE   PIC 9(7) VALUE ZERO. 

    PROCEDURE DIVISION. 
    BEGIN. 
    OPEN INPUT INPUTFILEDUP 
    OPEN OUTPUT OUTFILEDUP 

    READ INPUTFILEDUP 
     AT END SET EOFINPUTFILEDUP TO TRUE 
    END-READ 
    PERFORM UNTIL (EOFINPUTFILEDUP) 
     IF INPUTFILEID NOT EQUAL TO WS-VARIABLE 
       MOVE INPUTFILEID TO WS-VARIABLE 
       WRITE OUTFILEDUPREC FROM INPUTFILEID 
       READ INPUTFILEDUP 
        AT END SET EOFINPUTFILEDUP TO TRUE 
       PERFORM UNTIL (EOFINPUTFILEDUP) 
     ELSE 
       DISPLAY "dUPLICATE FOUND" INPUTFILEID 

    READ INPUTFILEDUP 
    AT END SET EOFINPUTFILEDUP TO TRUE 

    END-READ 

     END-PERFORM 

    CLOSE INPUTFILEDUP 
    CLOSE OUTFILEDUP 
    STOP RUN. 
+0

WOW nouvelle étiquette préférée! :) Question sur les données à partir de laquelle vous supprimez des doublons: les nombres tels que 8712351 vont-ils tous se produire dans une gamme relativement compacte, comme 8700000-8800000? Ou est-il possible que les nombres varient de 1-N sur une gamme énorme? –

Répondre

2

Lorsque Organization est Sequential, l'enregistrement supprimé correspond au dernier enregistrement lu. L'instruction Delete est valide uniquement lorsque la dernière opération sur le fichier est une instruction Read réussie. Dans le cas contraire, la Delete retourne une valeur File Status de 43. Parce qu'un Delete ne peut pas revenir File Status valeurs en commençant par un 2 lorsque le fichier est Open avec Sequential Access, codage Invalid Key sur un tel Delete n'est pas autorisé.

Lorsque Dynamic ou Random accès est sélectionné pour le fichier, le Delete statment, comme le Rewrite, devient un peu moins restrictive. L'enregistrement en cours de suppression n'a pas été préalablement lu. Il suffit de renseigner les informations primaires Key dans la description de l'enregistrement pour le fichier et d'émettre l'instruction Delete. Si l'enregistrement n'existe pas, un File Status de 23 est renvoyé et une condition Invalid Key existe.

De la page 274 du

Sams Teach Yourself COBOL in 24 Hours

la page 274 (que je viens dépoussiéré vers le bas de mon étagère hors). Donc, dans votre cas, vous allez vraisemblablement configurer vos enregistrements pour être triés par INPUTFILEID, faire un enregistrement au fur et à mesure des occurrences d'un INPUTFILEID après sa première occurrence, et Delete en conséquence (après l'avoir écrit dans votre fichier de sortie) .

1

Si vous triez le fichier avec un tri externe avant de le lire dans le programme cobol, vous pouvez supprimer les doublons avec le mot-clé SORT EQUALS. Si vous triez le fichier avant le programme cobol et ne supprimez pas les doublons, une simple instruction IF et un champ de sauvegarde vous permettront de supprimer les doublons.

Définissez un champ INPUTFILEID-save. Juste après la lecture ....IF inputfileid égal inputfileid-save relit sinon write ... après l'écriture déplace inputfileid to inputfileid-save. Vous devrez briser l'exécution actuelle pour le faire.

Si vous ne savez pas bien comprendre ce que je dis et vous aider à changer le code me laisse

5

Enfin, il a travaillé. Voici le code

IDENTIFICATION DIVISION. 
    PROGRAM-ID.RemoveDup2. 
    ENVIRONMENT DIVISION. 
    INPUT-OUTPUT SECTION. 
    FILE-CONTROL. 
    SELECT INPUTFILEDUP ASSIGN TO 'C:\Cobol\INPUTFILEDUP.txt' 
      ORGANIZATION IS LINE SEQUENTIAL. 
    SELECT OUTFILEDUP ASSIGN TO 'C:\Cobol\OUTFILEDUP.txt' 
       ORGANIZATION IS LINE SEQUENTIAL. 
    SELECT WorkFile ASSIGN TO "WORK.TMP". 

    DATA DIVISION. 

    FILE SECTION. 
    FD INPUTFILEDUP. 
    01 INPUTFILEDUPREC. 
     88 EOFINPUTFILEDUP VALUE HIGH-VALUES. 
     02 INPUTFILEID  PIC 9(07). 

    FD OUTFILEDUP. 
    01 OUTFILEDUPREC   PIC 9(07). 

    SD WorkFile. 
    01 WORKREC. 
     02 WINPUTFILEID  PIC 9(07). 

    WORKING-STORAGE SECTION. 
    77 WS-VARIABLE   PIC 9(09) VALUE ZERO. 
    77 REC-NOT-MATCH   PIC 9(01). 
    77 CUR-VARIABLE   PIC 9(7) VALUE ZERO. 

    PROCEDURE DIVISION. 
    BEGIN. 
     SORT WorkFile ON ASCENDING KEY WINPUTFILEID 
     USING INPUTFILEDUP GIVING INPUTFILEDUP 

    OPEN INPUT INPUTFILEDUP 
    OPEN OUTPUT OUTFILEDUP 

     READ INPUTFILEDUP 
       AT END SET EOFINPUTFILEDUP TO TRUE 
    END-READ 
     PERFORM UNTIL (EOFINPUTFILEDUP) 
      IF INPUTFILEID NOT EQUAL TO WS-VARIABLE 
        MOVE INPUTFILEID TO WS-VARIABLE 
        WRITE OUTFILEDUPREC FROM INPUTFILEID 
        READ INPUTFILEDUP 
         AT END SET EOFINPUTFILEDUP TO TRUE 
     PERFORM UNTIL (EOFINPUTFILEDUP) 
      ELSE 
        DISPLAY "DUPLICATE FOUND " INPUTFILEID 

    READ INPUTFILEDUP 
       AT END SET EOFINPUTFILEDUP TO TRUE 
    END-READ 
    END-PERFORM 

    CLOSE INPUTFILEDUP 
    CLOSE OUTFILEDUP 

    STOP RUN. 
1

sort est standard pour ces os-proches emplois suivre principe DRY, engrenages pour -t séparateur et -u pour visiteurs uniques. C'est C.