Search function error when retrieving data from table - cobol

01 emp-rec.
05 emp-rec-num pic x(3).
01 ws-table-data.
05 filler pic x(12)
value 'A12FIRST ONT'.
05 filler pic x(12)
value 'A14FIRST QUE'.
05 filler pic x(12)
value 'B10THIRD QUE'.
05 filler pic x(12)
value 'B12SECONDONT'.
05 filler pic x(12)
value 'B14SECONDONT'.
05 filler pic x(12)
value 'C09THIRD ONT'.
05 filler pic x(12)
value 'C11FIRST QUE'.
05 filler pic x(12)
value 'C13FIRST ONT'.
05 filler pic x(12)
value 'C21FIRST ONT'.
05 filler pic x(12)
value 'C22FIRST ONT'.
05 filler pic x(12)
value 'C23SECONDQUE'.
05 filler pic x(12)
value 'C25FIRST QUE'.
05 filler pic x(12)
value 'C27SECONDQUE'.
01 ws-table REDEFINES ws-table-data.
05 ws-table-element OCCURS 13 times
INDEXED BY data-index.
10 ws-operator-number pic x(3).
10 ws-operator-type pic x(6).
10 ws-operator-province pic x(3).
50-process-table-records.
set data-index to 1.
search ws-table-element
when (ws-operator-number(data-index) = emp-rec-num)
move ws-operator-type(data-index) to detail-line-type
move ws-operator-province(data-index)
to detail-line-province
when (ws-operator-number(data-index) is not equal to
emp-rec-num)
move 'Operator Not Found' to detail-line-type
end-search.
Output: https://prnt.sc/l5h64p
I have no idea why the first record in the table is printing 13 times, but it is supposed to iterate through the table. When emp-rec from the input file matches ws-operator-number, ws-operator-type and ws-operator-province are both supposed to be moved to the print line and printed, if not a messaged is displayed on the line instead.
Any and all help is appretiated, thanks!

Your second when phrase is the negation of the first. Each when phrase should be used to determine when the search statement should terminate. In effect you are telling the search to end if em-rec-no does not match the first entry of the table.
Change the code to match this.
50-process-table-records.
set data-index to 1.
search ws-table-element
at end
move 'Operator Not Found' to detail-line-type
when (ws-operator-number(data-index) = emp-rec-num)
move ws-operator-type(data-index) to detail-line-type
move ws-operator-province(data-index)
to detail-line-province
end-search.
Without knowing how 50-process-table-records is used, I can't tell if that will fix the problem of printing the same data 13 times.

Related

IGZ0201W and IGZ0035S errors in COBOL

*-----------------------
IDENTIFICATION DIVISION.
*-----------------------
PROGRAM-ID. TOPACCTS
AUTHOR. Sohan Kundu.
*--------------------
ENVIRONMENT DIVISION.
*--------------------
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRINT-LINE ASSIGN TO PRTLINE.
SELECT ACCT-REC ASSIGN TO ACCTREC.
*-------------
DATA DIVISION.
*-------------
FILE SECTION.
FD PRINT-LINE RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.
01 PRINT-REC.
05 FILLER PIC X(01) VALUE SPACES.
05 FIRST-NAME-O PIC X(11).
05 FILLER PIC X(02) VALUE SPACES.
05 LAST-NAME-O PIC X(22).
05 FILLER PIC X(02) VALUE SPACES.
05 ACCT-BALANCE-O PIC X(12).
05 FILLER PIC X(30) VALUE SPACES.
*
FD ACCT-REC RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.
01 ACCT-FIELDS.
05 FIRST-NAME PIC X(11).
05 LAST-NAME PIC X(22).
05 FILLER PIC X(28).
05 ACCT-BALANCE PIC X(12).
05 FILLER PIC X(7).
*
WORKING-STORAGE SECTION.
01 FLAGS.
05 LASTREC PIC X VALUE SPACE.
*
01 TOTAL-CLIENTS.
05 FILLER PIC X(14) VALUE
'# OF RECORDS: '.
05 CLIENTS PIC 9(3) VALUE ZERO.
05 FILLER PIC X(63) VALUE SPACES.
*
01 HEADER-1.
05 FILLER PIC X(30) VALUE 'REPORT FOR TOP ACCOUNT HOLDERS'.
05 FILLER PIC X(50) VALUE SPACES.
*
01 HEADER-2.
05 FILLER PIC X(05) VALUE 'Year '.
05 HDR-YR PIC 9(04).
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(06) VALUE 'Month '.
05 HDR-MO PIC X(02).
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(04) VALUE 'Day '.
05 HDR-DAY PIC X(02).
05 FILLER PIC X(53) VALUE SPACES.
*
01 HEADER-3.
05 FILLER PIC X(11) VALUE 'First Name '.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(10) VALUE 'Last Name '.
05 FILLER PIC X(14) VALUE SPACES.
05 FILLER PIC X(08) VALUE 'Balance '.
05 FILLER PIC X(35) VALUE SPACES.
*
01 HEADER-4.
05 FILLER PIC X(11) VALUE '-----------'.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(10) VALUE '----------'.
05 FILLER PIC X(14) VALUE SPACES.
05 FILLER PIC X(08) VALUE '--------'.
05 FILLER PIC X(35) VALUE SPACES.
*
01 WS-CURRENT-DATE-DATA.
05 WS-CURRENT-DATE.
10 WS-CURRENT-YEAR PIC 9(04).
10 WS-CURRENT-MONTH PIC 9(02).
10 WS-CURRENT-DAY PIC 9(02).
05 WS-CURRENT-TIME.
10 WS-CURRENT-HOURS PIC 9(02).
10 WS-CURRENT-MINUTE PIC 9(02).
10 WS-CURRENT-SECOND PIC 9(02).
10 WS-CURRENT-MILLISECONDS PIC 9(02).
*
*------------------
PROCEDURE DIVISION.
*------------------
OPEN-FILES.
OPEN INPUT ACCT-REC.
OPEN OUTPUT PRINT-LINE.
*
WRITE-HEADERS.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-DATA.
MOVE WS-CURRENT-YEAR TO HDR-YR.
MOVE WS-CURRENT-MONTH TO HDR-MO.
MOVE WS-CURRENT-DAY TO HDR-DAY.
WRITE PRINT-REC FROM HEADER-1.
WRITE PRINT-REC FROM HEADER-2.
MOVE SPACES TO PRINT-REC.
WRITE PRINT-REC AFTER ADVANCING 1 LINES.
WRITE PRINT-REC FROM HEADER-3.
WRITE PRINT-REC FROM HEADER-4.
MOVE SPACES TO PRINT-REC.
*
READ-NEXT-RECORD.
PERFORM READ-RECORD
PERFORM UNTIL LASTREC = 'Y'
PERFORM IS-BALANCE-HIGH
PERFORM READ-RECORD
END-PERFORM
.
*
CLOSE-STOP.
WRITE PRINT-REC FROM TOTAL-CLIENTS.
CLOSE ACCT-REC.
CLOSE PRINT-LINE.
STOP RUN.
*
READ-RECORD.
READ ACCT-REC
AT END MOVE 'Y' TO LASTREC
END-READ.
*
IS-BALANCE-HIGH.
IF FUNCTION NUMVAL-C(ACCT-BALANCE) > 8500000 THEN
ADD 1 TO CLIENTS
PERFORM WRITE-RECORD
END-IF.
*
WRITE-RECORD.
MOVE FIRST-NAME TO FIRST-NAME-O.
MOVE LAST-NAME TO LAST-NAME-O.
MOVE ACCT-BALANCE TO ACCT-BALANCE-O.
WRITE PRINT-REC.
*
I want to read the account details from an input file and print if the balance is more than 8500000.
The code is showing the following error:
IGZ0201W A file attribute mismatch was detected. File PRINT-LINE in program TOPACCTS had a record length of 81 and
the file specified in the ASSIGN clause had a record length of 80.
IGZ0035S There was an unsuccessful OPEN or CLOSE of file PRTLINE in program TOPACCTS at relative location X'1E8'.
Neither FILE STATUS nor an ERROR declarative were specified. The status code was 39.
From compile unit TOPACCTS at entry point TOPACCTS at compile unit offset +000001E8 at entry offset +000001E8
at address 1B8001E8.
In the JCL that you are using to execute this program (as a batchjob), within the step with EXEC PGM=TOPACCTS, make sure that you use a DD-card for your output file PRTLINE which looks similar to this:
//PRTLINE DD DISP=(NEW,CATLG),DSN=YOUR.DSN.GOES.HERE,
// UNIT=SYSDA,SPACE=(CYL,(5,5)),
// RECFM=FB,LRECL=80
That way you'll avoid the status code '39', which indicates that there is a mismatch between your record length of 80 (as shown in your program with CONTAINS 80 CHARACTERS), and whatever you specified in your JCL's DD-card.

Cobol output file not displaying properly

I'm trying to output 2 different lines in my cobol program, but it isn't outputting the way I want it to. Instead of writing one of each line it is writing two of the second line.
My code is:
DATA DIVISION.
FILE SECTION.
FD INVENT-FILE-IN.
01 INVENTORY-RECORD-IN.
05 PART-NUMBER PIC 9(5).
05 PART-NAME PIC X(20).
05 QUANTITY-ON-HAND PIC 9(3).
05 UNIT-PRICE PIC 9V99(6).
05 RE-ORDER-POINT PIC 9(3).
05 SUPPLIER-ID PIC X(2).
FD INVENT-REPORT-OUT.
01 INVENTORY-RECORD-OUT.
05 FILLER PIC X(1) VALUE SPACES.
05 PART-NUMBER PIC 9(5).
05 FILLER PIC X(3) VALUE SPACES.
05 PART-NAME PIC X(20).
05 FILLER PIC X(1) VALUE SPACES.
05 QUANTITY-ON-HAND PIC 9(4).
05 FILLER PIC X(1) VALUE SPACES.
05 UNIT-PRICE PIC 9V99(6).
05 FILLER PIC X(2).
05 INVENTORY-VALUE PIC 9V99(10).
01 INVENTORY-RECORD-HDR-LN1.
05 FILLER PIC X(9) VALUE SPACES.
05 FILLER PIC X(20) VALUE "INVENTORY REPORT FOR".
05 FILLER PIC X(3) VALUE SPACES.
05 CURRENT-MONTH PIC 9(2).
05 FILLER PIC X(18) VALUE SPACES.
01 INVENTORY-RECORD-HDR-LN2.
05 FILLER PIC X(1) VALUE SPACES.
05 FILLER PIC X(7) VALUE "PART NO".
05 FILLER PIC X(1) VALUE SPACES.
05 FILLER PIC X(9) VALUE "PART NAME".
05 FILLER PIC X(13) VALUE SPACES.
05 FILLER PIC X(2) VALUE "OH".
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(5) VALUE "PRICE".
05 FILLER PIC X(6) VALUE SPACES.
05 FILLER PIC X(5) VALUE "VALUE".
05 FILLER PIC X(2) VALUE SPACES.
01 INVENTORY-RECORD-END.
05 TOTAL-VALUE PIC 9(7)V99.
05 NUM-RECORDS-IN PIC 9(3).
05 NUM-RECORDS-OUT PIC 9(3).
FD RE-ORDER-FILE.
01 REORDER-RECORD-OUT.
05 PART-NUMBER PIC 9(5).
05 PART-NAME PIC X(20).
05 QUANTITY-ON-HAND PIC 9(3).
05 SUPPLIER-ID PIC X(2).
PROCEDURE DIVISION.
OPEN-RTN.
OPEN INPUT INVENT-FILE-IN.
OPEN OUTPUT INVENT-REPORT-OUT.
OPEN OUTPUT RE-ORDER-FILE.
PERFORM HEADER1-RTN.
HEADER1-RTN.
MOVE FUNCTION CURRENT-DATE(5:2) TO CURRENT-MONTH.
WRITE INVENTORY-RECORD-HDR-LN1.
PERFORM HEADER2-RTN.
HEADER2-RTN.
WRITE INVENTORY-RECORD-HDR-LN2
END-WRITE.
PERFORM CLOSE-RTN.
CLOSE-RTN.
CLOSE INVENT-FILE-IN.
CLOSE INVENT-REPORT-OUT.
CLOSE RE-ORDER-FILE.
STOP RUN.
The output file turns out like this:
PART NO PART NAME O11 PRICE VALUE
PART NO PART NAME O11 PRICE VALUE
But I want it to turn out like this:
INVENTORY REPORT FOR 11
PART NO PART NAME OH PRICE VALUE
These are just the headers for the rest of the data, and I can't figure out how to get them both to display properly. Any help is appreciated.

When I add slashes I get numbers added to the record

01 EMPLOYEE-RECORD1.
...
05 EMPLOYEEDOB1.
10 MONTH1 PIC 99.
*> here 10 FILLER PIC X(1) VALUE "/".
10 DAY11 PIC 99.
*> here 10 FILLER PIC X(1) VALUE "/".
10 YEARS1 PIC 9(4).
*> here
05 EMPLOYEE_YEARLYPAY1 PIC ZZ,ZZZV99.
...
There is more to the program and I will provide the code if necessary. In short my program takes input from a file and then loads it into a temp record. Then I copy the data from the temp record into the record for the output file and it writes it to the output file. When it writes it I lose the pay data and it adds numbers for the DOB instead of slashes. Why? What am I doing wrong?
program-id. Program1 as "NAME403.Program1".
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMPFILE
ASSIGN TO "C:\COBOLClass\DataFiles\NAME402.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT NEWEMPFILE
ASSIGN TO "C:\COBOLClass\DataFiles\NAME403.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
data division.
FILE SECTION.
FD EMPFILE.
01 EMPLOYEE-RECORD.
05 EMPLOYEE_ADDRESS.
10 BLDGNUMB-AND-STREET PIC X(10).
10 CITY PIC X(10).
10 STATE PIC X(10).
10 ZIPCODE PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEENUMB PIC 9(6).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEEDOB.
10 MONTH PIC 99.
10 DAY1 PIC 99.
10 YEARS PIC 9(4).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_FNAME PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_MNAME PIC X(2).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_LNAME PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_YEARLYPAY PIC ZZ,ZZZ.99.
FD NEWEMPFILE.
01 EMPLOYEE-RECORD1.
05 EMPLOYEENUMB1 PIC 9(6).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_FNAME1 PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_MNAME1 PIC X(2).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_LNAME1 PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEEDOB1.
10 MONTH1 PIC 99.
10 FILLER PIC X VALUE "/".
10 DAY11 PIC 99.
10 FILLER PIC X VALUE "/".
10 YEARS1 PIC 9(4).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_YEARLYPAY1 PIC ZZ,ZZZ.99.
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_ADDRESS1.
10 BLDGNUMB-AND-STREET1 PIC X(10).
10 CITY1 PIC X(10).
10 FILLER PIC X(10) VALUE SPACE.
10 STATE1 PIC X(10).
10 FILLER PIC X(10) VALUE SPACE.
10 ZIPCODE1 PIC X(10).
10 FILLER PIC X(166) VALUE "---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------".
05 EMPLOYEE_LNAME PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_YEARLYPAY PIC ZZ,ZZZ.99.
FD NEWEMPFILE.
01 EMPLOYEE-RECORD1.
05 EMPLOYEENUMB1 PIC 9(6).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_FNAME1 PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_MNAME1 PIC X(2).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_LNAME1 PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEEDOB1.
10 MONTH1 PIC 99.
10 FILLER PIC X VALUE "/".
10 DAY11 PIC 99.
10 FILLER PIC X VALUE "/".
10 YEARS1 PIC 9(4).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_YEARLYPAY1 PIC ZZ,ZZZ.99.
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_ADDRESS1.
10 BLDGNUMB-AND-STREET1 PIC X(10).
10 CITY1 PIC X(10).
10 FILLER PIC X(10) VALUE SPACE.
10 STATE1 PIC X(10).
10 FILLER PIC X(10) VALUE SPACE.
10 ZIPCODE1 PIC X(10).
10 FILLER PIC X(166) VALUE ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------".
working-storage section.
01 EMPLOYEE-RECORD-TEMP.
05 EMPLOYEE_ADDRESS-TEMP.
10 BLDGNUMB-AND-STREET-TEMP PIC X(10).
10 CITY-TEMP PIC X(10).
10 STATE-TEMP PIC X(10).
10 ZIPCODE-TEMP PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEENUMB-TEMP PIC 9(6).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEEDOB-TEMP.
10 MONTH-TEMP PIC 99.
10 DAY1-TEMP PIC 99.
10 YEARS-TEMP PIC 9(4).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_FNAME-TEMP PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_MNAME-TEMP PIC X(2).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_LNAME-TEMP PIC X(10).
05 FILLER PIC X(10) VALUE SPACE.
05 EMPLOYEE_YEARLYPAY-TEMP PIC ZZ,ZZZ.99.
01 SWITCHES.
05 CUSTMAST-EOF-SWITCH PIC X VALUE "N".
02 COUNTER PIC 9 VALUE 1.
procedure division.
000-STARTPROGRAM.
open input EMPFILE
output NEWEMPFILE.
PERFORM 100-GET-INFROMATION
UNTIL CUSTMAST-EOF-SWITCH="Y".
display "END OF SESSION.".
stop run.
100-GET-INFROMATION.
read EMPFILE into EMPLOYEE-RECORD-TEMP
at END
MOVE EMPLOYEE_ADDRESS-TEMP TO EMPLOYEE_ADDRESS1.
MOVE BLDGNUMB-AND-STREET-TEMP TO BLDGNUMB-AND-STREET1.
MOVE CITY-TEMP TO CITY1.
MOVE STATE-TEMP TO STATE1.
MOVE ZIPCODE-TEMP TO ZIPCODE1.
MOVE EMPLOYEENUMB-TEMP TO EMPLOYEENUMB1.
MOVE MONTH-TEMP TO MONTH1.
MOVE DAY1-TEMP TO DAY11.
MOVE YEARS-TEMP TO YEARS1.
MOVE EMPLOYEE_FNAME-TEMP TO EMPLOYEE_FNAME1.
MOVE EMPLOYEE_MNAME-TEMP TO EMPLOYEE_MNAME1.
move EMPLOYEE_LNAME-TEMP TO EMPLOYEE_LNAME1.
move EMPLOYEE_YEARLYPAY-TEMP to EMPLOYEE_YEARLYPAY1.
WRITE EMPLOYEE-RECORD1.
if COUNTER=5
close EMPFILE
close NEWEMPFILE
move "Y" to CUSTMAST-EOF-SWITCH
ELSE ADD 1 to COUNTER.
The actual MOVE or READ ... INTO are missing but I assume you (directly or indirectly) move a PIC 9(06) item to EMPLOYEEDOB1 which is a different format actual a PIC X(08).
As long as the question isn't improved (by showing both the data definition and the statement for the "copy") I say the answer to "What am I doing wrong?" is: You use the wrong definition for EMPLOYEEDOB1 and/or "copy" the data in falsely.
The target field definition must either match the original data or be changed to an edited field like PIC 99/99/99 (where the / are added automatically in the DISPLAY/WRITE you do with it) - in the later case: be aware that you cannot do any arithmetic with an edited field.
Alternative: MOVE all three parts of the date-of-birth (DOB) on their own and you can keep your definition (only useful if you want to do anything with the three parts afterwards).

Compiler Thinks Im Refering to Nonexistent Paragraph or Section

I am getting errors concerning my procedure division in one of my assignments for class. It is a COBOL Program that is supposed to keep a running total of the average height and weight of applicants, number of brown-eyed applicants, number of male applicants, and number of female applicants. Also the program is supposed to print the info of applicants who meet a specific set of requirements but i'm getting errors for almost all of my perform statements
COBCH0034 Operand operand should be numeric
A numeric value is required in this context, and you have specified a nonnumeric value.
COBCH0014 Invalid operand
The operand you have specified is in some way incorrect, and cannot be processed by your COBOL system. For example, you might have specified a negative integer where only positive integers are allowed
identification division.
program-id. ELECTRA-MODELING-AGENCY.
******************************************************************
*THIS PROGRAM PRODUCES THE REPORT ACCORDING TO THE GIVEN PRINTER
*SPACING CHART *
******************************************************************
environment division.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE ASSIGN TO "INFILE.txt"
Organization is line sequential.
SELECT OUTPUT-FILE ASSIGN TO "CHOSEN-APLICANTS.TXT"
Organization is line sequential.
data division.
FILE SECTION.
FD INPUT-FILE.
01 INPUT-REC.
05 APPLICANTS-NAME PIC X(20).
05 APPLICANTS-WEIGHT PIC 9(3).
05 APPLICANTS-HEIGHT PIC 9(2).
05 APPLICANTS-EYE-CODE PIC X.
05 APPLICANTS-HAIR-CODE PIC X.
05 APPLICANTS-GENDER PIC X.
FD OUTPUT-FILE.
01 OUTPUT-REC PIC X(78).
WORKING-STORAGE SECTION.
01 EOF PIC X VALUE "N".
01 HEADING-1.
05 FILLER PIC X(41) VALUE "M"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "O"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "D"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "E"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "L"
JUSTIFIED RIGHT.
05 FILLER PIC X(3) VALUE "R"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "E"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "P"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "O"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "R"
JUSTIFIED RIGHT.
05 FILLER PIC X(2) VALUE "T"
JUSTIFIED RIGHT.
05 FILLER PIC X(16) VALUE SPACES.
01 HEADING-2.
05 FILLER PIC X(23) VALUE "NAME"
JUSTIFIED RIGHT.
05 FILLER PIC X(13) VALUE "SEX"
JUSTIFIED RIGHT.
05 FILLER PIC X(10) VALUE "WEIGHT"
JUSTIFIED RIGHT.
05 FILLER PIC X(8) VALUE "HEIGHT"
JUSTIFIED RIGHT.
05 FILLER PIC X(5) VALUE "EYE"
JUSTIFIED RIGHT.
05 FILLER PIC X(6) VALUE "COLOR"
JUSTIFIED RIGHT.
05 FILLER PIC X(6) VALUE "HAIR"
JUSTIFIED RIGHT.
05 FILLER PIC X(6) VALUE "COLOR"
JUSTIFIED RIGHT.
05 FILLER PIC X VALUE SPACES.
01 DETAIL-LINE.
05 FILLER PIC X(10) VALUE SPACES.
05 NAME-OUT PIC X(20).
05 FILLER PIC X(4) VALUE SPACES.
05 GENDER-OUT PIC X.
05 FILLER PIC X(6) VALUE SPACES.
05 WEIGHT-OUT PIC X(3).
05 FILLER PIC X(6) VALUE SPACES.
05 HEIGHT-OUT PIC XX.
05 FILLER PIC X(6) VALUE SPACES.
05 EYE-COLOR-OUT PIC X(5).
05 FILLER PIC X(6) VALUE SPACES.
05 HAIR-COLOR-OUT PIC X(6).
01 SUMMARY-LINE-01
05 FILLER PIC X(17) VALUE "AVERAGE"
JUSTIFIED RIGHT.
05 FILLER PIC X(7) VALUE "HEIGHT"
JUSTIFIED RIGHT.
05 FILLER PIC X(3) VALUE "OF"
JUSTIFIED RIGHT.
05 FILLER PIC X(4) VALUE "ALL"
JUSTIFIED RIGHT.
05 FILLER PIC X(12) VALUE "APPLICANTS:"
JUSTIFIED RIGHT.
05 FILLER PIC X.
05 AVERAGE-HEIGHT PIC ZZZ9.
05 FILLER PIC X(12) VALUE SPACES.
01 SUMMARY-LINE-02
05 FILLER PIC X(17) VALUE "AVERAGE"
JUSTIFIED RIGHT.
05 FILLER PIC X(7) VALUE "WEIGHT"
JUSTIFIED RIGHT.
05 FILLER PIC X(3) VALUE "OF"
JUSTIFIED RIGHT.
05 FILLER PIC X(4) VALUE "ALL"
JUSTIFIED RIGHT.
05 FILLER PIC X(12) VALUE "APPLICANTS:"
JUSTIFIED RIGHT.
05 FILLER PIC X.
05 AVERAGE-WEIGHT PIC ZZZ9.
05 FILLER PIC X(12) VALUE SPACES.
01 SUMMARY-LINE-03
05 FILLER PIC X(16) VALUE "NUMBER"
JUSTIFIED RIGHT.
05 FILLER PIC X(3) VALUE "OF"
JUSTIFIED RIGHT.
05 FILLER PIC X(11) VALUE "BROWN-EYED"
JUSTIFIED RIGHT.
05 FILLER PIC X(12) VALUE "APPLICANTS:"
JUSTIFIED RIGHT.
05 FILLER PIC XX.
05 BROWN-EYED-APPLICANTS PIC ZZZ9.
05 FILLER PIC X(12) VALUE SPACES.
01 SUMMARY-LINE-04
05 FILLER PIC X(16) VALUE "NUMBER"
JUSTIFIED RIGHT.
05 FILLER PIC X(3) VALUE "OF"
JUSTIFIED RIGHT.
05 FILLER PIC X(5) VALUE "MALE"
JUSTIFIED RIGHT.
05 FILLER PIC X(12) VALUE "APPLICANTS:"
JUSTIFIED RIGHT.
05 FILLER PIC X(8) VALUE SPACES.
05 MALE-APPLICANTS PIC ZZZ9.
05 FILLER PIC X(12) VALUE SPACES.
01 SUMMARY-LINE-05
05 FILLER PIC X(16) VALUE "NUMBER"
JUSTIFIED RIGHT.
05 FILLER PIC X(3) VALUE "OF"
JUSTIFIED RIGHT.
05 FILLER PIC X(7) VALUE "FEMALE"
JUSTIFIED RIGHT.
05 FILLER PIC X(11) VALUE "APPLICANTS:"
JUSTIFIED RIGHT.
05 FILLER PIC X(6) VALUE SPACES.
05 FEMALE-APPLICANTS PIC ZZZ9.
05 FILLER PIC X(12) VALUE SPACES.
procedure division.
100-main.
OPEN INPUT INPUT-FILE
OUTPUT OUTPUT-FILE
PERFORM UNTIL EOF = 'Y'
READ INPUT-FILE
AT END MOVE 'Y' TO EOF
NOT AT END
PERFORM 200-HEADING.
PERFORM 200-AVG-HEIGHT.
PERFORM 200-AVG-WEIGHT.
PERFORM 200-BROWN-EYED-APPS.
PERFORM 200-MALE-APPS.
PERFORM 200-FEMALE-APPS.
PERFORM 200-MALE-DETAIL-LINE.
PERFORM 200-FEMALE-DETAIL-LINE.
CLOSE INPUT-FILE, OUTPUT-FILE.
STOP RUN.
200-HEADING.
WRITE OUTPUT-REC FROM HEADING-1.
MOVE SPACES TO OUTPUT-REC.
WRITE OUTPUT-REC.
WRITE OUTPUT-REC FROM HEADING-2.
MOVE SPACES TO OUTPUT-REC.
WRITE OUTPUT-REC.
200-AVG-HEIGHT.
IF NOT AT END
ADD APPLICANTS-HEIGHT TO AVERAGE-HEIGHT
ELSE AT END
DIVIDE AVERAGE-HEIGHT BY 21.
WRITE OUTPUT-REC FROM SUMMARY-LINE-01.
200-AVG-WEIGHT.
IF NOT AT END
ADD APPLICANTS-WEIGHT TO AVERAGE-WEIGHT
ELSE AT END
DIVIDE AVERAGE-HEIGHT BY 21.
WRITE OUTPUT-REC FROM SUMMARY-LINE-02.
200-BROWN-EYED-APPS.
IF APPLICANTS-EYE-CODE = 2
ADD 1 TO BROWN-EYED-APPLICANTS
ELSE CONTINUE.
WRITE OUTPUT-REC FROM SUMMARY-LINE-03.
200-MALE-APPS.
IF APPLICANTS-GENDER = M
ADD 1 TO MALE-APPLICANTS
ELSE CONTINUE.
WRITE OUTPUT-REC FROM SUMMARY-LINE-04.
200-FEMALE-APPS.
IF APPLICANTS-GENDER = F
ADD 1 TO FEMALE-APPLICANTS
ELSE CONTINUE.
WRITE OUTPUT-REC FROM SUMMARY-LINE-05.
200-MALE-DETAIL-LINE.
IF APPLICANTS-HAIR-CODE = 1
IF APPLICANTS-EYE-CODE = 1
IF APPLICANTS-GENDER = M
IF APPLICANTS-HEIGHT >= 72
IF 185 <= APPLICANTS-WEIGHT <= 200
ELSE CONTINUE.
WRITE OUTPUT-REC FROM 01 DETAIL-LINE.
200-FEMALE-DETAIL-LINE.
IF APPLICANTS-HAIR-CODE = 2
IF APPLICANTS-EYE-CODE = 2
IF APPLICANTS-GENDER = F
IF 62 <= APPLICANTS-HEIGHT <= 64
IF 110 <= APPLICANTS-WEIGHT <= 125
ELSE CONTINUE.
WRITE OUTPUT-REC FROM 01 DETAIL-LINE.
end program ELECTRA-MODELING-AGENCY.
So you have several things that are going wrong here. Let me detail a few of them and give you some hints to fix them.
You are using periods to end statements, this is awful and bad when you mix it with some of the newer (and by newer, i mean only 30 years old) style of statements, like inline perform and read/at end/not at end/end-read.
Instead of this:
PERFORM UNTIL EOF = 'Y'
READ INPUT-FILE
AT END MOVE 'Y' TO EOF
NOT AT END
PERFORM 200-HEADING.
PERFORM 200-AVG-HEIGHT.
PERFORM 200-AVG-WEIGHT.
PERFORM 200-BROWN-EYED-APPS.
PERFORM 200-MALE-APPS.
PERFORM 200-FEMALE-APPS.
PERFORM 200-MALE-DETAIL-LINE.
PERFORM 200-FEMALE-DETAIL-LINE.
CLOSE INPUT-FILE, OUTPUT-FILE.
STOP RUN.
You need something like this:
PERFORM UNTIL EOF = 'Y' <--- This is better as an 88 level
READ INPUT-FILE
AT END MOVE 'Y' TO EOF
NOT AT END
PERFORM SOMETHING <--- You need to accumulate you data here
END-READ
END-PERFORM
PERFORM 200-HEADING
PERFORM 200-AVG-HEIGHT
PERFORM 200-AVG-WEIGHT
PERFORM 200-BROWN-EYED-APPS
PERFORM 200-MALE-APPS
PERFORM 200-FEMALE-APPS
PERFORM 200-MALE-DETAIL-LINE
PERFORM 200-FEMALE-DETAIL-LINE
CLOSE INPUT-FILE, OUTPUT-FILE
STOP RUN. <--- This is the only period you need
<--- In your mainline
You can not do this:
200-AVG-HEIGHT.
IF NOT AT END <--- NOT AT END and AT END only work
<--- in the context of a READ statement
ADD APPLICANTS-HEIGHT TO AVERAGE-HEIGHT
ELSE AT END
DIVIDE AVERAGE-HEIGHT BY 21.
WRITE OUTPUT-REC FROM SUMMARY-LINE-01.
While you are looping through the file, accumulate the total height by adding each applicants to APPLICANTS-HEIGHT and adding 1 to your APPLICANTS-COUNT. When you are ready to do your summary line for height, do this:
200-AVG-HEIGHT.
DIVIDE APPLICANTS-HEIGHT BY APPLICANTS-COUNT
WRITE OUTPUT-REC FROM SUMMARY-LINE-01
. <---- Again, you only need a single period to end a paragraph
In all of your paragraphs, you are trying to accumulate your data AND write your summary line. This does not work. See the perform loop above where I have the "Perform Something To Accumulate your data", this is the paragraph you want to put all of your code that adds up every applicant. You need separate paragraphs, as you have, to write the summary lines.
So this should happen every record:
200-MALE-DETAIL-LINE.
IF APPLICANTS-HAIR-CODE = 1
IF APPLICANTS-EYE-CODE = 1
IF APPLICANTS-GENDER = M
IF APPLICANTS-HEIGHT >= 72
IF 185 <= APPLICANTS-WEIGHT <= 200
ELSE CONTINUE. <--- you are doing nothing here
WRITE OUTPUT-REC FROM 01 DETAIL-LINE.
It is better written like this:
200-MALE-DETAIL-LINE.
IF APPLICANTS-HAIR-CODE = 1
AND APPLICANTS-EYE-CODE = 1
AND APPLICANTS-GENDER = M
AND APPLICANTS-HEIGHT >= 72
AND (185 <= APPLICANTS-WEIGHT <= 200)
WRITE OUTPUT-REC FROM 01-DETAIL-LINE
END-IF
That should get you going. You will need to apply these hints to all the other paragraphs. In brief, your program should generally look like this:
Open Files
Perform until EOF
Read a-record
not at end
Perform Do-Detail-Lines
at end
Set EOF to true
End-Read
End-Perform
Perform Do-Summary-Lines
Close files
Stop Run.
Do-Detail-Lines.
...add up all the things you are averaging and counting...
...populate detail line...
write output-rec from detail-line
.
Do-Summary-Lines.
...calculate all averages...
...populate summary line...
write output-red from summary-line
...repeat as needed for other summary-lines...
.
Happy coding :-)

How to skip a record in COBOL with an if statement

FD STUDENTS-FILE-IN.
01 STUDENTS-RECORD-IN.
05 SSN-IN PIC X(9).
05 STUDENT-NAME-IN PIC X(11).
05 PIC X(5).
05 GRAD-STATUS-IN PIC X.
05 CLASS-STANDING-IN PIC X.
05 MAJOR-IN PIC X(3).
05 CREDIT-HOURS-IN PIC 9(3).
05 CREDIT-POINTS-IN PIC 9(3).
FD STUDENTS-FILE-OUT.
01 STUDENTS-RECORD-OUT PIC X(80).
WORKING-STORAGE SECTION.
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'.
01 PAGE-NUMBER PIC 99 VALUE ZERO.
01 LINE-COUNT PIC 99 VALUE ZERO.
01 SSID-BREAK.
03 FIRST-PART PIC X(3).
03 SECOND-PART PIC X(2).
03 THIRD-PART PIC X(4).
01 NAME-BREAK.
03 FIRST-LETTER PIC X(1).
03 MIDDLE-LETTER PIC X(1).
03 LAST-LETTER PIC X(10).
01 GRAD-CHECK PIC X.
01 WS-DATE.
05 RUN-YEAR PIC XX.
05 RUN-MONTH PIC XX.
05 RUN-DAY PIC XX.
01 HEADING-LINE-ONE.
05 PIC X(21) VALUE SPACES.
05 PIC X(33)
VALUE 'RHODES STATE COLLEGE GRADE REPORT'.
05 PIC X(6) VALUE SPACES.
05 HEADING-LINE-DATE.
10 MONTH-NOW PIC XX.
10 PIC X VALUE '/'.
10 DAY-NOW PIC XX.
10 PIC X VALUE '/'.
10 YEAR-NOW PIC XX.
05 PIC X(3) VALUE SPACES.
05 PIC X(4) VALUE 'PAGE'.
05 HL-1-PAGE-NUMBER PIC Z9 VALUE ZEROS.
01 HEADING-LINE-TWO.
05 PIC X(10) VALUE 'SOC SEC NO'.
05 PIC X(4) VALUE SPACES.
05 PIC X(12) VALUE 'STUDENT NAME'.
05 PIC X(3) VALUE SPACES.
05 PIC X(8) VALUE 'STANDING'.
05 PIC X(4) VALUE SPACES.
05 PIC X(5) VALUE 'MAJOR'.
05 PIC X(10) VALUE SPACES.
05 PIC X(5) VALUE 'HOURS'.
05 PIC X(2) VALUE SPACES.
05 PIC X(6) VALUE 'POINTS'.
05 PIC X(5) VALUE SPACES.
05 PIC X(3) VALUE 'GPA'.
01 DETAIL-LINE.
05 DL-SSID.
10 SSID-1 PIC X(3).
10 PIC X VALUE "-".
10 SSID-2 PIC X(2).
10 PIC X VALUE "-".
10 SSID-3 PIC X(4).
05 BLANK-B PIC X(3) VALUE SPACES.
05 DL-NAME .
10 FIRST-INI PIC X.
10 PIC X VALUE SPACES.
10 MID-INI PIC X.
10 PIC X VALUE SPACES.
10 LAST-NAME PIC X(10).
05 BLANK-C PIC X(3) VALUE SPACES.
05 YEAR-STATUS PIC X(9).
05 BLANK-D PIC X(3) VALUE SPACES.
05 STUDENT-MAJOR PIC X(13).
05 BLANK-E PIC X(5) VALUE SPACES.
05 STUDNET-HOURS PIC ZZ9.
05 BLANK-F PIC X(5) VALUE SPACES.
05 STUDENT-POINTS PIC ZZ9.
05 BLANK-G PIC X(4) VALUE SPACES.
05 STUDENT-GPA PIC 9V99.
01 TOTALS-LINE.
05 TOTALS PIC X(6) VALUE 'TOTALS'.
05 PIC X(34) VALUE SPACES.
05 HITS-TOTAL PIC ZZZ,ZZZ.
05 PIC X(9) VALUE SPACES.
05 BATS-TOTAL PIC ZZZ,ZZZ.
05 PIC X(10) VALUE SPACES.
05 AVG-TOTAL PIC .999.
PROCEDURE DIVISION.
100-MAIN.
OPEN INPUT STUDENTS-FILE-IN
OPEN OUTPUT STUDENTS-FILE-OUT
ACCEPT WS-DATE FROM DATE
MOVE RUN-MONTH TO MONTH-NOW
MOVE RUN-DAY TO DAY-NOW
MOVE RUN-YEAR TO YEAR-NOW
PERFORM 300-WRITE-HEADINGS
PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO '
READ STUDENTS-FILE-IN
AT END
MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 200-PROCESS-ONE-RECORD
END-READ
END-PERFORM
CLOSE STUDENTS-FILE-IN
CLOSE STUDENTS-FILE-OUT
STOP RUN.
200-PROCESS-ONE-RECORD.
IF LINE-COUNT >= 53
PERFORM 300-WRITE-HEADINGS
END-IF
* IF GRAD-STATUS-IN NOT = '1' AND NOT = '2'
* PERFORM 400-WRITE-TOTALS.
* END-IF
MOVE SSN-IN TO SSID-BREAK
MOVE FIRST-PART TO SSID-1
MOVE SECOND-PART TO SSID-2
MOVE THIRD-PART TO SSID-3
MOVE STUDENT-NAME-IN TO NAME-BREAK
MOVE FIRST-LETTER TO FIRST-INI
MOVE MIDDLE-LETTER TO MID-INI
MOVE LAST-LETTER TO LAST-NAME
MOVE GRAD-STATUS-IN TO GRAD-CHECK
IF GRAD-CHECK = 'Y'
END-IF
MOVE DETAIL-LINE TO STUDENTS-RECORD-OUT
WRITE STUDENTS-RECORD-OUT
AFTER ADVANCING 1 LINES
ADD 1 TO LINE-COUNT.
The input file looks like this
307662099KRAlexander Y2NES005017
Basically certain files won't meet the requirements and we are just suppose to just skip over them. This is an example of the file that we don't want to write to the output file and skip over. I apologize if I explained this poorly but I am really struggling with COBOL.
Your 200- paragraph needs to do something like this:
IF NOT ( <condition-for-skipping )
PERFORM PROCESS-THIS-RECORD
ELSE
PERFORM IGNORE-THIS-RECORD
END-IF
You can swap the conditions easily
IF ( <condition-for-skipping )
PERFORM IGNORE-THIS-RECORD
ELSE
PERFORM PROCESS-THIS-RECORD
END-IF
All the stuff you have in the 200- paragraph currently, you put in to a new paragrpah PROCESS-THIS-RECORD. You should have a new paragraph IGNORE-THIS-RECORD. If nothing else, it can count the records which are ignored. Then if you count the records which are processed, and count the input records, at the end you can check that everything is either processed or ignored.
You should check file-statuses. It is good to use scope-delimiters (like the END-IF) and keep full-stops/periods to a minimum.
88s are good to use for conditions. Saves lots of literals hanging about to make maintenance more complex.

Resources