Issue while populating array in COBOL - cobol

I am getting very strange scenario. I have one array defined in my COBOL pgm.
05 A-TABLE.
10 A-TABLE-LIST OCCURS 10 TIMES INDEXED BY A-IDX.
15 FILLER PIC X(7) VALUE '<TEST>'.
15 A-LIST-VALUE PIC X(30).
15 FILLER PIC X(8) VALUE '</TEST>'.
I am setting A-IDX=1 and moving 'XYZ' to A-LIST-VALUE(A-IDX).
While displaying A-TABLE, it is showing as
XYZ------------------------------
and all spaces... :(
I am not getting what is the issue here?
Can anyone help me to resolve this?
Regards,
Saisha.

You cannot set values for a table that way. One way to set values in a table is to use a REDEFINES and a separate data area.
05 A-TABLE-X.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
10 FILLER PIC X(45)
VALUE '<TEST> </TEST>'.
05 A-TABLE REDEFINES A-TABLE-X.
10 A-TABLE-LIST OCCURS 10 TIMES INDEXED BY A-IDX.
15 FILLER PIC X(7).
15 A-LIST-VALUE PIC X(30).
15 FILLER PIC X(8).
That is pretty cumbersome. Another method is to MOVE the data in at runtime in an initialisation paragraph.
05 A-TABLE REDEFINES A-TABLE-X.
10 A-TABLE-LIST OCCURS 10 TIMES INDEXED BY A-IDX.
15 A-LIST-A PIC X(7).
15 A-LIST-VALUE PIC X(30).
15 A-LIST-B PIC X(8).
PERFORM VARYING A-IDX FROM 1 BY 1 UNTIL A-IDX > 1
MOVE '<TEST> TO A-LIST-A(A-IDX)
MOVE SPACES TO A-LIST-VALUE(A-IDX)
MOVE '</TEST> TO A-LIST-B(A-IDX)
END-PERFORM
I didn't try compiling any of these, this is just freehand.
As a side note, if you are using Enterprise COBOL version 3.2 or higher and you are trying to create XML in COBOL, there exists an XML GENERATE statement.

To my understanding, your question is why "XYZ<27 spaces>" is being displayed when only "XYZ" was moved. If so, you need to initialize before moving and trim the spaces before displaying or moving into another variable.
If your problem is not yet solved, describe much otherwise let us know how it was resolved.

Related

Suggest improvement for simple Cobol program

I'm an "aspiring" programmer currently trying to learn Cobol. The code below is obviously a very simple Cobol program with hard-coded values. However I am curious to know how a more experienced Cobol programmer would improve such simple program. Maybe there are a lot of things I am missing?
Feel free to suggest how you would accomplish it.
IDENTIFICATION DIVISION.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WORK-FIELDS.
05 EMPTY-LINE PIC X(132) VALUE SPACES.
01 HEADLINE.
05 VALUE "Invoice Specification".
01 FOOTER.
05 VALUE "Invoice End".
01 CALC-FIELDS.
10 SPOILER PIC 9(4).
10 WINDSHIELD PIC 9(3).
10 PARTSUM PIC 9(4).
10 DISCOUNT PIC 9(4).
10 TO-PAY-EXKL PIC 9(6).
10 VAT PIC 9(3).
10 TOTAL-TO-PAY PIC 9(4).
01 PRINT-FIELDS.
05 GROUP-1.
10 PIC X(36)
VALUE "01 SPOILER left-front, 1250:-".
10 SPOILER-EDITED PIC Z,ZZZ.99.
10 PIC X(2) VALUE ":-".
05 GROUP-2.
10 PIC X(36)
VALUE "02 Windshield, 390:-".
10 WINDSHIELD-EDITED PIC Z,ZZZ.99.
10 PIC X(2) VALUE ":-".
05 GROUP-3.
10 PIC X(36)
VALUE "Part Sum".
10 PARTSUM-EDITED PIC Z,ZZZ.99.
10 PIC X(2) VALUE ":-".
05 GROUP-4.
10 PIC X(36)
VALUE "Discount 15%".
10 DISCOUNT-EDITED PIC Z,ZZZ.99.
10 PIC X(2) VALUE ":-".
05 GROUP-5.
10 PIC X(36)
VALUE "To Pay exkl VAT".
10 TO-PAY-EDITED PIC Z,ZZZ.99.
10 PIC X(2) VALUE ":-".
05 GROUP-6.
10 PIC X(36)
VALUE "Added VAT 25%".
10 VAT-EDITED PIC Z,ZZZ.99.
10 PIC X(2) VALUE ":-".
05 GROUP-7.
10 PIC X(36)
VALUE "Total Amount to Pay".
10 PIC X(4) VALUE "SEK ".
10 TOTAL-EDITED PIC Z,ZZZ.99.
10 PIC X(2) VALUE ":-".
PROCEDURE DIVISION.
100-GENERATE-INVOICE.
PERFORM 200-CALCULATE.
PERFORM 300-PRINT-VALUES.
STOP RUN.
200-CALCULATE.
MOVE 1250 TO SPOILER
MOVE SPOILER TO SPOILER-EDITED
MOVE 390 TO WINDSHIELD
MOVE WINDSHIELD TO WINDSHIELD-EDITED
ADD SPOILER WINDSHIELD TO PARTSUM
MOVE PARTSUM TO PARTSUM-EDITED
MULTIPLY PARTSUM BY 0.15 GIVING DISCOUNT
MOVE DISCOUNT TO DISCOUNT-EDITED
SUBTRACT DISCOUNT FROM PARTSUM GIVING TO-PAY-EXKL
MOVE TO-PAY-EXKL TO TO-PAY-EDITED
MULTIPLY TO-PAY-EXKL BY 0.25 GIVING VAT
MOVE VAT TO VAT-EDITED
MULTIPLY TO-PAY-EXKL BY 1.25 GIVING TOTAL-TO-PAY
MOVE TOTAL-TO-PAY TO TOTAL-EDITED
.
300-PRINT-VALUES.
DISPLAY HEADLINE
DISPLAY EMPTY-LINE
DISPLAY EMPTY-LINE
DISPLAY GROUP-1
DISPLAY GROUP-2
DISPLAY GROUP-3
DISPLAY GROUP-4
DISPLAY GROUP-5
DISPLAY GROUP-6
DISPLAY EMPTY-LINE
DISPLAY GROUP-7
DISPLAY EMPTY-LINE
DISPLAY EMPTY-LINE
DISPLAY FOOTER
.
We don't know the objective of this code. Things to consider:
Determine objectives
Determine inputs and outputs
Design input file/db access mode (sequential/random/start from a criteria...etc.).
Identify the business rules.
Design the output (will you just produce a result via display only, will you update a database? will you print a report?)
Design a flow for the processing expected.
Code the required parts.
Note that your code above has no PROCEDURE DIVISION.
Maybe some code here could help amongst the ton of code already out there:
Sample Code

I can't figure out why my filler spaces aren't being displayed in my COBOL application

Ok so I'm making this application for school, which requires a certain format of spacing between the entries read in from .txt file. I've created the header using the filler term and the spacing works just fine, however when I apply the same method to the formatting of the records imported from the .txt it doesn't seem to work. I've tried everything under the sun and I can't make it work for the life of me!
This is what the output looks like now:
PARTNUMBER PARTNAME QUANTITY VALUE
1111111screws robertson 10 43210200Ajax
2222222screws robertson 08 41000100Ajax
2222233screws robertson 06 43210200Ajax
3333333screws robertson 04 41000100Ajax
4444444bolts dead 10 43210200Robo
5555555bolts dead 80 01000100Robo
But, it should be something like:
PARTNUMBER PARTNAME QUANTITY VALUE
1111111 screws robertson 10 43210200 Ajax
2222222 screws robertson 08 41000100 Ajax
2222233 screws robertson 06 43210200 Ajax
3333333 screws robertson 04 41000100 Ajax
4444444 bolts dead 10 43210200 Robo
5555555 bolts dead. 80 01000100 Robo
Below is the code that I think I need to make this happen, but again I'm just not sure why it isn't working
FILE SECTION.
FD INVENT-FILE-IN.
01 INVENT-RECORD-IN PIC X(49).
WORKING-STORAGE SECTION.
01 DISPLAY-HEADERS.
05 DISPLAY-PART-NUMBER PIC A(11)
VALUE "PARTNUMBER".
05 FILLER PIC X(1).
05 DISPLAY-PART-NAME PIC A(9)
VALUE "PARTNAME".
05 FILLER PIC X(4).
05 DISPLAY-QUANTITY PIC A(8)
VALUE "QUANTITY".
05 FILLER PIC X(2).
05 DISPLAY-VALUE PIC A(5)
VALUE "VALUE".
01 DISPLAY-RECORDS.
05 WS-INVENTORY-PART-NUMBER PIC 9(7).
05 FILLER PIC X(4) VALUE SPACES.
05 WS-INVENTORY-PART-NAME PIC X(20).
05 FILLER PIC X(4) VALUE SPACES.
05 WS-INVENTORY-QUANTITY PIC 9(4).
05 FILLER PIC X(2) VALUE SPACES.
05 WS-INVENTORY-VALUE PIC 9(8).
05 FILLER PIC X(1) VALUE SPACES.
05 WS-INVENTORY-SUPPLIER-CODE PIC X(5).
PROCEDURE DIVISION.
100-PROCESS-INVENTORY-FILE.
PERFORM 201-OPEN-INVENT-FILE.
PERFORM 202-DISPLAY-HEADER.
PERFORM 204-INPUT-INVENT-FILE
PERFORM 206-DISPLAY-RECORDS
UNTIL EOF-SWITCH = "Y".
PERFORM 205-TERMINATE-INVENTORY-FILE.
STOP RUN.
201-OPEN-INVENT-FILE.
OPEN INPUT INVENT-FILE-IN.
202-DISPLAY-HEADER.
DISPLAY DISPLAY-HEADERS.
206-DISPLAY-RECORDS.
MOVE INVENT-RECORD-IN TO DISPLAY-RECORDS.
DISPLAY DISPLAY-RECORDS.
READ INVENT-FILE-IN
AT END
MOVE "Y" TO EOF-SWITCH
NOT AT END
COMPUTE READ-COUNTER = READ-COUNTER + 1
END-READ.
204-INPUT-INVENT-FILE.
READ INVENT-FILE-IN
AT END
MOVE "Y" TO EOF-SWITCH
NOT AT END
COMPUTE READ-COUNTER = READ-COUNTER + 1
END-READ.
205-TERMINATE-INVENTORY-FILE.
CLOSE INVENT-FILE-IN.
As previously stated in the comments, in paragraph 206-DISPLAY-RECORDS, you are moving the entire input record to DISPLAY-RECORDS.
The problem here is that your input record is not formatted the same as your output record. This just means that you have to format it yourself. The easiest way to do this is to define your input input record differently. Something like this should do the trick:
FILE SECTION.
FD INVENT-FILE-IN.
01 INVENT-RECORD-IN.
05 INVENT-PART-NUMBER PIC 9(7).
05 INVENT-PART-NAME PIC X(20).
05 INVENT-QUANTITY PIC 9(4).
05 INVENT-VALUE PIC 9(8).
05 INVENT-SUPPLIER-CODE PIC X(5).
From here, its as easy as moving this fields to their equivalent spot in you DISPLAY-RECORDS:
206-DISPLAY-RECORDS.
MOVE INVENT-PART-NUMBER TO WS-INVENTORY-PART-NUMBER
MOVE INVENT-PART-NAME TO WS-INVENTORY-PART-NAME
MOVE INVENT-QUANTITY TO WS-INVENTORY-QUANTITY
MOVE INVENT-VALUE TO WS-INVENTORY-VALUE
MOVE INVENT-SUPPLIER-CODE TO WS-INVENTORY-SUPPLIER-CODE
READ INVENT-FILE-IN
AT END
MOVE "Y" TO EOF-SWITCH
NOT AT END
COMPUTE READ-COUNTER = READ-COUNTER + 1
END-READ.

COBOL program won't output the detail lines in my report

EDIT: Figured it out. I needed to call the read again at the end of A420-COUNT-MARKS
Edit: Working on a z/OS mainframe that I'm accessing via Vista TN3270. The program is submitted using JCL which was provided by the teacher.
I'm in school for programming and I have a COBOL assignment where my program reads a file full of subject names and codes and a file full of student marks and an associated subject code. It must use this info to create a report that lists all the subjects and count the number of students that received grades of A , B, C, D or F for each subject. It then totals up the amount of each grade at the bottom.
Report example:
01 ABC COLLEGE TESTING CENTER
02 TEST RESULTS SUMMARY DATE: yyyy/mm/dd
03
04 SUBJECT NAME A B C D F
05
06 xxxxxxxxxxxxxxxxxxxx 9,999 9,999 9,999 9,999 9,999
07 xxxxxxxxx 9,999 9,999 9,999 9,999 9,999
19
20 TOTAL 99,999 99,999 99,999 99,999 99,999
The problem is that my program is only outputting the header rows, but won't output the detail rows or the grand total row. I've written functions to perform these things but they're not getting any errors so I have no idea what's going wrong.
Here's my file control and file section:
FILE-CONTROL.
SELECT F01-SUBJ-FILE ASSIGN TO F01SUBJ.
SELECT F02-MARK-FILE ASSIGN TO F02MARK.
SELECT F03-REPT-FILE ASSIGN TO F03REPT.
FILE SECTION.
FD F01-SUBJ-FILE
RECORDING MODE IS F
RECORD CONTAINS 80 CHARACTERS
DATA RECORD IS F01-SUBJ-RECORD.
01 F01-SUBJ-RECORD.
05 F01-SUBJ-CODE PIC X(6).
05 F01-SUBJ-NAME PIC X(20).
05 PIC X(54).
FD F02-MARK-FILE
RECORDING MODE IS F
RECORD CONTAINS 80 CHARACTERS
DATA RECORD IS F02-MARK-RECORD
01 F02-MARK-RECORD.
05 F02-STUD-NAME PIC X(20).
05 F02-SUBJ-CODE PIC X(6).
05 PIC X.
05 F02-DATE-TEST PIC X(8).
05 F02-STUD-MARK PIC 9(3).
05 PIC X(42).
FD F03-REPT-FILE
RECORDING MODE IS F
RECORD CONTAINS 120 CHARACTERS
DATA RECORD IS F03-REPT-RECORD.
01 F03-REPT-RECORD.
05 PIC X(120).
Here's working storage:
WORKING-STORAGE SECTION.
01 W01-EOF-SWITCH.
05 W01-MARK-EOF PIC X VALUE 'N'.
05 W01-SUBJ-EOF PIC X VALUE 'N'.
01 W02-TEST-TABLE.
05 W02-SUBJ-COUNT PIC 99 VALUE 0.
05 W02-SUBJ-MAX PIC 99 VALUE 50.
05 W02-TEST-ROW OCCURS 1 TO 50
DEPENDING ON W02-SUBJ-COUNT
ASCENDING KEY IS W02-SUBJ-CODE
INDEXED BY W02-IDX.
10 W02-SUBJ-CODE PIC X(6) VALUE SPACES.
10 W02-SUBJ-NAME PIC X(20) VALUE SPACES.
10 W02-A-CTR PIC 9999 VALUE 0.
10 W02-B-CTR PIC 9999 VALUE 0.
10 W02-C-CTR PIC 9999 VALUE 0.
10 W02-D-CTR PIC 9999 VALUE 0.
10 W02-F-CTR PIC 9999 VALUE 0.
01 W03-REPT.
05 W03-HEADER-ROW1.
10 PIC X(9) VALUE SPACES.
10 PIC X(3) VALUE 'ABC'.
10 PIC X VALUE SPACES.
10 PIC X(7) VALUE 'COLLEGE'.
10 PIC X VALUE SPACES.
10 PIC X(7) VALUE 'TESTING'.
10 PIC X VALUE SPACES.
10 PIC X(6) VALUE 'CENTER'.
10 PIC X(85) VALUE SPACES.
05 W03-HEADER-ROW2.
10 PIC X(9) VALUE SPACES.
10 PIC X(4) VALUE 'TEST'.
10 PIC X VALUE SPACES.
10 PIC X(7) VALUE 'RESULTS'.
10 PIC X VALUE SPACES.
10 PIC X(7) VALUE 'SUMMARY'.
10 PIC X(11) VALUE SPACES.
10 PIC X(5) VALUE 'DATE:'.
10 PIC X VALUE SPACES.
10 W03-YEAR PIC 9999.
10 PIC X VALUE '/'.
10 W03-MONTH PIC 99.
10 PIC X VALUE '/'.
10 W03-DAY PIC 99.
10 PIC X(64) VALUE SPACES.
05 W03-HEADER-ROW3.
10 PIC X VALUE SPACES.
10 PIC X(7) VALUE 'SUBJECT'.
10 PIC X VALUE SPACES.
10 PIC X(4) VALUE 'NAME'.
10 PIC X(15) VALUE SPACES.
10 PIC X VALUE 'A'.
10 PIC X(7) VALUE SPACES.
10 PIC X VALUE 'B'.
10 PIC X(7) VALUE SPACES.
10 PIC X VALUE 'C'.
10 PIC X(7) VALUE SPACES.
10 PIC X VALUE 'D'.
10 PIC X(7) VALUE SPACES.
10 PIC X VALUE 'F'.
10 PIC X(59) VALUE SPACES.
05 W03-DETAIL-ROW.
10 PIC X VALUE SPACES.
10 W03-SUBJ-NAME PIC X(20).
10 PIC XXX VALUE SPACES.
10 W03-A-CTR PIC Z,ZZ9.
10 PIC XXX VALUE SPACES.
10 W03-B-CTR PIC Z,ZZ9.
10 PIC XXX VALUE SPACES.
10 W03-C-CTR PIC Z,ZZ9.
10 PIC XXX VALUE SPACES.
10 W03-D-CTR PIC Z,ZZ9.
10 PIC XXX VALUE SPACES.
10 W03-F-CTR PIC Z,ZZ9.
10 PIC X(59) VALUE SPACES.
01 W04-SYS-DATE.
05 W04-YEAR PIC 9999.
05 W04-MONTH PIC 99.
05 W04-DAY PIC 99.
01 W05-TOTALS.
05 W05-TOTAL-A PIC 99999 VALUE 0.
05 W05-TOTAL-B PIC 99999 VALUE 0.
05 W05-TOTAL-C PIC 99999 VALUE 0.
05 W05-TOTAL-D PIC 99999 VALUE 0.
05 W05-TOTAL-F PIC 99999 VALUE 0.
Here's procedure division
PROCEDURE DIVISION.
PERFORM A100-OPEN-FILES
PERFORM A200-WRITE-HEADINGS
PERFORM A300-PROCESS-SUBJECTS
PERFORM A400-PROCESS-MARKS
PERFORM A500-WRITE-TOTALS
PERFORM A600-CLOSE-FILES
STOP RUN
.
A100-OPEN-FILES.
* OPENS FILES
OPEN INPUT F01-SUBJ-FILE
F02-MARK-FILE
OPEN OUTPUT F03-REPT-FILE
.
A200-WRITE-HEADINGS.
* WRITES HEADERS TO THE REPORT FILE
MOVE W03-HEADER-ROW1 TO F03-REPT-RECORD
WRITE F03-REPT-RECORD
MOVE FUNCTION CURRENT-DATE (1:8) TO W04-SYS-DATE
MOVE W04-YEAR TO W03-YEAR
MOVE W04-MONTH TO W03-MONTH
MOVE W04-DAY TO W03-DAY
MOVE W03-HEADER-ROW2 TO F03-REPT-RECORD
WRITE F03-REPT-RECORD
MOVE W03-HEADER-ROW3 TO F03-REPT-RECORD
WRITE F03-REPT-RECORD
.
A300-PROCESS-SUBJECTS.
* MOVES SUBJECT NAMES AND CODES INTO W02-TEST-TABLE
PERFORM A310-READ-RECORD
PERFORM UNTIL W01-SUBJ-EOF = 'Y'
IF W02-SUBJ-COUNT < W02-SUBJ-MAX
ADD 1 TO W02-SUBJ-COUNT
SET W02-IDX TO W02-SUBJ-COUNT
MOVE F01-SUBJ-CODE TO W02-SUBJ-CODE(W02-IDX)
MOVE F01-SUBJ-NAME TO W02-SUBJ-NAME(W02-IDX)
ELSE
DISPLAY "ERROR - SUBJECT FILE EXCEEDS MAX OF "
W02-SUBJ-MAX " RECORDS, RECORD IGNORED"
END-IF
PERFORM A310-READ-RECORD
END-PERFORM
.
A310-READ-RECORD.
* READS FROM THE SUBJECT FILE INTO THE SUBJECT RECORD
READ F01-SUBJ-FILE
AT END MOVE 'Y' TO W01-SUBJ-EOF
END-READ
.
A400-PROCESS-MARKS.
PERFORM A410-READ-RECORD
PERFORM A420-COUNT-MARKS
UNTIL W01-MARK-EOF = 'Y'
.
A410-READ-RECORD.
* READS FROM THE MARK FILE INTO THE MARK RECORD
READ F02-MARK-FILE
AT END MOVE 'Y' TO W01-MARK-EOF
END-READ
.
A420-COUNT-MARKS.
* COUNTS GRADE TOTALS
SET W02-IDX TO 1
SEARCH ALL W02-TEST-ROW
AT END DISPLAY 'INVALID INPUT RECORD: ' F02-MARK-RECORD
WHEN W02-SUBJ-CODE(W02-IDX) = F02-SUBJ-CODE
EVALUATE F02-STUD-MARK
WHEN "80" THRU "100"
ADD 1 TO W05-TOTAL-A
ADD 1 TO W02-A-CTR(W02-IDX)
WHEN "70" THRU "79"
ADD 1 TO W05-TOTAL-B
ADD 1 TO W02-B-CTR(W02-IDX)
WHEN "60" THRU "69"
ADD 1 TO W05-TOTAL-C
ADD 1 TO W02-C-CTR(W02-IDX)
WHEN "50" THRU "59"
ADD 1 TO W05-TOTAL-D
ADD 1 TO W02-D-CTR(W02-IDX)
WHEN OTHER
ADD 1 TO W05-TOTAL-F
ADD 1 TO W02-F-CTR(W02-IDX)
END-EVALUATE
END-SEARCH
.
A500-WRITE-TOTALS.
PERFORM A510-WRITE-SUBJ-GRADE-TOTALS
PERFORM A520-WRITE-GRADE-GRAND-TOTALS
.
A510-WRITE-SUBJ-GRADE-TOTALS.
PERFORM VARYING W02-IDX FROM 1 BY 1
UNTIL W02-IDX > W02-SUBJ-COUNT
MOVE W02-SUBJ-NAME(W02-IDX) TO W03-SUBJ-NAME
MOVE W02-A-CTR(W02-IDX) TO W03-A-CTR
MOVE W02-B-CTR(W02-IDX) TO W03-B-CTR
MOVE W02-C-CTR(W02-IDX) TO W03-C-CTR
MOVE W02-D-CTR(W02-IDX) TO W03-D-CTR
MOVE W02-F-CTR(W02-IDX) TO W03-F-CTR
MOVE W03-DETAIL-ROW TO F03-REPT-RECORD
WRITE F03-REPT-RECORD
END-PERFORM
.
A520-WRITE-GRADE-GRAND-TOTALS.
* WRITES THE GRADE GRAND TOTALS TO THE REPORT FILE
* AFTER INSERTING A BLANK ROW
MOVE SPACES TO F03-REPT-RECORD
WRITE F03-REPT-RECORD
MOVE W05-TOTAL-A TO W03-TOTAL-A
MOVE W05-TOTAL-B TO W03-TOTAL-B
MOVE W05-TOTAL-C TO W03-TOTAL-C
MOVE W05-TOTAL-D TO W03-TOTAL-D
MOVE W05-TOTAL-F TO W03-TOTAL-F
MOVE W03-TOTAL-ROW TO F03-REPT-RECORD
WRITE F03-REPT-RECORD
.
A600-CLOSE-FILES.
* CLOSES THE FILES
CLOSE F01-SUBJ-FILE
F02-MARK-FILE
F03-REPT-FILE
.
I'm glad you figured it out, Tom.
I hope you're not turned off and will explore further. FYI, while ISPF, TSO/E, and other classic user interfaces still work (and some people still like them, and they'll continue to work "forever"), nowadays developers often use and prefer graphical user interfaces. There are some free ones, for example IBM Explorer for z/OS and its Remote System Explorer (RSE):
https://developer.ibm.com/mainframe/products/zosexplorer/
That works just fine on its own on a Mac or PC (Linux or Windows), as you prefer (with the RSE part on z/OS). All free. Or, if you wish, you can add a more "COBOL aware" editor (among several other features) if you add the IBM Z Open Development plug-ins:
https://developer.ibm.com/mainframe/products/ibm-z-open-development/
And that works too, free for 90 days. At the end of the 90 days you can either pay the going price to keep those plug-ins or uninstall them and just use the base/free Explorer for z/OS functions.
Maybe this'd be good feedback to your instructor/professor? Yes, your first experience with any programming language can be (for example) via emacs and a terminal emulator. Yes, you can write Apple Swift code (for example) with emacs, ISPF, or vi. However, these classic user interfaces aren't everybody's favorite firsts. Again, if you like a particular UI, and it works for you, no problem! But from a pedagogical perspective it's probably best to start with something more familiar to the audience.
On edit: As another example, if you happen to prefer Microsoft Visual Studio Code, then you can add IBM Z Open Editor free of charge to that IDE.
I figured out what was wrong with my program by placing a DISPLAY at the start of each function which output what function was running. I saw that it was in an infinite loop in A420-COUNT-MARKS and that I forgot to add a PERFORM A410-READ-RECORD at the end of it.

Search function error when retrieving data from table

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.

How do I move a PIC X field to a PIC S9 COMP-3 field in COBOL?

My situation is as follows.
I'm reading input from a file into the following working storage field:
WORKING-STORAGE SECTION.
01 WORK-FIELDS.
05 W1-INPUT.
10 TESTCASE-NUMBER PIC X(02).
10 PIC X(01).
10 TESTCASE-ID PIC X(18).
10 PIC X(01).
10 TESTCASE-CONTENT PIC X(20).
Depending on what the TESTCASE-ID contains, I have to eventually move the content of the TESTCASE-CONTENT field into either the AMOUNT-DECIMAL-FORMAT or the AMOUNT-DECIMAL-NUMBER field in the following copybook:
05 (*)AMOUNT.
10 AMOUNT-DECIMAL-FORMAT PIC S9(18) COMP-3.
10 AMOUNT-DECIMAL-NUMBER PIC S9(01) COMP-3.
10 AMOUNT-IN-XML-FORMAT PIC N(20).
I then have to do a call to another program which will process these parameters and fill the AMOUNT-IN-XML-FORMAT field.
Anyway, so my question is: What's the best way to move the content of my PIC X field into my S9 COMP-3 field?
Thanks in advance for your time!

Resources