SORT and MERGE
==================
If you wished to take a file of unordered records and produce a new
file of these records sorted into ascending or descending order of a
field you would use SORT.
The League table program in the Sample code section uses this utility
to generate a league table from updated records from a data file,
sorted principally by descending points.
Consider this segment of code from this program:
000050 ENVIRONMENT DIVISION.
000060 INPUT-OUTPUT SECTION.
000070 FILE-CONTROL.
000080 SELECT TEAM-REC-IN ASSIGN TO "INPUT.REC"
000090 ORGANIZATION IS SEQUENTIAL.
000100 SELECT WORK-FILE ASSIGN TO SORTWK01.
000110 SELECT SORT-OUT ASSIGN TO "SORTED.REC"
000120 ORGANIZATION IS SEQUENTIAL.
000130 SELECT PRINT-FILE ASSIGN TO "PRINTOUT.TXT".
000140
000150 000160 DATA DIVISION.
000170 FILE SECTION.
000180 FD TEAM-REC-IN.
000190 01 TEAM-REC.
000200 03 TEAM-CODE PIC XXX.
000210 03 TEAM-NAME PIC X(20).
000220 03 PLAYED PIC 99.
000230 03 GOALS-FOR PIC 99.
000240 03 GOALS-AGST PIC 99.
000250 03 G-WON PIC 99.
000260 03 G-LOST PIC 99.
000270 03 G-DRAWN PIC 99.
000280 03 GOAL-DIFF PIC S99 SIGN LEADING SEPARATE.
000290 03 POINTS PIC 99.
000300 000310 SD WORK-FILE.
000320 01 WORK-REC.
000330 03 TEAM-CODE-KEY PIC XXX.
000340 03 PIC X(22).
000350 03 GF-KEY PIC 99.
000360 03 PIC X(8).
000370 03 GD-KEY PIC S99 SIGN LEADING SEPARATE.
000380 03 POINTS-KEY PIC 99.
In addition to the FD for the TEAM-REC-IN (the main data file) there
is also a WORK-FILE that the computer uses for sorting. Here it is
assigned to SORTWK01, required for the Fujitsu COBOL compiler, but for
MicroFocus you might code ASSIGN TO DISK or even ASSIGN TO
"B:TEMPFILE".
The WORK-FILE does not have a FD descriptor, but rather, has a sort
descriptor SD.
003310 SORT-TABLE.
003320 SORT WORK-FILE
003330 ON DESCENDING KEY POINTS-KEY GD-KEY GF-KEY
003340 USING TEAM-REC-IN
003350 GIVING SORT-OUT.
The SORT-TABLE paragraph then sorts the data file TEAM-REC-IN as shown
above. Note that the SORT verb is followed by WORK-FILE and that
TEAM-REC-IN is refered to with USING...
Since it is common for two teams to have the same number of points
then, the DESCENDING KEY first attempts to sort by points (POINTS-KEY)
but if these match then they are than sorted by goal difference
(GD-KEY) and then by goals scored (GF-KEY). If these all match then
the teams will be placed as the appear from the data file (for
TEAM-REC-IN I placed them in alphabetical order).
SORT-OUT is the destination of the sorted data where the new league
table would appear.
Note, a file that is to be sorted if already open, must be closed
prior to sorting. THE SORT STATEMENT WILL AUTOMATICALLY OPEN THE
UNSORTED FILE WHEN EXECUTED.
===========
MERGE
===========
To merge two sorted files into a single sorted file, the MERGE
statement is used:
MERGE WORK-FILE
ON ASCENDING KEY CUS-CODE-KEY
USING FILE-A
FILE-B
GIVING MERGED-FILE
You can merge more than 2 files if you wish. An SD would be required
as used with a SORT
----------------------------------------------------------------------------------------------------------
=============================
INPUT and OUTPUT PROCEDURE
==============================
The SORT statement above sorted all the records in the file into a new file.
But if you wanted to produce a sorted file that only contained, for
example, product numbers which begin with a '1', you would use an
INPUT PROCEDURE.
The record FD might be:
FD UNSORTED-FILE.
01 UNSORTED-RECORD.
03 1ST-DIGIT-OF-CODE PIC 9.
03 PIC X(20).
The description gives the minimum detail required. Now some procedure division:
PROCEDURE DIVISION.
SORT-SELECT.
SORT WORK-FILE
ON DESCENDING KEY PRODUCT-NO
INPUT PROCEDURE SELECT-PROD-CODE
GIVING SORTED-CODES-FILE
STOP RUN.
The INPUT PROCEDURE clause acts like a PERFORM, indicating the logic
to go to a different paragraph (i.e. procedure).
So the paragraph SELECT-PROD-CODE might be like this:
SELECT-PROD-CODE.
OPEN INPUT UNSORTED-DATA-FILE
PERFORM UNTIL END-OF-FILE
READ UNSORTED-DATA-FILE
AT END MOVE
'Y' TO EOF-FLAG
NOT AT END
IF 1ST-DIGIT-OF-CODE = 1 THEN
MOVE UNSORTED-RECORD TO WORK-REC
RELEASE WORK-REC
END-IF
END-READ
END-PERFORM
CLOSE UNSORTED-DATA-FILE
When the if condition is true, the record is moved to the work-file
(WORK-REC is the level 01 name) by the RELEASE verb, even though the
MOVE verb appears first (I dunno why..!). Unlike a simple SORT, you DO
have to OPEN the unsorted file prior to an input procedure.
OUTPUT PROCEDURE
If you just want to print specific sorted fields you would use an
OUTPUT PROCEDURE. Based on the above example:
PROCEDURE DIVISION.
PRINT-SORT-REC.
SORT WORK-FILE
ON DESCENDING KEY PRODUCT-NO
USING UNSORTED-RECORD
OUTPUT PROCEDURE PRINT-SELECT-PROD-CODE
STOP RUN.
The INPUT PROCEDURE clause acts like a PERFORM, indicating the logic
to go to a different paragraph (i.e. procedure).
So the paragraph SELECT-PROD-CODE might be like this:
SELECT-PROD-CODE.
OPEN OUTPUT PRINT-FILE
PERFORM UNTIL END-OF-FILE
RETURN UNSORTED-DATA-FILE
AT END MOVE 'Y' TO EOF-FLAG
NOT AT END
{move fields
in SD sort group to print fields}...
WRITE PRINT-RECORD FROM
{print group}
END-RETURN
END-PERFORM
CLOSE PRINT-FILE.
Instead of READ you use RETURN and then WRITE the record
to the printer rather than RELEASE the record to a file.
You can combine INPUT and OUTPUT procedures into the same sort
statement by replacing both the USING and GIVING statements:
SORT WORK-FILE ON DESCENDING KEY PRODUCT-NO
INPUT PROCEDURE SELECT-PROD-CODE
OUTPUT PROCEDURE PRINT-SELECT-PROD-CODE
STOP RUN.
------------------------------------------------------------------------------------------------------
No comments:
Post a Comment