So I'm trying to make a program in OpenCobolIDE that uses the SCREEN SECTION feature in COBOL to create a menu where the user chooses whether he wants to input data or display it.
This data is being recorded in a sequential .txt file. The writing process works fine so I don't add the code of this part here. The problem is in the reading process. I wanted the program to display multiple times the DISPLAY-SCREEN in a PERFORM loop showing all the records in my file but this is not working. I thought that by removing the BLANK SCREEN from my DISPLAY-SCREEN it would work the way I wanted but all that happens is that the program shows the DISPLAY-SCREEN a single time and it doesn't even display any records. What could be the problem? Here is the code:
IDENTIFICATION DIVISION.
PROGRAM-ID.PGM001.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT MYFILE ASSIGN TO "DATA.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD MYFILE.
01 FS-TB.
02 FS-ID PIC X(03).
02 FS-NAME PIC A(15).
02 FS-PHONE PIC X(09).
WORKING-STORAGE SECTION.
01 WS-TB.
02 WS-ID PIC X(03).
02 WS-NAME PIC A(15).
02 WS-PHONE PIC X(09).
01 WS-EOF PIC A(01) VALUE "N".
01 WS-COUNT PIC 9(01) VALUE ZERO.
01 WS-OP PIC 9(01).
SCREEN SECTION.
01 MENU-SCREEN.
02 BLANK SCREEN.
02 LINE 1 COL 1 VALUE "------------------------------------".
02 LINE 2 COL 1 VALUE "- MENU -".
02 LINE 3 COL 1 VALUE "------------------------------------".
02 LINE 4 COL 1 VALUE "- (1).REGISTER -".
02 LINE 5 COL 1 VALUE "- (2).DISPLAY -".
02 LINE 6 COL 1 VALUE "- (3).EXIT -".
02 LINE 7 COL 1 VALUE "- -".
02 LINE 8 COL 1 VALUE " OPTION:( ) -".
02 LINE 9 COL 1 VALUE "------------------------------------".
02 LINE 8 COL 20 PIC 9(01) TO WS-OP.
01 DISPLAY-SCREEN.
02 LINE 1 COL 1 VALUE "------------------------------------".
02 LINE 2 COL 1 VALUE "- DISPLAY -".
02 LINE 3 COL 1 VALUE "------------------------------------".
02 LINE 4 COL 1 VALUE "-(1).ID : -".
02 LINE 4 COL 18 PIC X(03) FROM WS-ID.
02 LINE 5 COL 1 VALUE "-(2).NAME : -".
02 LINE 5 COL 18 PIC A(15) FROM WS-NAME.
02 LINE 6 COL 1 VALUE "-(3).PHONE : -".
02 LINE 6 COL 18 PIC X(09) FROM WS-PHONE.
02 LINE 7 COL 1 VALUE "------------------------------------".
PROCEDURE DIVISION.
A-100.
DISPLAY MENU-SCREEN.
ACCEPT MENU-SCREEN.
EVALUATE WS-OP
WHEN 1
GO TO A-200
WHEN 2
GO TO A-300
WHEN 3
STOP RUN
WHEN OTHER
GO TO A-100
END-EVALUATE.
A-200.
A-300.
OPEN INPUT MYFILE
PERFORM UNTIL WS-EOF = "Y"
READ MYFILE INTO WS-TB
AT END MOVE "Y" TO WS-EOF
NOT AT END DISPLAY DISPLAY-SCREEN
END-READ
END-PERFORM
CLOSE MYFILE.
STOP RUN.
END PROGRAM PGM001.
As Bill pointed out already: The PERFORM and DISPLAY is too fast.
To see every record you´d need to add an ACCEPT after the DISPLAY, I guess ACCEPT OMITTED will work, if not add a dummy var and ACCEPT this.
You seem to not want to stop the program during the PERFORM then you may add an ACCEPT DUMMY at the program's end (always useful if you use extended DISPLAY/ACCEPT). But you would only get the last item displayed.
Depending on your needs a CALL 'CBL_OC_NANOSLEEP' USING 500000000 (wait one-half second) or CALL 'C$SLEEP' USING 1 after the DISPLAY DISPLAY-SCREEN may be the result you want.
But likely the best option would be ACCEPT dummy WITH TIMEOUT time (if you press ENTER it goes directly to the next DISPLAY if you don't it will wait the specified time before doing the next DISPLAY.
Related
Aside from the specific platform and the compiler, suppose you have this defined in a COBOL program using Report Writer Module:
01 CF-MM TYPE CONTROL FOOTING WS-MM.
02 LINE PLUS 1.
03 COLUMN 1 VALUE "* CF MONTH: ".
03 COLUMN PLUS 1 PIC 99 SOURCE WS-MM.
03 S-MM COLUMN PLUS 5 PIC S9(4)V99 SUM WS-TUTION-PAY.
03 VAL-NN COLUMN PLUS 5 PIC S9(4)V99 SOURCE S-MM.
<...>
PROCEDURE DIVISION.
DECLARATIVES.
SEC2 SECTION.
USE BEFORE REPORTING
CF-MM.
DISPLAY "SUM MM LEVEL:" S-MM
.
Furthermore, suppose that the program reported 3 lines where SUM WS-TUTION-PAY resulted in 126.
What would be the value resulting from the statement in SEC2 SECTION that displays S-MM value? I guess it should be 126 but I am getting ZERO displayed. This maybe because the value 126 was not yet moved to S-MM, but I am not sure.
What is the value that "should" be displayed in the declaratives section for S-MM
Q: Could you reference a column in DECLARATIVES section when the column is used with SUM clause in COBOL REPORT WRITER Module?
03 S-MM COLUMN PLUS 5 PIC S9(4)V99 SUM WS-TUTION-PAY.
S-MM is a data-name format of the entry-name clause. Quoting from the 2002 COBOL standard, Report group description entry, 13.13.2 Syntax rules:
7) The data-name format of the entry-name clause shall be specified when the data-name is referenced in a GENERATE statement, a USE BEFORE REPORTING statement, as a qualifier for a SUM counter, in the UPON phrase of the SUM clause, or as an operand in a SUM clause. The data-name shall not be referenced in any other way.
Given that S-MM qualifies, it may be referenced "as a qualifier for a SUM counter".
[The COBOL 74 and 85 standards stated, "Data-name-1 is optional but may be specified in any entry. Data-name-1, however, may be referenced only if the entry defines a sum counter."]
The compiler I used for the following code is Micro Focus COBOL 85.
Code:
program-id. rw-test.
environment division.
input-output section.
select report-file assign "rpt.txt"
organization line sequential.
data division.
fd report-file
report is report-1.
working-storage section.
01 n comp pic 99 value 0.
01 test-table.
02 test-data.
03 pic 9999 value 1001.
03 pic 9999 value 1002.
03 pic 9999 value 1003.
03 pic 9999 value 2004.
03 pic 9999 value 2005.
03 pic 9999 value 2006.
02 test-entry redefines test-data pic 9999 occurs 6.
01 report-entry.
03 test-group pic 9.
03 test-value pic 999.
report section.
rd report-1
control is test-group.
01 rw-detail type de.
02 line plus 1.
03 grp column 1 pic 9 source test-group.
03 val column 4 pic zz9 source test-value.
01 rw-foot type cf test-group.
02 line plus 1.
03 column 1 pic x(6) value "- ---".
02 line plus 1.
03 column 1 pic 9 source test-group.
03 s-mm column 4 pic zz9 *> s.mm defined
sum test-value
reset test-group.
02 line plus 1 pic x value space.
procedure division.
declaratives.
decl-rpt section.
use before reporting rw-foot.
display s-mm. *> s.mm referenced
end declaratives.
main-line section.
open output report-file.
initiate report-1
perform varying n from 1 by 1
until n > 6
move test-entry (n) to report-entry
generate rw-detail
end-perform
terminate report-1
close report-file
stop run.
end program rw-test.
Report:
1 1
1 2
1 3
- ---
1 6
2 4
2 5
2 6
- ---
2 15
Display:
006
015
Another COBOL question here again. I have been playing around with COBOL and the problem is, I have to input a decimal value in the input file. So the output in the input file should look something like this:
2019-00042Alexander Bell 1.501.752.25
...
The numbers are grades in a quiz. 1.00 to 5.00.
So I'm assuming in the print line, which is named as INF-PRINT-LINE in my code, I have to declare it as:
01 INF-PRINT-LINE.
02 SNO-IN PIC X(10).
02 SNAME-IN PIC X(25).
02 Q1-IN PIC 9.9(2).
02 Q2-IN PIC 9.9(2).
02 Q3-IN PIC 9.9(2).
Now on the WORKING-STORAGE SECTION I have declared three separate variables (STUD-QX-IN) so that I'll move it later on to the INF-PRINT-LINE variables (QX-IN) which can be seen here:
01 STUD-Q1-IN PIC 999.
01 STUD-Q2-IN PIC 999.
01 STUD-Q3-IN PIC 999.
Now, when this program is executed, I'd get a chance to see what's the value of STUD-QX-IN and QX-IN because of the DISPLAY line that will be shown on Column 45 so the program should look now something like this in the command line:
ENTER STUDENT NUMBER: 2019-00042
ENTER STUDENT NAME: Alexander Bell
ENTER QUIZ 1: 150 150 0.00
ENTER QUIZ 2: 175 175 5.00
ENTER QUIZ 3: 225 225 5.00
ENTER ANOTHER STUDENT(Y/N)
Now as you can see, what has passed down into the QX-IN variable is just the last digit of STUD-QX-IN, and the input file now would like something like this instead of what I was thinking about:
2019-00042Alexander Bell 0.005.005.00
...
What should I declare on the STUD-QX-IN so that I can pass down the correct value to QX-IN? I did try PIC 9V99 on STUD-QX-IN but it also doesn't work. Is the QX-IN PIC clause value were wrong after all?
Here's the full code:
* -----------------------------
IDENTIFICATION DIVISION.
PROGRAM-ID. exercise.
* -----------------------------
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
* INPUT
* OUTPUT
SELECT INF-STUD-GRADES ASSIGN TO "STUDENTGRADES.DAT".
DATA DIVISION.
FILE SECTION.
FD INF-STUD-GRADES.
01 INF-PRINT-REC PIC X(80).
WORKING-STORAGE SECTION.
*> INPUT THE ANSWER IN THIS SECTION
01 INF-PRINT-LINE.
02 SNO-IN PIC X(10).
02 SNAME-IN PIC X(25).
02 Q1-IN PIC 9.9(2).
02 Q2-IN PIC 9.9(2).
02 Q3-IN PIC 9.9(2).
01 ANS PIC X VALUE 'Y'.
01 L PIC 9.
01 STUD-NO-IN PIC X(10).
01 STUD-NAME-IN PIC X(25).
01 STUD-Q1-IN PIC 999.
01 STUD-Q2-IN PIC 999.
01 STUD-Q3-IN PIC 999.
SCREEN SECTION.
01 BSCRN.
02 BLANK SCREEN.
PROCEDURE DIVISION.
OPEN OUTPUT INF-STUD-GRADES.
PERFORM INPUT-GRADES-RTN UNTIL ANS = 'N' OR ANS = 'n'.
PERFORM CLOSE-INPUT-GRADES-RTN.
PERFORM FINAL-CLOSE-RTN.
INPUT-GRADES-RTN.
DISPLAY BSCRN.
MOVE 4 TO L.
DISPLAY "ENTER STUDENT NUMBER: " LINE L COLUMN 5.
ACCEPT STUD-NO-IN LINE L COLUMN 35.
MOVE STUD-NO-IN TO SNO-IN.
ADD 1 TO L.
DISPLAY "ENTER STUDENT NAME: " LINE L COLUMN 5.
ACCEPT STUD-NAME-IN LINE L COLUMN 35.
MOVE STUD-NAME-IN TO SNAME-IN.
ADD 1 TO L.
DISPLAY "ENTER QUIZ 1: " LINE L COLUMN 5.
ACCEPT STUD-Q1-IN LINE L COLUMN 35.
DISPLAY STUD-Q1-IN LINE L COLUMN 45.
MOVE STUD-Q1-IN TO Q1-IN.
DISPLAY Q1-IN LINE L COLUMN 55.
ADD 1 TO L.
DISPLAY "ENTER QUIZ 2: " LINE L COLUMN 5.
ACCEPT STUD-Q2-IN LINE L COLUMN 35.
DISPLAY STUD-Q2-IN LINE L COLUMN 45.
MOVE STUD-Q2-IN TO Q2-IN.
DISPLAY Q2-IN LINE L COLUMN 55.
ADD 1 TO L.
DISPLAY "ENTER QUIZ 3: " LINE L COLUMN 5.
ACCEPT STUD-Q3-IN LINE L COLUMN 35.
DISPLAY STUD-Q3-IN LINE L COLUMN 45.
MOVE STUD-Q3-IN TO Q3-IN.
DISPLAY Q3-IN LINE L COLUMN 55.
ADD 2 TO L.
WRITE INF-PRINT-REC FROM INF-PRINT-LINE BEFORE 1 LINE.
DISPLAY "ENTER ANOTHER STUDENT(Y/N)" LINE L COLUMN 30.
ACCEPT ANS.
CLOSE-INPUT-GRADES-RTN.
CLOSE INF-STUD-GRADES.
FINAL-CLOSE-RTN.
STOP RUN.
You need to move fields defined as 9v99 to the output fields. The v means assumed decimal place.
What you can do is
01 work fields
03 STUD-Q1-IN PIC 999.
03 STUD-Q1-IN-V redefines STUD-Q1-IN PIC 9v99.
03 STUD-Q2-IN PIC 999.
03 STUD-Q2-IN-V redefines STUD-Q2-IN PIC 9v99.
03 STUD-Q3-IN PIC 999.
03 STUD-Q3-IN-V redefines STUD-Q3-IN PIC 9v99.
You would then do
MOVE STUD-Q1-IN-V TO Q1-IN.
You could also do
compute Q1-IN = STUD-Q1-IN / 100
end-compute
Redefines keyword
The Redefines keyword lets you give a different definition to a field
So if you do
Move 123 to STUD-Q1-IN.
Then
STUD-Q1-IN = 123
STUD-Q1-IN-V = 1.23
OK so I'm doing assignment but then I found that I was asked to add page numbers and change pages for each 4 records. Since it's an online course and I don't think there is anything about page numbers in lecture videos. So the main problems are
To add a heading that contains date and page number,
Print 4 records per page, which means page needs to be changed after printing 4 records.
I really have no idea how to do this.
Here is the code I have finished:
ENVIRONMENT DIVISION.
FILE-CONTROL. SELECT STOCK-IN ASSIGN TO 'F:/CS201S13/PROJECT2.TXT'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT STOCK-OUT ASSIGN TO 'F:/CS201S13/PROJECT2OUTPUT.TXT'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD STOCK-IN.
01 STOCK-RECORD.
05 ST-TRANSACTION-INFORMATION.
10 ST-TRANSACTION-SHARES PIC 9(3).
10 ST-TRANSACTION-STOCK PIC X(14).
05 ST-PURCHASE-INFORMATION.
10 ST-PURCHASE-PRICE PIC 9(5)V99.
10 ST-PURCHASE-DATE.
15 ST-PURCHASE-YEAR PIC 99.
15 ST-PURCHASE-MONTH PIC 99.
15 ST-PURCHASE-DAY PIC 99.
05 ST-SALE-INFORMATION.
10 ST-SALE-PRICE PIC 9(5)V99.
10 ST-SALE-DATE.
15 ST-SALE-YEAR PIC 99.
15 ST-SALE-MONTH PIC 99.
15 ST-SALE-DAY PIC 99.
FD STOCK-OUT.
01 STOCK-RECORD-OUT.
05 ST-TRANSACTION-INFORMATION-OUT.
10 ST-TRANSACTION-SHARES-OUT PIC 9(3).
10 ST-TRANSACTION-STOCK-OUT PIC X(14).
05 TOTAL-PURCHASE PIC 9(8)V99.
05 PIC X(4).
05 TOTAL-SALE PIC 9(8)V99.
05 PIC X(4).
05 TOTAL-PROFIT PIC 9(8)V99.
05 PIC X(4).
05 ST-PURCHASE-DATE-OUT.
10 ST-PURCHASE-YEAR-OUT PIC 99.
10 PIC X VALUE '/'.
10 ST-PURCHASE-MONTH-OUT PIC 99.
10 PIC X VALUE '/'.
10 ST-PURCHASE-DAY-OUT PIC 99.
05 PIC X(4).
05 ST-SALE-DATE-OUT.
10 ST-SALE-YEAR-OUT PIC 99.
10 PIC X VALUE '/'.
10 ST-SALE-MONTH-OUT PIC 99.
10 PIC X VALUE '/'.
10 ST-SALE-DAY-OUT PIC 99.
05 PIC X(4).
05 RECORD-OUT PIC 9 VALUE 0.
05 PAGE-OUT PIC 9.
WORKING-STORAGE SECTION.
01 ARE-THERE-MORE-RECORDS PIC XXX VALUE 'YES'.
01 IS-THIS-PAGE-FULL PIC XXX VALUE 'NO '.
PROCEDURE DIVISION.
100-MAIN-PROCESS.
OPEN INPUT STOCK-IN
OUTPUT STOCK-OUT
MOVE ST-TRANSACTION-INFORMATION TO ST-TRANSACTION-INFORMATION-OUT
PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO '
READ STOCK-IN
AT END
MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 200-PROCEDURE-RTN
ADD 1 TO RECORD-OUT
END-READ
END-PERFORM
CLOSE STOCK-IN
STOCK-OUT
STOP RUN.
200-PROCEDURE-RTN.
IF RECORD-OUT = 4
MOVE 'YES' TO IS-THIS-PAGE-FULL
MOVE 0 TO RECORD-OUT
MOVE 'NO ' TO IS-THIS-PAGE-FULL
ADD 1 TO PAGE-OUT
END-IF
MULTIPLY ST-PURCHASE-PRICE BY ST-TRANSACTION-SHARES GIVING TOTAL-PURCHASE
MULTIPLY ST-SALE-PRICE BY ST-TRANSACTION-SHARES GIVING TOTAL-SALE
SUBTRACT TOTAL-PURCHASE FROM TOTAL-SALE GIVING TOTAL-PROFIT
WRITE STOCK-RECORD-OUT.
You are both close, and far away.
"Close" because you need a little bit of code in between setting IS-THIS-PAGE-FULL to YES and NO.
"Far away" as you have quite a lot to do rather than just "patch up" what you have.
Is the program writing an output file (STOCK-OUT) and a report, or is STOCK-OUT the report? If it is a report, change the names so that it is clear that it is a report, not an output file.
Don't worry if this seems a lot. You should be learning how to Program in Cobol, as well as learning Cobol. Doesn't happen overnight.
In no particular order:
Include FILE-STATUS checking for all IO operations on all files, always. At the moment, if your input fails to open and the system does not fail the program (even if yours does, you are presumably learning Cobol to be able to work with any system, not just the one you have) then no records will be read, your "end of file test" will never be YES and you'll have a BFL (Big Fat Loop). With the FILE-STATUS checking, produce useful messages, including key/reference/record number as appropriate for failed READ or WRITE.
You may feel that this is a lot of work. However, put together some "template" files with all the stuff in, and then paste (or even COPY) those into your program each time.
You have VALUE clause in the FD. These will not do what you think.
You have single digit for your page count, which is unlikely to have general application.
Why use YES and NO as literals? Look at the SET verb, in relation to "condition names", use 88's for tests and "flags/switches".
You have "MOVE ST-TRANSACTION-INFORMATION" after the input is opened but before a record is read, and only have one reference to it in the program. This is not going to work.
For reading files, have a look at the "priming read" approach.
read input
loop until end-of-file (88 on file-status)
process data
read input
end-loop
This avoids the AT END/NOT AT END, allows processing of headers (if present) and "empty files" without clogging-up the main logic. The code "expands" with headers/trailers (including the correct number of them), sequence-checking of keys, etc, but you only need to code it once then "template" it.
According to your VALUE clauses in your FD, you expect RECORD-OUT to be zero, so the test for 4 will actually get you five on the first page, and four thereafter.
You always assume there will be a "profit" (a positive amount), which is not realistic, yet you don't allow a signed value for the "profit".
Now, for the report.
For your report FD, just make it a simple thing, length of your print line.
In WORKING-STORAGE, define data for the headings and titles that you need. Define data for a print line. Since you're in the WORKING-STORAGE, put VALUEs for everything which will not have data MOVEd to it in the PROCEDURE DIVISION.
When you have written four items (or when your program tells you this) and you have a fifth, write the headings and titles, remembering to update the page number.
I say "or when your program tells you this" because you can set your original value of "records written" to 4. Comment it, so that it is clear that it is what you want, and why you want it. The reason is, you don't have to then deal with "first time" headings and othe things. For first time, or on a "contol break" (I guess you'll get to those soon) set the " done on a page already" to the maximum for a page, and the headings will pop out when you want.
Format the print line. PERFORM a para to print it (which is where the "page full" test will be).
Note: You can use VALUEs for your "/"s in the dates, or you can use the "/" editing character in the PICture, like this:
05 an-input-date PIC X(8) (can be other definitions).
...
05 date-to-print PIC X(4)/XX/XX.
...
MOVE an-input-date TO date-to-print
I like to see that you are using "minimal full-stops/periods". You can go a little further.
MOVE an-input-date TO date-to-print
.
Then you get your final full-stop/period in a paragraph, without having it "attached" to any particular line of code, which makes "tossing code around" easier, as you don't have to think "do I need/not need that full-stop/period there".
You could also look through some of the Cobol questions here, and get a handle on some general tips and advice.
This may or may not help, if LINAGE is not supported you'll have to do some explicit counting.
*****************************************************************
* Example of LINAGE File Descriptor
* Author: Brian Tiffin
* Date: 10-July-2008
* Tectonics: $ cobc -x linage.cob
* $ ./linage <filename ["linage.cob"]>
* $ cat -n mini-report
*****************************************************************
IDENTIFICATION DIVISION.
PROGRAM-ID. linage-demo.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
select optional data-file assign to file-name
organization is line sequential
file status is data-file-status.
select mini-report assign to "mini-report".
DATA DIVISION.
FILE SECTION.
FD data-file.
01 data-record.
88 endofdata value high-values.
02 data-line pic x(80).
FD mini-report
linage is 16 lines
with footing at 15
lines at top 2
lines at bottom 2.
01 report-line pic x(80).
WORKING-STORAGE SECTION.
01 command-arguments pic x(1024).
01 file-name pic x(160).
01 data-file-status pic 99.
01 lc pic 99.
01 report-line-blank.
02 filler pic x(18) value all "*".
02 filler pic x(05) value spaces.
02 filler pic x(34)
VALUE "THIS PAGE INTENTIONALLY LEFT BLANK".
02 filler pic x(05) value spaces.
02 filler pic x(18) value all "*".
01 report-line-data.
02 body-tag pic 9(6).
02 line-3 pic x(74).
01 report-line-header.
02 filler pic x(6) VALUE "PAGE: ".
02 page-no pic 9999.
02 filler pic x(24).
02 filler pic x(5) VALUE " LC: ".
02 header-tag pic 9(6).
02 filler pic x(23).
02 filler pic x(6) VALUE "DATE: ".
02 page-date pic x(6).
01 page-count pic 9999.
PROCEDURE DIVISION.
accept command-arguments from command-line end-accept.
string
command-arguments delimited by space
into file-name
end-string.
if file-name equal spaces
move "linage.cob" to file-name
end-if.
open input data-file.
read data-file
at end
display
"File: " function trim(file-name)
" open error or empty"
end-display
go to early-exit
end-read.
open output mini-report.
write report-line
from report-line-blank
end-write.
move 1 to page-count.
accept page-date from date end-accept.
move page-count to page-no.
write report-line
from report-line-header
after advancing page
end-write.
perform readwrite-loop until endofdata.
display
"Normal termination, file name: "
function trim(file-name)
" ending status: "
data-file-status
end-display.
close mini-report.
* Goto considered harmful? Bah! :)
early-exit.
close data-file.
exit program.
stop run.
****************************************************************
readwrite-loop.
move data-record to report-line-data
move linage-counter to body-tag
write report-line from report-line-data
end-of-page
add 1 to page-count end-add
move page-count to page-no
move linage-counter to header-tag
write report-line from report-line-header
after advancing page
end-write
end-write
read data-file
at end set endofdata to true
end-read
.
*****************************************************************
* Commentary
* LINAGE is set at a 20 line logical page
* 16 body lines
* 2 top lines
* A footer line at 15 (inside the body count)
* 2 bottom lines
* Build with:
* $ cobc -x -Wall -Wtruncate linage.cob
* Evaluate with:
* $ ./linage
* This will read in linage.cob and produce a useless mini-report
* $ cat -n mini-report
*****************************************************************
END PROGRAM linage-demo.
Hi i need some help on this i cannot save if the user will input only 2 items and not more than 5 items.i can only save 5 items but when i input only 3 items i could not save i get run time error.maybe i have problem in looping.Thank you in advance
I am using mscobol 2.20
here is my code i put it back the file status
IDENTIFICATION DIVISION.
PROGRAM-ID. SOENTRY.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SYSTEM-FILE
ASSIGN TO DISK
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS SYS-FY
FILE STATUS IS SYSTEM-STATUS.
SELECT CUSTOMER-FILE
ASSIGN TO DISK
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS CUSNO
FILE STATUS IS CUSTOMER-STATUS.
SELECT ITEM-FILE
ASSIGN TO DISK
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS ITMNO
FILE STATUS IS ITEM-STATUS.
SELECT SO-FILE
ASSIGN TO DISK
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS SONO
FILE STATUS IS SO-STATUS.
SELECT SOD-FILE
ASSIGN TO DISK
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS SODKEY
FILE STATUS IS SOD-STATUS.
DATA DIVISION.
FILE SECTION.
FD SYSTEM-FILE LABEL RECORD IS STANDARD
VALUE OF FILE-ID IS "SYSTEM.DAT".
01 SYSTEM-RECORD.
03 SYS-FY PIC 9(4).
03 SYS-CONAME PIC X(50).
03 SYS-COADDR PIC X(50).
03 SYS-USER PIC 9(10).
03 SYS-PWORD PIC 9(10).
03 SYS-LASTCUSNO PIC 9(5).
03 SYS-LASTITMNO PIC 9(5).
03 SYS-LASTSONO PIC 9(7).
03 SYS-LASTSINO PIC 9(7).
03 SYS-LASTORNO PIC 9(7).
03 SYS-RECSTAT PIC A.
FD CUSTOMER-FILE LABEL RECORD IS STANDARD
VALUE OF FILE-ID IS "CUSTOMER.DAT".
01 CUSTOMER-RECORD.
03 CUSNO PIC 9(5).
03 CUSNAME PIC X(40).
03 CUSADDR PIC X(40).
03 CUSCONTACTPERSON PIC X(40).
03 CUSCONTACTNO PIC 9(18).
03 CUSCREDITLIMIT PIC 9(7)V99.
03 CUSBALANCE PIC S9(7)V99.
03 CUSLASTSONO PIC 9(7).
03 CUSLASTSINO PIC 9(7).
03 CUSLASTORNO PIC 9(7).
03 CUSRECSTAT PIC A.
FD ITEM-FILE LABEL RECORD IS STANDARD
VALUE OF FILE-ID IS "ITEM.DAT".
01 ITEM-RECORD.
03 ITMNO PIC 9(5).
03 ITMDESC PIC X(40).
03 ITMUM PIC X(3).
03 ITMPRICE PIC S9(6)V99.
03 ITMQTYONHAND PIC 9(4).
03 ITMQTYONORDER PIC 9(4).
03 ITMLASTONO PIC 9(7).
03 ITMLASTSINO PIC 9(7).
03 ITMRECSTAT PIC X.
FD SO-FILE LABEL RECORD IS STANDARD
VALUE OF FILE-ID IS "SO.DAT".
01 SO-RECORD.
03 SONO PIC 9(7).
03 SODATE PIC 9(8).
03 SOCUSNO PIC 9(5).
03 SOPAYMODE PIC XX.
03 SOTOTAL PIC 9(7)V99.
03 SOPREPBY PIC X(30).
03 SOAPPRBY PIC X(30).
03 SORECSTAT PIC X.
FD SOD-FILE LABEL RECORD IS STANDARD
VALUE OF FILE-ID IS "SOD.DAT".
01 SOD-RECORD.
03 SODKEY.
05 SODSONO PIC 9(7).
05 SODITMNO PIC 9(5).
03 SODQTYORD PIC 9(4).
03 SODQTYINV PIC 9(4).
03 SODUPRICE PIC 9(6)V99.
03 SODAMOUNT PIC 9(6)V99.
03 SODRECSTAT PIC X.
WORKING-STORAGE SECTION.
01 ESC-CODE PIC 99 VALUE 0.
88 ESC-KEY VALUE 1.
88 F2 VALUE 3.
88 F10 VALUE 11.
01 ERRMSG PIC X(75) VALUE SPACES.
01 ERR PIC 9 VALUE 0.
01 TEMP-VAR VALUE ZEROES.
03 VAR-ITMNO PIC 9(5) OCCURS 5 TIMES.
03 VAR-ITMPRICE PIC 9(6) OCCURS 5 TIMES.
03 VAR-ITMQTYONORDER PIC 9(4) OCCURS 5 TIMES.
03 VAR-SODITMQTYORDER PIC 9(4) OCCURS 5 TIMES.
03 VAR-AMOUNT PIC 9(6) OCCURS 5 TIMES.
01 TEMP-STR VALUE SPACES.
03 VAR-ITMDESC PIC X(40) OCCURS 5 TIMES.
03 VAR-ITMUM PIC X(3) OCCURS 5 TIMES.
01 QTYORD PIC 9(4).
01 ROW PIC 9.
01 R PIC 9.
01 EDIT-PRICE.
03 E-PRICE PIC ZZZ,ZZ9.99.
01 MY-DATE.
03 MY-YEAR PIC 9(4).
03 MY-MONTH PIC 9(2).
03 MY-DAY PIC 9(2).
01 AMOUNT PIC 9(6)V99.
01 TOTAL-AMOUNT PIC 9(7)V99.
01 CUSTOMER.
03 VAR-CRDLIMIT PIC Z,ZZZ,ZZ9.99.
03 VAR-BALANCE PIC Z,ZZZ,ZZ9.99.
01 EDIT-AMOUNT.
03 E-AMOUNT PIC ZZZ,ZZ9.99.
03 E-TOTAL PIC Z,ZZZ,ZZ9.99.
01 MOD PIC XX.
01 FLAG PIC 9.
01 LBL.
03 LBLSONO PIC 9(7).
01 APP-PREV.
03 PREPBY PIC X(30).
03 APPBY PIC X(30).
01 VAR-ITEM.
03 VAR-QTYONHAND PIC 9(4).
03 TOTAL-QTYONORDER PIC 9(4).
01 CHECK-STATUS.
03 SYSTEM-STATUS PIC XX.
03 CUSTOMER-STATUS PIC XX.
03 ITEM-STATUS PIC XX.
03 SO-STATUS PIC XX.
03 SOD-STATUS PIC XX.
SCREEN SECTION.
01 HEADER.
03 BLANK SCREEN BACKGROUND-COLOR 0.
01 ENTRY-FORM.
03 LINE 1 COLUMN 31 PIC X(50)
FROM SYS-CONAME HIGHLIGHT.
03 LINE 3 COLUMN 55 VALUE "SO NO :".
03 LINE 4 COLUMN 55 VALUE "SO DATE:".
03 LINE 4 COLUMN 68 VALUE "/".
03 LINE 4 COLUMN 73 VALUE "/".
03 LINE 4 COLUMN 2 VALUE "CUSTOMER N0:".
03 LINE 4 COLUMN 15 PIC 9(5) USING CUSNO.
03 LINE 6 COLUMN 2 VALUE "NAME :".
03 LINE 7 COLUMN 2 VALUE "ADDRESS :".
03 LINE 17 COLUMN 53 VALUE "TOTAL ======> ".
03 LINE 17 COLUMN 66 PIC Z,ZZZ,ZZ9.99
FROM TOTAL-AMOUNT.
03 LINE 19 COLUMN 2 "PREPARED BY: ".
03 LINE 19 COLUMN 14 PIC X(30) USING SOPREPBY.
03 LINE 20 COLUMN 2 "APPROVED BY: ".
03 LINE 20 COLUMN 14 PIC X(30) USING SOAPPRBY.
03 LINE 19 COLUMN 48 VALUE "CRDTLIMIT : ".
03 LINE 19 COLUMN 64 PIC Z,ZZZ,ZZ9.99
FROM VAR-CRDLIMIT.
03 LINE 20 COLUMN 48 VALUE "BALANCE : ".
03 LINE 20 COLUMN 64 PIC Z,ZZZ,ZZ9.99
FROM VAR-BALANCE.
03 LINE 21 COLUMN 48 VALUE "ITMQTYHAND : ".
03 LINE 21 COLUMN 64 PIC 9(4)
FROM ITMQTYONHAND.
03 LINE 6 COLUMN 55 VALUE "PAYMENT MODE:".
01 CLEAR-CUSNO.
03 LINE 4 COLUMN 15 VALUE "00000".
01 CUST-PRO.
03 LINE 6 COLUMN 15 PIC X(40)
FROM CUSNAME BACKGROUND-COLOR 0.
03 LINE 7 COLUMN 15 PIC X(40)
FROM CUSADDR BACKGROUND-COLOR 0.
01 ITEM-HEADER.
03 LINE 9 COLUMN 2 "ITEM NO" BACKGROUND-COLOR 9.
03 LINE 9 COLUMN 10 " " BACKGROUND-COLOR 9.
03 LINE 9 COLUMN 12 " DESCRPTION " BACKGROUND-COLOR 9.
03 LINE 9 COLUMN 30 " " BACKGROUND-COLOR 9.
03 LINE 9 COLUMN 41 " UOM " BACKGROUND-COLOR 9.
03 LINE 9 COLUMN 47 " QTY " BACKGROUND-COLOR 9.
03 LINE 9 COLUMN 53 " UNIT PRICE " BACKGROUND-COLOR 9.
03 LINE 9 COLUMN 67 " AMOUNT " BACKGROUND-COLOR 9.
01 FUNCTION-KEYS.
03 LINE 24 COLUMN 5 "Esc" HIGHLIGHT.
03 "=Exit ".
03 "F2" HIGHLIGHT.
03 "=Save ".
03 "F10" HIGHLIGHT.
03 "=Cancel".
01 ERROR-MESSAGE.
03 LINE 25 COLUMN 5 PIC X(70) FROM ERRMSG HIGHLIGHT.
01 CLEAR-SCREEN.
03 BLANK SCREEN BACKGROUND-COLOR 0.
PROCEDURE DIVISION.
MAIN.
OPEN I-O SYSTEM-FILE CUSTOMER-FILE ITEM-FILE
SO-FILE SOD-FILE.
IF SOD-STATUS not = '00'
DISPLAY "error" SOD-STATUS
STOP RUN.
IF SOD-STATUS = '05'
DISPLAY "error" SOD-STATUS
STOP RUN.
IF SO-STATUS = '00'
DISPLAY "error" SO-STATUS
STOP RUN.
IF SO-STATUS = '05'
DISPLAY "error" SO-STATUS
STOP RUN.
MOVE 2012 TO SYS-FY.
READ SYSTEM-FILE INVALID KEY MOVE 1 TO ERR.
IF ERR = 1
DISPLAY "SYSTEM RECORD NOT FOUND."
ELSE
PERFORM INITIALIZE-ITEMREC
DISPLAY HEADER
PERFORM ENTRY1 UNTIL ESC-KEY
DISPLAY CLEAR-SCREEN.
CLOSE SYSTEM-FILE CUSTOMER-FILE ITEM-FILE
SO-FILE SOD-FILE.
STOP RUN.
ENTRY1.
COMPUTE SONO = SYS-LASTSONO + 1.
MOVE SONO TO LBLSONO.
DISPLAY ENTRY-FORM ITEM-HEADER FUNCTION-KEYS ERROR-MESSAGE.
DISPLAY (3 , 65) LBLSONO.
MOVE 2012 TO MY-YEAR.
DISPLAY ( 4 , 74) MY-YEAR.
MOVE 1 TO FLAG.
PERFORM ENTER-MONTH UNTIL FLAG = 0 OR ESC-KEY
OR F2 OR F10.
MOVE 1 TO FLAG.
PERFORM ENTER-DAY UNTIL FLAG = 0 OR ESC-KEY
OR F2 OR F10.
MOVE 1 TO ERR.
PERFORM ENTER-CUSNO UNTIL ERR = 0 OR ESC-KEY
OR F2 OR F10.
DISPLAY CUST-PRO.
MOVE CUSCREDITLIMIT TO VAR-CRDLIMIT.
MOVE CUSBALANCE TO VAR-BALANCE.
DISPLAY(19 , 66) VAR-CRDLIMIT.
DISPLAY(20 , 66) VAR-BALANCE.
MOVE 1 TO ERR.
PERFORM ENTER-PREP UNTIL ERR = 0 OR ESC-KEY.
MOVE 1 TO ERR.
PERFORM ENTER-APP UNTIL ERR = 0 OR ESC-KEY.
MOVE 1 TO FLAG.
PERFORM CHCK-MOD UNTIL FLAG = 0 OR ESC-KEY.
PERFORM ITM-INPUT.
IF F2 PERFORM SAVE-ENTRIES
ELSE IF F10 PERFORM CANCEL-ENTRIES.
ENTER-MONTH.
ACCEPT(4 , 65)MY-MONTH.
ACCEPT ESC-CODE FROM ESCAPE KEY.
IF F2
PERFORM SAVE-ENTRIES
ELSE IF F10
PERFORM CANCEL-ENTRIES
ELSE IF MY-MONTH 12
MOVE "INVALID MONTH" TO ERRMSG
DISPLAY ERROR-MESSAGE
ELSE
MOVE SPACES TO ERRMSG
DISPLAY ERROR-MESSAGE
MOVE 0 TO FLAG.
ENTER-DAY.
ACCEPT(4 , 70)MY-DAY.
ACCEPT ESC-CODE FROM ESCAPE KEY.
IF F2
PERFORM SAVE-ENTRIES
ELSE IF F10
PERFORM CANCEL-ENTRIES
ELSE IF MY-DAY 31
MOVE "INVALID DAY" TO ERRMSG
DISPLAY ERROR-MESSAGE
ELSE
MOVE SPACES TO ERRMSG
DISPLAY ERROR-MESSAGE
MOVE 0 TO FLAG.
ENTER-CUSNO.
ACCEPT (4 , 15) CUSNO.
ACCEPT ESC-CODE FROM ESCAPE KEY.
IF F2
PERFORM SAVE-ENTRIES
ELSE IF F10
PERFORM CANCEL-ENTRIES
ELSE IF CUSNO = ZEROES
MOVE 1 TO ERR
ELSE
MOVE SPACES TO ERRMSG
PERFORM VALIDATE-CUSNO.
VALIDATE-CUSNO.
MOVE 0 TO ERR.
READ CUSTOMER-FILE INVALID KEY MOVE 1 TO ERR.
IF ERR = 1
MOVE "CUSTOMER NO. NOT FOUND" TO ERRMSG
MOVE 1 TO ERR
DISPLAY CLEAR-CUSNO
DISPLAY ERROR-MESSAGE
PERFORM CLEAN
ELSE
DISPLAY ERROR-MESSAGE.
CHCK-MOD.
ACCEPT (6 , 69) MOD.
ACCEPT ESC-CODE FROM ESCAPE KEY.
IF ESC-KEY
DISPLAY CLEAR-SCREEN
STOP RUN
IF F2 PERFORM SAVE-ENTRIES
ELSE IF F10 PERFORM CANCEL-ENTRIES.
IF MOD = "CA" OR "CR"
MOVE SPACES TO ERRMSG
DISPLAY ERROR-MESSAGE
MOVE 0 TO FLAG
ELSE
MOVE "INVALID INPUT." TO ERRMSG
DISPLAY ERROR-MESSAGE.
ENTER-PREP.
ACCEPT (19 , 14 ) SOPREPBY.
ACCEPT ESC-CODE FROM ESCAPE KEY.
IF ESC-KEY
DISPLAY CLEAR-SCREEN
STOP RUN
ELSE IF SOPREPBY = SPACES
MOVE 1 TO ERRMSG
MOVE "PLEASE FILL-IN" TO ERRMSG
DISPLAY ERROR-MESSAGE
ELSE
MOVE SPACES TO ERRMSG
DISPLAY ERROR-MESSAGE
MOVE 0 TO ERR.
ENTER-APP.
ACCEPT (20 , 14 ) SOAPPRBY.
ACCEPT ESC-CODE FROM ESCAPE KEY.
IF ESC-KEY
DISPLAY CLEAR-SCREEN
STOP RUN
ELSE IF SOAPPRBY = SPACES
MOVE 1 TO ERR
MOVE "PLEASE FILL-IN" TO ERRMSG
DISPLAY ERROR-MESSAGE
ELSE
MOVE SPACES TO ERRMSG
DISPLAY ERROR-MESSAGE
MOVE 0 TO ERR.
ITM-INPUT.
MOVE 10 TO LIN.
MOVE 0 TO TOTAL-AMOUNT.
MOVE 1 TO ROW.
PERFORM ITM-INPUT1 VARYING R FROM 1 BY 1 UNTIL R > 5.
ITM-INPUT1.
MOVE 1 TO ERR.
PERFORM ITM-INPUT2 UNTIL ERR = 0 OR F2 OR F10.
ITM-INPUT2.
ACCEPT (LIN, 4) ITMNO.
ACCEPT ESC-CODE FROM ESCAPE KEY.
IF ESC-KEY
DISPLAY CLEAR-SCREEN
STOP RUN
ELSE IF F2
PERFORM SAVE-ENTRIES
ELSE IF F10
PERFORM CANCEL-ENTRIES
ELSE
MOVE SPACES TO ERRMSG
PERFORM ITM-INPUT3.
ITM-INPUT3.
MOVE 0 TO ERR
READ ITEM-FILE INVALID KEY MOVE 1 TO ERR.
IF ERR = 1
MOVE "ITMNO NO. NOT FOUND." TO ERRMSG
DISPLAY ERROR-MESSAGE
ELSE
DISPLAY ERROR-MESSAGE
PERFORM ITM-INPUT4.
ITM-INPUT4.
DISPLAY (LIN , 10) ITMDESC
DISPLAY (LIN , 41) ITMUM
MOVE ITMPRICE TO E-PRICE
DISPLAY (LIN , 52) E-PRICE
DISPLAY (21 , 66 ) ITMQTYONHAND
PERFORM VALIDATE-ITMQTY.
VALIDATE-ITMQTY.
ACCEPT (LIN , 48)QTYORD.
MOVE QTYORD TO VAR-SODITMQTYORDER(R).
ACCEPT ESC-CODE FROM ESCAPE KEY.
IF ESC-KEY
DISPLAY CLEAR-SCREEN
STOP RUN
ELSE IF VAR-SODITMQTYORDER (R) > ITMQTYONHAND
MOVE "INSUFFICIENT STOCK" TO ERRMSG
DISPLAY ERROR-MESSAGE
ELSE
COMPUTE AMOUNT = VAR-SODITMQTYORDER (R) * ITMPRICE
MOVE AMOUNT TO E-AMOUNT
DISPLAY (LIN , 66)E-AMOUNT
ADD 1 TO LIN
MOVE ITMNO TO VAR-ITMNO(R)
* MOVE ITMQTYONORDER TO VAR-ITMQTYONORDER(R).
MOVE ITMDESC TO VAR-ITMDESC(R)
MOVE ITMUM TO VAR-ITMUM(ROW)
COMPUTE TOTAL-QTYONORDER = ITMQTYONORDER +
VAR-SODITMQTYORDER (ROW)
MOVE ITMPRICE TO VAR-ITMPRICE(R)
MOVE AMOUNT TO VAR-AMOUNT(R)
COMPUTE TOTAL-AMOUNT = TOTAL-AMOUNT + AMOUNT
MOVE TOTAL-AMOUNT TO E-TOTAL
DISPLAY (17 , 66) E-TOTAL
COMPUTE VAR-QTYONHAND = ITMQTYONHAND
- VAR-SODITMQTYORDER(R)
ADD 1 TO ROW.
SAVE-ENTRIES.
PERFORM SAVE-SOD VARYING R FROM 1 BY 1 UNTIL
R = ROW.
PERFORM SAVE-SO.
MOVE LBLSONO TO CUSLASTSONO.
REWRITE CUSTOMER-RECORD.
MOVE LBLSONO TO SYS-LASTSONO.
REWRITE SYSTEM-RECORD.
MOVE "ENTRIES RECORDED." TO ERRMSG.
DISPLAY ERROR-MESSAGE.
PERFORM INITIALIZE-ITEMREC.
SAVE-SOD.
MOVE LBLSONO TO SODSONO.
MOVE VAR-ITMNO(R) TO SODITMNO.
MOVE VAR-SODITMQTYORDER(R) TO SODQTYORD.
MOVE VAR-ITMPRICE(R) TO SODUPRICE.
MOVE VAR-AMOUNT(R) TO SODAMOUNT.
WRITE SOD-RECORD.
PERFORM SAVE-ITEM.
SAVE-ITEM.
MOVE VAR-ITMNO(R) TO SODITMNO.
READ ITEM-FILE.
MOVE VAR-QTYONHAND TO ITMQTYONHAND.
MOVE TOTAL-QTYONORDER TO ITMQTYONORDER.
MOVE LBLSONO TO ITMLASTONO.
REWRITE ITEM-RECORD.
SAVE-SO.
MOVE LBLSONO TO SONO.
MOVE MY-DATE TO SODATE.
MOVE CUSNO TO SOCUSNO.
MOVE TOTAL-AMOUNT TO SOTOTAL.
* MOVE PREPBY TO SOPREPBY.
* MOVE APPBY TO SOAPPRBY.
MOVE "O" TO SORECSTAT.
WRITE SO-RECORD.
CANCEL-ENTRIES.
MOVE "ENTRIES CANCELLED" TO ERRMSG.
PERFORM INITIALIZE-ITEMREC.
INITIALIZE-ITEMREC.
MOVE ZEROES TO CUSTOMER-RECORD.
MOVE ZEROES TO CUSNO ITMNO.
MOVE ZEROES TO CUSBALANCE CUSCREDITLIMIT.
MOVE ZEROES TO SODAMOUNT SODUPRICE.
MOVE ZEROES TO TOTAL-AMOUNT SORECSTAT.
MOVE 0 TO R.
MOVE SPACES TO TEMP-STR.
MOVE SPACES TO SOPREPBY SOAPPRBY.
MOVE "A" TO ITMRECSTAT.
MOVE 'O' TO SODRECSTAT.
MOVE SPACE TO SOPAYMODE MOD.
MOVE ZEROES TO SODQTYINV ITMQTYONHAND.
MOVE SPACES TO CUSNAME CUSADDR.
CLEAN.
MOVE SPACES TO CUSNAME.
MOVE SPACES TO CUSADDR.
I did not use when like your example because i don't know how to use it.it gives me an error,when compiling.By the way sir why is that if i have file status checking my program will not be runtime and it iwll write to the so.dat and sod.dat and my sono will be generated but if i will remove the file status my program will have input output error when inputing only 3 or less than 5 items.can you please enlighten my mind.Thank you in advance.
I would highly recommend tidying up your code using END-IF statements, as this would make the code a bit easier to understand and read. If you just rely on the full-stops then you run the risk of missing one out, which seems to be the case for the "STOP RUN" line in the "CHK-MOD" paragraph. While that may not be the problem with your file error.
Also, I would recommend you figure out how to use EVALUATE statements as these can make the code a lot more readable. Consider the following alternative to your ENTER-MONTH paragraph:
ENTER-MONTH.
ACCEPT(4 , 65)MY-MONTH.
ACCEPT ESC-CODE FROM ESCAPE KEY.
EVALUATE TRUE
WHEN F2
PERFORM SAVE-ENTRIES
WHEN F10
PERFORM CANCEL-ENTRIES
WHEN MY-MONTH > 12
MOVE "INVALID MONTH" TO ERRMSG
DISPLAY ERROR-MESSAGE
WHEN OTHER
MOVE SPACES TO ERRMSG
DISPLAY ERROR-MESSAGE
MOVE 0 TO FLAG
END-EVALUATE.
Your SAVE-ITEM paragraph is a bit of a mystery. The key for the ITEM-FILE is ITMNO, but you are moving the Item No into SODITMNO before the READ. Also, you are assuming that the ITEM-FILE record exists and always doing a REWRITE. What if the record doesn't exist?
Lastly, I'm not sure if this is significant, but you don't have a DECLARATIVES section defined. That's usually the way to trap I/O errors and carry on from them.
I would also put 88 Level values on your file statuses (ITEM-STATUS, SO-STATUS, SOD-STATUS, etc) so that you can test for those instead of the status values. For example, you might have an 88 level value for ITEM-NOT-FOUND under the ITEM-STATUS.
If you can, edit your source code with these readability improvements and we might be able to see your error better.
I want to acheive the below
a string of pic X(5) contains A1992 and is incremented to A9999 , after it reaches A9999 , the A should be replaced by B and the other characters should be reinitialized to 0000 ie B0000 , this should happen until Z9999 , is it possible somehow ?
or if you could show me how to increment A till Z that would be suffice
You will need to do some manual character manipulation on this one. There are several parts, first, you need to handle the simple addition of the numeric portion, then you need to handle the rollover of that to increment the alpha portion.
Data structures similar to this might be helpful:
01 Some-Work-Area.
02 Odometer-Char-Vals pic x(27) value 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
02 Odometer-Char occurs 27 pic x.
02 Odo-Char-Ndx pic s9(8) binary.
01 My-Odometer.
88 End-Odometer-Value value 'Z9999'.
02 My-Odometer-X pic X.
02 My-Odometer-9 pic 9999.
88 Carry-Is-True value 9999.
This would be used with a simple perform loop like so:
Move 0 to My-Odometer-9
Move 1 to Odo-Char-Ndx
Move Odometer-Char-Vals (Odo-Char-Ndx) to My-Odometer-X
Perform until End-Odometer-Value
Add 1 to My-Odometer-9
Display My-Odometer
If Carry-Is-True
Move 0 to My-Odometer-9
Add 1 to Odo-Char-Ndx
Move Odometer-Char-Vals (Odo-Char-Ndx) to My-Odometer-X
End-If
End-Perform
That is one way you could do it.
Please note, the code above took some shortcuts (aka skanky hacks) -- like putting a pad cell in the Odometer-Char array so I don't have to range check it. You wouldn't want to use this for anything but examples and ideas.
I'd probably do this with a nested perform loop.
Storage:
01 ws-counter-def
03 ws-counter-def-alpha-list pic x(27) value 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
03 ws-counter-def-num pic 9(4) comp-3.
01 ws-counter redefines ws-counter-def
03 ws-counter-alpha occurs 27 times indexed by counter-idx pic x.
03 ws-counter-num pic 9(4) comp-3.
01 ws-variable
03 ws-variable-alpha pic X
03 ws-variable-num pic X(4).
Procedure:
Initialize counter-idx.
Move 1992 to ws-counter-num.
Perform varying counter-idx from 1 by 1 until counter-idx > 26
move ws-counter-alpha(counter-idx) to ws-variable-alpha
perform until ws-counter-num = 9999
add 1 to ws-counter-
move ws-counter-num to ws-variable-num.
*do whatever it is you need to do to the pic X(5) value in ws-variable*
end-perform
move zeros to ws-counter-num
end-perform.
Just can't help myself... How about this...
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01.
02 ALL-LETTERS PIC X(26) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
02 LETTERS REDEFINES ALL-LETTERS.
03 LETTER PIC X OCCURS 26 INDEXED BY I.
01 START-NUMBER PIC 9(4).
01 COUNTER.
02 COUNTER-LETTER PIC X.
02 COUNTER-NUMBER PIC 9(4).
PROCEDURE DIVISION.
MOVE 1992 TO START-NUMBER
PERFORM VARYING I FROM 1 BY 1 UNTIL I > LENGTH OF ALL-LETTERS
MOVE LETTER (I) TO COUNTER-LETTER
PERFORM TEST AFTER VARYING COUNTER-NUMBER FROM START-NUMBER BY 1
UNTIL COUNTER-NUMBER = 9999
DISPLAY COUNTER - or whatever else you need to do with the counter...
END-PERFORM
MOVE ZERO TO START-NUMBER
END-PERFORM
GOBACK
.
This will print all the "numbers" beginning with A1992 through to Z9999.
Basically stole Marcus_33's code and twiked it a tiny bit more. If you feel so inclined please upvote his answer, not mine
For lovers of obfuscated COBOL, here's the shortest (portable) version I can think of (assuming a compiler with Intrinsic Functions):
IDENTIFICATION DIVISION.
PROGRAM-ID. so.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 ws-counter value "A00".
03 ws-alpha pic x.
03 ws-number pic 99.
PROCEDURE DIVISION.
1.
Perform with test after until ws-counter > "Z99"
Display ws-counter, " " with no advancing
Add 1 To ws-number
On size error
Move zero to ws-number
perform with test after until ws-alpha is alphabetic-upper or > "Z"
Move Function Char (Function Ord( ws-alpha ) + 1) to ws-alpha
end-perform
End-add
End-perform.
END PROGRAM so.
Tested on OpenVMS/COBOL. I shorten the value to X(3) since it's boring to watch run. A non-portable version (if you are aware of the Endianness of your platform) is to redefined the prefix as a S9(4) COMP and increment the low-order bits directly. But that solution wouldn't be any shorter...