Search code examples
cobolgnucobol

Subtract 1 from all the following record key after deleting a specific one


i want to delete a specific item then subtract 1 from all the following item-id so it would look like something like this:

item-id item-name qty price
 [01]   Item 1     10   99
 [02]   Item 2     10   99
 [03]   Item 3     10   99
 [04]   Item 4     33   23
 [05]   Item 5     22   33

-Delete item-id 03 new output:

item-id item-name qty price
 [01]   Item 1     10   99
 [02]   Item 2     10   99
 [03]   Item 4     33   23
 [04]   Item 5     22   33

ive tried something like this the delete works correctly i just dont know how to subtract 1 from all the following item-id's

   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
   SELECT INVENTORY
   ASSIGN TO 'C:\Users\User\Desktop\FINALS\inventory.dat'
       ORGANIZATION IS INDEXED
       ACCESS MODE IS RANDOM
       RECORD KEY IS ITEM-ID.
   FILE SECTION.
     FD INVENTORY.
     01 FILE-INVENTORY.
        02 ITEM-ID PIC 9(2).
        02 ITEM-NAME PIC X(25).
        02 QTY PIC Z99.
        02 PRICE PIC ZZZ9.00.
   WORKING-STORAGE SECTION.
     01 WS-INVENTORY.
        02 WS-ID PIC 9(2).
        02 WS-GA PIC X(25).
        02 WS-QTY PIC 999.
        02 WS-PRC PIC 9999.00.
     01 WS-EOF PIC A(4).
   PROCEDURE DIVISION.
       DEL-ITEM.
       OPEN I-O INVENTORY
       DISPLAY "  ENTER ID OF THE PRODUCT YOU WANT TO DELETE"
       DISPLAY "  ITEM ID: " WITH NO ADVANCING
       ACCEPT ITEM-ID
       MOVE ITEM-ID TO WS-ID
       DELETE INVENTORY
       INVALID KEY
            DISPLAY "ITEM DOES NOT EXIST"
       END-DELETE
       MOVE WS-ID TO ITEM-ID
       READ INVENTORY NEXT INTO WS-INVENTORY
       NOT AT END PERFORM ID-CHECK UNTIL WS-EOF = 'TRUE'
       AT END MOVE 'TRUE' TO WS-EOF
       CLOSE INVENTORY
   ID-CHECK.
       SUBTRACT 1 FROM WS-ID GIVING ITEM-ID REWRITE FILE-INVENTORY.

Solution

  • When using DELETE to remove a record, the DELETE statement must be preceded by a successful READ statement. For example,

        READ INVENTORY KEY ITEM-ID
        INVALID KEY
            SET some-error-condition TO TRUE
        NOT INVALID KEY
            DELETE INVENTORY
                more tests for errors
            END-DELETE
        END-READ
    

    After successfully deleting the record, a loop is needed to change the prime record key of the remaining records.

    Note that when changing the prime record key, REWRITE cannot be used. For ACCESS MODE IS RANDOM, use something like the following as a more complete example,

    01 WS-DELETE-KEY PIC 99.
    01 WS-DELETE-STATUS PIC 9 VALUE 0.
      88 RECORD-NOT-FOUND VALUE 1.
      88 RECORD-DELETED VALUE 2.
      88 DELETE-FAILED VALUE 3.
      88 NO-MORE-RECORDS VALUE 4.
    
        ACCEPT WS-DELETE-KEY
        PERFORM DELETE-RECORD
        IF RECORD-DELETED
            ADD 1 TO WS-DELETE-KEY
            PERFORM CHANGE-PRIMARY-KEY *> for the remaining records
                VARYING WS-DELETE-KEY FROM WS-DELETE-KEY BY 1
                UNTIL NO-MORE-RECORDS
            END-PERFORM
        END-IF
        .
    
    DELETE-RECORD.
        MOVE WS-DELETE-KEY TO ITEM-ID
        READ INVENTORY KEY ITEM-ID
        INVALID KEY
            SET RECORD-NOT-FOUND TO TRUE
        NOT INVALID KEY
            DELETE INVENTORY
            INVALID KEY
                SET DELETE-FAILED TO TRUE
            NOT INVALID KEY
                SET RECORD-DELETED TO TRUE
            END-DELETE
        END-READ
        .
    
    CHANGE-PRIMARY-KEY.
        MOVE WS-DELETE-KEY TO ITEM-ID
        READ INVENTORY KEY ITEM-ID
        INVALID KEY
            SET NO-MORE-RECORDS TO TRUE
        NOT INVALID KEY
            DELETE INVENTORY
            SUBTRACT 1 FROM ITEM-ID
            WRITE FILE-INVENTORY
        END-READ
    

    This assumes that all remaining records are sequentially numbered and that the failure to read a record means there are no more records.

    It may be wise to add additional checks in CHANGE-PRIMARY-KEY for other errors after the DELETE and WRITE statements.

    For ACCESS MODE IS DYNAMIC the code is similar but could use START and READ ... NEXT statements.