The FINAL clause represents a sophisticated control break mechanism within COBOL's Report Writer facility, serving as the ultimate control level that triggers processing when all input data has been exhausted and final summary calculations are required. This clause embodies the principles of hierarchical report control by providing comprehensive end-of-report processing capabilities, enabling sophisticated grand total calculations, and supporting complex summary report generation while maintaining data integrity and ensuring accurate final computations across multi-level control break hierarchies in enterprise reporting systems and business intelligence applications.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473IDENTIFICATION DIVISION. PROGRAM-ID. FINAL-CONTROL-BREAK-DEMO. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT SALES-INPUT-FILE ASSIGN TO 'SALES.DAT' ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS SALES-FILE-STATUS. SELECT SALES-REPORT-FILE ASSIGN TO 'SALESRPT.RPT' ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS REPORT-FILE-STATUS. DATA DIVISION. FILE SECTION. FD SALES-INPUT-FILE BLOCK CONTAINS 0 RECORDS RECORD CONTAINS 100 CHARACTERS. 01 SALES-INPUT-RECORD. 05 SI-REGION PIC X(10). 05 SI-DISTRICT PIC X(8). 05 SI-SALESPERSON PIC X(20). 05 SI-PRODUCT-CODE PIC X(8). 05 SI-SALES-AMOUNT PIC 9(7)V99. 05 SI-COMMISSION-RATE PIC 9V999. 05 SI-SALE-DATE PIC 9(8). 05 FILLER PIC X(34). FD SALES-REPORT-FILE BLOCK CONTAINS 0 RECORDS RECORD CONTAINS 132 CHARACTERS. 01 SALES-REPORT-RECORD PIC X(132). REPORT SECTION. RD SALES-REPORT CONTROLS ARE FINAL SI-REGION SI-DISTRICT SI-SALESPERSON PAGE LIMIT IS 60 LINES HEADING 1 FIRST DETAIL 5 LAST DETAIL 55 FOOTING 58. *> Report Header Group 01 REPORT-HEADER TYPE IS REPORT HEADING. 05 LINE NUMBER IS 1. 10 COLUMN 1 PIC X(20) VALUE 'SALES PERFORMANCE'. 10 COLUMN 25 PIC X(6) VALUE 'REPORT'. 10 COLUMN 60 PIC X(4) VALUE 'PAGE'. 10 COLUMN 65 PIC ZZ9 SOURCE IS PAGE-COUNTER. 05 LINE NUMBER IS 2. 10 COLUMN 1 PIC X(50) VALUE ALL '='. 05 LINE NUMBER IS 3. 10 COLUMN 1 PIC X(10) VALUE 'REGION'. 10 COLUMN 15 PIC X(8) VALUE 'DISTRICT'. 10 COLUMN 28 PIC X(11) VALUE 'SALESPERSON'. 10 COLUMN 45 PIC X(7) VALUE 'PRODUCT'. 10 COLUMN 58 PIC X(12) VALUE 'SALES AMOUNT'. 10 COLUMN 75 PIC X(10) VALUE 'COMMISSION'. *> Page Header Group 01 PAGE-HEADER TYPE IS PAGE HEADING. 05 LINE NUMBER IS 1. 10 COLUMN 1 PIC X(20) VALUE 'SALES PERFORMANCE'. 10 COLUMN 25 PIC X(6) VALUE 'REPORT'. 10 COLUMN 60 PIC X(4) VALUE 'PAGE'. 10 COLUMN 65 PIC ZZ9 SOURCE IS PAGE-COUNTER. *> Detail Line Group 01 DETAIL-LINE TYPE IS DETAIL. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(10) SOURCE IS SI-REGION. 10 COLUMN 15 PIC X(8) SOURCE IS SI-DISTRICT. 10 COLUMN 28 PIC X(20) SOURCE IS SI-SALESPERSON. 10 COLUMN 45 PIC X(8) SOURCE IS SI-PRODUCT-CODE. 10 COLUMN 55 PIC ZZZ,ZZ9.99 SOURCE IS SI-SALES-AMOUNT. 10 COLUMN 70 PIC ZZ9.99 SOURCE IS WS-COMMISSION. *> Salesperson Control Footer 01 SALESPERSON-TOTAL TYPE IS CONTROL FOOTING SI-SALESPERSON. 05 LINE NUMBER IS PLUS 2. 10 COLUMN 28 PIC X(20) VALUE 'SALESPERSON TOTAL:'. 10 COLUMN 55 PIC ZZZ,ZZ9.99 SUM SI-SALES-AMOUNT. 10 COLUMN 70 PIC ZZ9.99 SUM WS-COMMISSION. *> District Control Footer 01 DISTRICT-TOTAL TYPE IS CONTROL FOOTING SI-DISTRICT. 05 LINE NUMBER IS PLUS 2. 10 COLUMN 15 PIC X(8) VALUE 'DISTRICT'. 10 COLUMN 24 PIC X(5) VALUE 'TOTAL'. 10 COLUMN 55 PIC ZZZ,ZZ9.99 SUM SI-SALES-AMOUNT. 10 COLUMN 70 PIC ZZ9.99 SUM WS-COMMISSION. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 15 PIC X(30) VALUE ALL '-'. *> Region Control Footer 01 REGION-TOTAL TYPE IS CONTROL FOOTING SI-REGION. 05 LINE NUMBER IS PLUS 2. 10 COLUMN 1 PIC X(6) VALUE 'REGION'. 10 COLUMN 8 PIC X(5) VALUE 'TOTAL'. 10 COLUMN 55 PIC ZZZ,ZZ9.99 SUM SI-SALES-AMOUNT. 10 COLUMN 70 PIC ZZ9.99 SUM WS-COMMISSION. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(50) VALUE ALL '='. *> FINAL Control Footer (Grand Totals) 01 FINAL-TOTAL TYPE IS CONTROL FOOTING FINAL. 05 LINE NUMBER IS PLUS 3. 10 COLUMN 1 PIC X(15) VALUE 'GRAND TOTALS:'. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(50) VALUE ALL '='. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(20) VALUE 'TOTAL SALES AMOUNT:'. 10 COLUMN 55 PIC ZZZ,ZZ9.99 SUM SI-SALES-AMOUNT. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(20) VALUE 'TOTAL COMMISSION:'. 10 COLUMN 70 PIC ZZ9.99 SUM WS-COMMISSION. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(20) VALUE 'NUMBER OF RECORDS:'. 10 COLUMN 25 PIC ZZZ,ZZ9 SUM WS-RECORD-COUNT. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(20) VALUE 'AVERAGE SALE:'. 10 COLUMN 55 PIC ZZZ,ZZ9.99 SOURCE IS WS-AVERAGE-SALE. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(20) VALUE 'COMMISSION RATE:'. 10 COLUMN 25 PIC Z9.999 SOURCE IS WS-AVERAGE-COMMISSION-RATE. 05 LINE NUMBER IS PLUS 2. 10 COLUMN 1 PIC X(15) VALUE 'END OF REPORT'. 05 LINE NUMBER IS PLUS 1. 10 COLUMN 1 PIC X(50) VALUE ALL '='. WORKING-STORAGE SECTION. 01 FILE-STATUS-CODES. 05 SALES-FILE-STATUS PIC XX. 88 SALES-SUCCESS VALUE '00'. 88 SALES-EOF VALUE '10'. 05 REPORT-FILE-STATUS PIC XX. 88 REPORT-SUCCESS VALUE '00'. 01 PROCESSING-VARIABLES. 05 WS-COMMISSION PIC 9(5)V99. 05 WS-RECORD-COUNT PIC 9(5) VALUE 1. 05 WS-TOTAL-SALES PIC 9(9)V99 VALUE 0. 05 WS-TOTAL-COMMISSION PIC 9(7)V99 VALUE 0. 05 WS-AVERAGE-SALE PIC 9(7)V99. 05 WS-AVERAGE-COMMISSION-RATE PIC 9V999. 05 WS-TOTAL-COMMISSION-RATE PIC 9(3)V999 VALUE 0. 01 SAMPLE-DATA-TABLE. 05 SAMPLE-DATA OCCURS 10 TIMES. 10 SD-REGION PIC X(10). 10 SD-DISTRICT PIC X(8). 10 SD-SALESPERSON PIC X(20). 10 SD-PRODUCT-CODE PIC X(8). 10 SD-SALES-AMOUNT PIC 9(7)V99. 10 SD-COMMISSION-RATE PIC 9V999. 10 SD-SALE-DATE PIC 9(8). 01 SAMPLE-DATA-VALUES. 05 FILLER PIC X(67) VALUE 'NORTH DIST001 JOHN SMITH PROD001 0001250000250020240101'. 05 FILLER PIC X(67) VALUE 'NORTH DIST001 JOHN SMITH PROD002 0000875001750020240102'. 05 FILLER PIC X(67) VALUE 'NORTH DIST001 JANE DOE PROD001 0002100002000020240103'. 05 FILLER PIC X(67) VALUE 'NORTH DIST002 MIKE JOHNSON PROD003 0001500003000020240104'. 05 FILLER PIC X(67) VALUE 'SOUTH DIST003 SARA WILSON PROD001 0001800002250020240105'. 05 FILLER PIC X(67) VALUE 'SOUTH DIST003 SARA WILSON PROD002 0002250003000020240106'. 05 FILLER PIC X(67) VALUE 'SOUTH DIST004 TOM BROWN PROD003 0001950002750020240107'. 05 FILLER PIC X(67) VALUE 'EAST DIST005 LISA GARCIA PROD001 0002800003500020240108'. 05 FILLER PIC X(67) VALUE 'EAST DIST005 LISA GARCIA PROD002 0003200004000020240109'. 05 FILLER PIC X(67) VALUE 'WEST DIST006 DAVID MARTINEZ PROD003 0002650003250020240110'. 01 SAMPLE-DATA-REDEFINES REDEFINES SAMPLE-DATA-VALUES. 05 SAMPLE-RECORDS OCCURS 10 TIMES PIC X(67). 01 TABLE-INDEX PIC 9(2) VALUE 1. PROCEDURE DIVISION. MAIN-PROCESSING. PERFORM INITIALIZE-REPORT-PROCESSING PERFORM GENERATE-SAMPLE-DATA PERFORM PROCESS-SALES-REPORT PERFORM FINALIZE-REPORT-PROCESSING STOP RUN. INITIALIZE-REPORT-PROCESSING. DISPLAY 'Initializing FINAL control break processing...' OPEN OUTPUT SALES-INPUT-FILE OPEN OUTPUT SALES-REPORT-FILE IF SALES-SUCCESS AND REPORT-SUCCESS DISPLAY 'Files opened successfully' INITIATE SALES-REPORT DISPLAY 'Report initiated' ELSE DISPLAY 'Failed to open files' DISPLAY 'Sales status: ' SALES-FILE-STATUS DISPLAY 'Report status: ' REPORT-FILE-STATUS STOP RUN END-IF. GENERATE-SAMPLE-DATA. DISPLAY 'Generating sample sales data...' PERFORM VARYING TABLE-INDEX FROM 1 BY 1 UNTIL TABLE-INDEX > 10 MOVE SAMPLE-RECORDS(TABLE-INDEX) TO SALES-INPUT-RECORD WRITE SALES-INPUT-RECORD IF SALES-SUCCESS DISPLAY 'Sample record ' TABLE-INDEX ' written' ELSE DISPLAY 'Failed to write sample record ' TABLE-INDEX END-IF END-PERFORM CLOSE SALES-INPUT-FILE OPEN INPUT SALES-INPUT-FILE. PROCESS-SALES-REPORT. DISPLAY 'Processing sales report with FINAL control...' PERFORM UNTIL SALES-EOF READ SALES-INPUT-FILE AT END DISPLAY 'End of sales data reached' DISPLAY 'Processing FINAL control break...' PERFORM CALCULATE-FINAL-STATISTICS NOT AT END PERFORM PROCESS-SALES-RECORD END-READ END-PERFORM. PROCESS-SALES-RECORD. *> Calculate commission for this record COMPUTE WS-COMMISSION = SI-SALES-AMOUNT * SI-COMMISSION-RATE *> Accumulate totals for FINAL processing ADD SI-SALES-AMOUNT TO WS-TOTAL-SALES ADD WS-COMMISSION TO WS-TOTAL-COMMISSION ADD SI-COMMISSION-RATE TO WS-TOTAL-COMMISSION-RATE *> Generate detail line GENERATE DETAIL-LINE DISPLAY 'Processed: ' SI-REGION ' - ' SI-DISTRICT ' - ' SI-SALESPERSON DISPLAY 'Sale: ' SI-SALES-AMOUNT ' Commission: ' WS-COMMISSION. CALCULATE-FINAL-STATISTICS. *> Calculate statistics for FINAL control footer IF WS-RECORD-COUNT > 0 COMPUTE WS-AVERAGE-SALE = WS-TOTAL-SALES / WS-RECORD-COUNT COMPUTE WS-AVERAGE-COMMISSION-RATE = WS-TOTAL-COMMISSION-RATE / WS-RECORD-COUNT ELSE MOVE 0 TO WS-AVERAGE-SALE MOVE 0 TO WS-AVERAGE-COMMISSION-RATE END-IF DISPLAY 'FINAL statistics calculated:' DISPLAY 'Total Sales: ' WS-TOTAL-SALES DISPLAY 'Total Commission: ' WS-TOTAL-COMMISSION DISPLAY 'Average Sale: ' WS-AVERAGE-SALE DISPLAY 'Average Commission Rate: ' WS-AVERAGE-COMMISSION-RATE DISPLAY 'Record Count: ' WS-RECORD-COUNT. FINALIZE-REPORT-PROCESSING. DISPLAY 'Finalizing report processing...' TERMINATE SALES-REPORT CLOSE SALES-INPUT-FILE CLOSE SALES-REPORT-FILE DISPLAY 'FINAL control break processing completed' DISPLAY 'Report generated with grand totals and statistics'. *> Alternative FINAL Processing Without Report Writer IDENTIFICATION DIVISION. PROGRAM-ID. MANUAL-FINAL-PROCESSING. DATA DIVISION. WORKING-STORAGE SECTION. 01 CONTROL-BREAK-PROCESSING. 05 CURRENT-REGION PIC X(10). 05 CURRENT-DISTRICT PIC X(8). 05 CURRENT-SALESPERSON PIC X(20). 05 PREVIOUS-REGION PIC X(10). 05 PREVIOUS-DISTRICT PIC X(8). 05 PREVIOUS-SALESPERSON PIC X(20). 01 ACCUMULATOR-TOTALS. 05 SALESPERSON-SALES PIC 9(9)V99 VALUE 0. 05 SALESPERSON-COMMISSION PIC 9(7)V99 VALUE 0. 05 DISTRICT-SALES PIC 9(9)V99 VALUE 0. 05 DISTRICT-COMMISSION PIC 9(7)V99 VALUE 0. 05 REGION-SALES PIC 9(9)V99 VALUE 0. 05 REGION-COMMISSION PIC 9(7)V99 VALUE 0. 05 FINAL-SALES PIC 9(9)V99 VALUE 0. 05 FINAL-COMMISSION PIC 9(7)V99 VALUE 0. 05 FINAL-RECORD-COUNT PIC 9(6) VALUE 0. 01 CONTROL-FLAGS. 05 FIRST-RECORD-FLAG PIC X(1) VALUE 'Y'. 88 FIRST-RECORD VALUE 'Y'. 88 NOT-FIRST-RECORD VALUE 'N'. 05 END-OF-FILE-FLAG PIC X(1) VALUE 'N'. 88 END-OF-FILE VALUE 'Y'. 88 NOT-END-OF-FILE VALUE 'N'. PROCEDURE DIVISION. MANUAL-FINAL-DEMO. PERFORM INITIALIZE-MANUAL-PROCESSING PERFORM PROCESS-WITH-MANUAL-CONTROL-BREAKS PERFORM FINAL-PROCESSING-MANUAL STOP RUN. INITIALIZE-MANUAL-PROCESSING. DISPLAY 'Initializing manual FINAL processing...' MOVE SPACES TO PREVIOUS-REGION MOVE SPACES TO PREVIOUS-DISTRICT MOVE SPACES TO PREVIOUS-SALESPERSON. PROCESS-WITH-MANUAL-CONTROL-BREAKS. DISPLAY 'Processing with manual control breaks...' PERFORM UNTIL END-OF-FILE *> Simulate reading a record PERFORM READ-SALES-RECORD-SIMULATION IF NOT-END-OF-FILE *> Check for control breaks PERFORM CHECK-CONTROL-BREAKS *> Process current record PERFORM ACCUMULATE-TOTALS *> Update control fields PERFORM UPDATE-CONTROL-FIELDS END-IF END-PERFORM. READ-SALES-RECORD-SIMULATION. *> Simulate reading records with control break logic IF FIRST-RECORD MOVE 'NORTH' TO CURRENT-REGION MOVE 'DIST001' TO CURRENT-DISTRICT MOVE 'JOHN SMITH' TO CURRENT-SALESPERSON SET NOT-FIRST-RECORD TO TRUE ELSE *> Simulate end of file for demonstration SET END-OF-FILE TO TRUE END-IF. CHECK-CONTROL-BREAKS. *> Check for salesperson break IF CURRENT-SALESPERSON NOT = PREVIOUS-SALESPERSON AND NOT FIRST-RECORD PERFORM SALESPERSON-BREAK-PROCESSING END-IF *> Check for district break IF CURRENT-DISTRICT NOT = PREVIOUS-DISTRICT AND NOT FIRST-RECORD PERFORM DISTRICT-BREAK-PROCESSING END-IF *> Check for region break IF CURRENT-REGION NOT = PREVIOUS-REGION AND NOT FIRST-RECORD PERFORM REGION-BREAK-PROCESSING END-IF. SALESPERSON-BREAK-PROCESSING. DISPLAY 'Salesperson break: ' PREVIOUS-SALESPERSON DISPLAY 'Total sales: ' SALESPERSON-SALES DISPLAY 'Total commission: ' SALESPERSON-COMMISSION *> Add to district totals ADD SALESPERSON-SALES TO DISTRICT-SALES ADD SALESPERSON-COMMISSION TO DISTRICT-COMMISSION *> Reset salesperson totals MOVE 0 TO SALESPERSON-SALES MOVE 0 TO SALESPERSON-COMMISSION. DISTRICT-BREAK-PROCESSING. DISPLAY 'District break: ' PREVIOUS-DISTRICT DISPLAY 'Total sales: ' DISTRICT-SALES DISPLAY 'Total commission: ' DISTRICT-COMMISSION *> Add to region totals ADD DISTRICT-SALES TO REGION-SALES ADD DISTRICT-COMMISSION TO REGION-COMMISSION *> Reset district totals MOVE 0 TO DISTRICT-SALES MOVE 0 TO DISTRICT-COMMISSION. REGION-BREAK-PROCESSING. DISPLAY 'Region break: ' PREVIOUS-REGION DISPLAY 'Total sales: ' REGION-SALES DISPLAY 'Total commission: ' REGION-COMMISSION *> Add to final totals ADD REGION-SALES TO FINAL-SALES ADD REGION-COMMISSION TO FINAL-COMMISSION *> Reset region totals MOVE 0 TO REGION-SALES MOVE 0 TO REGION-COMMISSION. ACCUMULATE-TOTALS. *> Simulate accumulating current record totals ADD 1250.00 TO SALESPERSON-SALES ADD 31.25 TO SALESPERSON-COMMISSION ADD 1 TO FINAL-RECORD-COUNT. UPDATE-CONTROL-FIELDS. MOVE CURRENT-REGION TO PREVIOUS-REGION MOVE CURRENT-DISTRICT TO PREVIOUS-DISTRICT MOVE CURRENT-SALESPERSON TO PREVIOUS-SALESPERSON. FINAL-PROCESSING-MANUAL. DISPLAY 'Processing FINAL control break manually...' *> Force final breaks for remaining totals PERFORM SALESPERSON-BREAK-PROCESSING PERFORM DISTRICT-BREAK-PROCESSING PERFORM REGION-BREAK-PROCESSING *> Display FINAL totals DISPLAY 'FINAL TOTALS:' DISPLAY '=============' DISPLAY 'Grand Total Sales: ' FINAL-SALES DISPLAY 'Grand Total Commission: ' FINAL-COMMISSION DISPLAY 'Total Records Processed: ' FINAL-RECORD-COUNT IF FINAL-RECORD-COUNT > 0 COMPUTE WS-AVERAGE-SALE = FINAL-SALES / FINAL-RECORD-COUNT DISPLAY 'Average Sale Amount: ' WS-AVERAGE-SALE END-IF DISPLAY 'FINAL processing completed successfully'.