2009-11-18 7 views
29

Die Eingabedatei haben Datensätze als: 8712351,8712353,8712353,8712354,8712356,8712352,8712355 8712352,8712355Wie können Duplikate mit COBOL aus einer Datei entfernt werden?

Mit COBOL Ich brauche Duplikate aus der obigen Datei zu entfernen und in eine Ausgabedatei schreiben. I schrieb einfache Logik zum Lesen von Datensätzen und Schreiben in eine Ausgabedatei.

Wo muss ich die Logik zum Entfernen von Duplikaten (sagen wir 8712353,8712352) aus der obigen Datei. Hier ist die Programmlogik:

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. 

ich die Eingabedatei in aufsteigender Reihenfolge sortiert, wie: 8712351,8712353,8712353,8712354,8712356,8712352,8712355,8712352,8712355 Und es hat funktioniert, ist unten der modifizierte Code:

Aber angenommen, wenn meine Datei nicht in aufsteigender oder absteigender Reihenfolge ist, wo ich die Sortierlogik schreiben muss, bevor ich die Duplikate entferne. Sie können Sie meinen Code unten für dieses Update als ich versuchte, aber nicht in dies zu tun erfolgreichen, wenn der Eingang fiel Struktur wie ist:

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 neues Lieblings-Tag! :) Frage zu den Daten, aus denen Duplikate entfernt werden: Werden die Zahlen wie 8712351 alle in einem relativ kompakten Bereich auftreten, z. B. 8700000-8800000? Oder ist es möglich, dass Zahlen von 1-N über eine enorme Bandbreite variieren? –

Antwort

2

Wenn OrganizationSequential ist, ist der gelöschte Datensatz der letzte gelesene Datensatz. Die Delete-Anweisung ist nur gültig, wenn die letzte Operation für die Datei eine erfolgreiche Read-Anweisung ist. Wenn nicht, kehrt der Delete einen File Status Wert von 43. Da ein Delete nicht File Status Werte beginnend mit einem 2 zurückkehren kann, wenn die Datei Open mit Sequential Access ist, Codierung Invalid Key auf einer solchen Delete nicht erlaubt ist.

Wenn Dynamic oder Random Zugriff für die Datei ausgewählt, die Delete statment, wie die Rewrite, wird etwas weniger restriktiv. Der gelöschte Datensatz muss nicht zuvor gelesen worden sein. Füllen Sie einfach die primären Key Informationen in der Datensatzbeschreibung für die Fle und geben Sie die Delete Anweisung aus. Wenn der Datensatz nicht existiert, wird eine File Status von 23 zurückgegeben und ein Invalid Key Zustand existiert.

Von Seite 274 von

Sams Teach Yourself COBOL in 24 Hours

Seite 274 (die ich nur abgestaubt habe nach unten aus aus meinem Bücherregal). In Ihrem Fall werden Sie Ihre Datensätze vermutlich so einrichten, dass sie nach INPUTFILEID sortiert werden. Erstellen Sie einen Datensatz, wenn Sie das Vorkommen INPUTFILEID nach dem ersten Auftreten durchlaufen, und Delete entsprechend (nachdem Sie es in Ihre Ausgabedatei geschrieben haben). .

1

Wenn Sie die Datei vor dem Lesen im cobol-Programm mit einer externen Sortierung sortieren, können Sie die Duplikate mit dem SORT-Schlüsselwort EQUALS entfernen. Wenn Sie die Datei vor dem cobol-Programm sortieren und keine Duplikate löschen, können Sie mit einer einfachen IF-Anweisung und einem Speicherfeld die Duplikate löschen.

Richten Sie ein INPUTFILEID-Speicherfeld ein. Gleich nach dem Lesen ....IF Eingabedatei gleich Eingabedatei - Speichern erneut lesen wenn nicht schreiben ... nach dem Schreiben move Eingabedatei nach Eingabedatei speichern. Sie müssen die aktuelle Leistung aufteilen, um dies zu tun.

Wenn Sie nicht vollständig verstehen, was ich sage, und wird Ihnen helfen, den Code zu ändern mich nur wissen lassen

5

Schließlich hat es funktioniert. Hier ist der 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 für diese os-close Arbeitsplätze Standard ist DRY-Prinzip zu folgen, -t Getriebe für Abscheider und -u für unique. Es ist C.