I have a COBOL program that requires a transaction number every run of the program. I am planning to get the last transaction number from the file and add 1 to it. The problem is I don't know how to get the last recorded value.
IDENTIFICATION DIVISION.
PROGRAM-ID. INVENTORY-SYS.
AUTHOR. LINSEY.
DATE-WRITTEN. 2/22/2015.
DATE-COMPILED. 2/22/2015.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT MASTER-FILE ASSIGN TO "inventory-file.txt"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD MASTER-FILE.
01 IN-RECORDS.
02 IN-CODE PIC 9(7).
02 IN-NAME PIC X(30).
02 IN-PRICE PIC 9(3).
02 IN-STOCK PIC 9(4).
WORKING-STORAGE SECTION.
01 WS-EOF PIC A(1).
PROCEDURE DIVISION.
100-READ-FILE.
OPEN I-O MASTER-FILE.
PERFORM UNTIL WS-EOF = "Y"
READ MASTER-FILE
AT END
MOVE 'Y' TO WS-EOF
NOT AT END
DISPLAY IN-RECORDS
END-READ
END-PERFORM
CLOSE MASTER-FILE.
STOP RUN.
This is the sample program. The problem is it retrieves all the records from the file I only the last record from "inventory-file.txt"
Well, you are insistent, so:
IDENTIFICATION DIVISION.
PROGRAM-ID. INVENTORY-SYS.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT MASTER-FILE ASSIGN TO "inventory-file.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS w-if-in-file-status.
DATA DIVISION.
FILE SECTION.
FD MASTER-FILE.
01 IN-RECORDS.
02 IN-CODE PIC 9(7).
02 IN-NAME PIC X(30).
02 IN-PRICE PIC 9(3).
02 IN-STOCK PIC 9(4).
WORKING-STORAGE SECTION.
01 w-if-in-file-status PIC XX.
88 master-file-status-good VALUE ZERO "10".
88 end-of-master-file VALUE "10".
01 w-save-code PIC 9(7).
PROCEDURE DIVISION.
OPEN INPUT MASTER-FILE
[code to check FILE STATUS field]
PERFORM UNTIL end-of-master-file
READ MASTER-FILE
[code to check FILE STATUS field]
MOVE IN-CODE to w-save-code
END-PERFORM
DISPLAY ">" w-save-code "<"
CLOSE MASTER-FILE
[code to check FILE STATUS field]
GOBACK
.
I don't know why your IN-CODE field is numeric. Are you going to do calculations with it?
You keep a Control File. That has a date (to match to the Business Date file) a logical file-name, an environment and the last transaction number.
You maintain that file, checking everything as you do so.
I'm not sure of OpenCobol supports it, but you might try using OPEN/REVERSED. It is an old school way of reading a tape backwards, or these days, a virtual tape. I've no idea if it is implemented, but it is an easy way to read a sequential file backwards.
Related
I just want to know why i can't see my records on my Notepad files, is there something wrong in my code? I created my Notepad files into this path: "C:\Users\jamal.eclipse\MicroFocus\Student-Record.txt". When I run the code, it asks me the student number, the student tuition owed and the student name but can't see it in my Notepad files. Here's my code:
program-id. Project as "Project".
environment division.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT STUDENT-FILE-IN
ASSIGN TO
"C:\Users\jamal\.eclipse\MicroFocus\Student-Record.txt"
ORGANIZATION IS LINE SEQUENTIAL.
configuration section.
data division.
FILE Section.
FD STUDENT-FILE-IN.
01 STUDENT-RECORD-OUT PIC X(52).
working-storage section.
01 STUDENT-RECORD-IN.
05 STUDENT-NUMBER PIC 9(6).
05 TUITION-OWED PIC 9(6).
05 STUDENT-NAME PIC X(40).
01 PROMPT-MESSAGES-RESPONSES.
05 RECORD-Y-N PIC X(41) VALUE
"Do you have record ? Y or N: ".
05 RESPONSE PIC X(1).
05 STUDENT-NUMBER-OUT PIC X(24) VALUE
"Enter the Student Number: ".
05 TUITION-OWED-OUT PIC X(22) VALUE
"Enter the tuition owed: ".
05 STUDENT-NAME-OUT PIC X(22) VALUE
"Enter your Student Name: ".
procedure division.
CREATE-STUDENT-RECORD-FILE.
PERFORM STUDENT-RECORD-FILE.
PERFORM CREATE-STUDENT-RECORD
UNTIL RESPONSE="N" or "n".
PERFORM T-CREATE-STUDENT-RECORD-FILE.
STOP RUN.
STUDENT-RECORD-FILE.
PERFORM OPEN-RECORD.
PERFORM PROMPT-USER.
CREATE-STUDENT-RECORD.
PERFORM ENTER-STUDENT-DATA.
PERFORM WRITE-STUDENT-RECORD.
PERFORM PROMPT-USER.
T-CREATE-STUDENT-RECORD-FILE.
PERFORM CLS-CREATE-STUDENT-RECORD.
OPEN-RECORD.
OPEN OUTPUT STUDENT-FILE-IN.
PROMPT-USER.
DISPLAY RECORD-Y-N.
ACCEPT RESPONSE.
ENTER-STUDENT-DATA.
DISPLAY STUDENT-NUMBER-OUT.
ACCEPT STUDENT-NUMBER.
DISPLAY TUITION-OWED-OUT.
ACCEPT TUITION-OWED.
DISPLAY STUDENT-NAME-OUT
ACCEPT STUDENT-NAME.
WRITE-STUDENT-RECORD.
MOVE STUDENT-RECORD-IN TO STUDENT-RECORD-OUT.
WRITE STUDENT-RECORD-OUT.
CLS-CREATE-STUDENT-RECORD.
CLOSE STUDENT-FILE-IN.
end program Project.
I'm a beginner to Cobol, thank you in advance for the help.
Here is your program, i made some changes , i hope that will help you
IDENTIFICATION DIVISION.
PROGRAM-ID. project.
environment division.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT STUDENT-FILE-IN
ASSIGN TO "C:\Users\jamal\.eclipse\MicroFocus\Student-Record.txt"
ORGANIZATION IS LINE SEQUENTIAL.
configuration section.
data division.
FILE Section.
FD STUDENT-FILE-IN.
01 STUDENT-RECORD-OUT PIC X(52).
working-storage section.
01 STUDENT-RECORD-IN.
05 STUDENT-NUMBER PIC 9(6).
05 TUITION-OWED PIC 9(6).
05 STUDENT-NAME PIC X(40).
01 PROMPT-MESSAGES-RESPONSES.
05 RECORD-Y-N PIC X(41) VALUE
"Do you have record ? Y or N: ".
05 RESPONSE PIC X(1).
05 STUDENT-NUMBER-OUT PIC X(20) VALUE "Enter Student Number".
05 TUITION-OWED-OUT PIC X(20) VALUE "Enter tuition owed:".
05 STUDENT-NAME-OUT PIC X(20) VALUE "Enter Student Name:".
procedure division.
OPEN OUTPUT STUDENT-FILE-IN.
PERFORM PROMPT-USER.
PERFORM CREATE-STUDENT-RECORD
UNTIL RESPONSE="N" or "n".
PERFORM T-CREATE-STUDENT-RECORD-FILE.
CREATE-STUDENT-RECORD.
PERFORM ENTER-STUDENT-DATA.
PERFORM WRITE-STUDENT-RECORD.
PERFORM PROMPT-USER.
T-CREATE-STUDENT-RECORD-FILE.
PERFORM CLS-CREATE-STUDENT-RECORD.
PROMPT-USER.
DISPLAY RECORD-Y-N.
ACCEPT RESPONSE.
ENTER-STUDENT-DATA.
DISPLAY STUDENT-NUMBER-OUT.
ACCEPT STUDENT-NUMBER.
DISPLAY TUITION-OWED-OUT.
ACCEPT TUITION-OWED.
DISPLAY STUDENT-NAME-OUT
ACCEPT STUDENT-NAME.
WRITE-STUDENT-RECORD.
MOVE STUDENT-RECORD-IN TO STUDENT-RECORD-OUT.
WRITE STUDENT-RECORD-OUT.
CLS-CREATE-STUDENT-RECORD.
CLOSE STUDENT-FILE-IN
STOP RUN.
Is it possible to dynamically specify the file name at runtime in a COBOL program?
For example I would like to not have to define the name of a file I would like to open when I write the File-Control section, I would like to read the name of the file I want to open from a different file containing names and I would also like to define(FD) the file I want to open when I pass the name to File-COntrol.
The platform is Unix with Micro Focus Visual Cobol compiler.
I really love it when people ask for help posting a snippet of code that doesn't have a prayer of compiling.
IDENTIFICATION DIVISION.
PROGRAM-ID. STACK-OVERFLOW-1.
AUTHOR. Roland Hughes.
DATE-WRITTEN. TODAY.
DATE-COMPILED. TODAY.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OPTIONAL OUT_FILE
ASSIGN TO DISK
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS IN-STAT.
DATA DIVISION.
FILE SECTION.
FD OUT_FILE
IS GLOBAL
VALUE OF FILE-ID IS OUT_FILE_NAME
LABEL RECORDS ARE STANDARD.
01 DTL-LINE.
03 FIELDA PIC X(14).
03 FIELDB PIC X(10).
03 FIELDC PIC X(32).
03 FIELDD PIC X(03).
03 FIELDE PIC X(02).
WORKING-STORAGE SECTION.
01 STATUS-VARIABLES.
05 IN-STAT PIC X(2).
01 STUFF.
05 OUT_FILE_NAME PIC X(80).
PROCEDURE DIVISION.
MOVE "FILE1.DAT" to OUT_FILE_NAME.
OPEN OUTPUT OUT_FILE.
MOVE SPACES TO DTL-LINE.
MOVE 'HELLO!' TO FIELDA.
WRITE DTL-LINE.
CLOSE OUT_FILE
MOVE "FILE2.DAT" to OUT_FILE_NAME.
OPEN OUTPUT OUT_FILE.
MOVE SPACES TO DTL-LINE.
MOVE 'HI!' TO FIELDB.
WRITE DTL-LINE.
CLOSE OUT_FILE.
MOVE "FILE3.DAT" to OUT_FILE_NAME.
OPEN OUTPUT OUT_FILE.
MOVE SPACES TO DTL-LINE.
MOVE 'FRED' TO FIELDC.
WRITE DTL-LINE.
CLOSE OUT_FILE.
STOP RUN.
I tested this on KDE Neon with all of the latest updates installed. I installed the open-cobol package from the repositories.
cobc -x -free STACK-OVERFLOW-1.COB
./STACK-OVERFLOW-1
roland#roland-HP-EliteDesk-800-G2-SFF:~/COBOL$ ls *.DAT
FILE1.DAT FILE2.DAT FILE3.DAT
roland#roland-HP-EliteDesk-800-G2-SFF:~/COBOL$ cat *.DAT
HELLO! HI! FRED roland#roland-HP-EliteDesk-800-G2-SFF:~/COBOL$
A more complete example:
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN_FILE ASSIGN TO IN_FILE
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS FSTAT.
FILE SECTION.
FD IN_FILE
VALUE OF ID IS IN_FILE_NAME.
01 IN_POST.
03 FIELDA PIC X(14).
03 FIELDB PIC X(10).
03 FIELDC PIC X(32).
03 FIELDD PIC X(03).
03 FIELDE PIC X(02).
WORKING-STORAGE SECTION.
01 IN_FILE_NAME PIC X(22).
01 FSTAT PIC XX.
PROCEDURE DIVISION.
MOVE "FILE1.DAT" to IN_FILE_NAME
OPEN INPUT IN_FILE
CLOSE IN_FILE
MOVE "FILE2.DAT" to IN_FILE_NAME
OPEN INPUT IN_FILE
CLOSE IN_FILE
MOVE "FILE3.DAT" to IN_FILE_NAME
OPEN INPUT IN_FILE
CLOSE IN_FILE
STOP RUN.
I need help writing a small program in COBOL.
I wrote this piece of code:
IDENTIFICATION DIVISION.
PROGRAM-ID. CallC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 INITBUF PIC X(10).
01 SHOWBUF PIC X(10).
01 BUF USAGE IS POINTER.
01 NUM PIC 9(10).
PROCEDURE DIVISION.
MOVE 10 to NUM.
CALL "getBuffer" USING BY VALUE NUM RETURNING BUF.
CALL "initBuffer" USING BY VALUE BUF RETURNING INITBUF.
CALL "showBuffer" USING BY VALUE BUF RETURNING SHOWBUF.
DISPLAY SHOWBUF.
STOP RUN.
How do I go about writing the DISPLAY result to a file?
Bill. Declare the file as in the example below. Move whatever you want to output into the output variable then Write outputVar
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PARM-OUT ASSIGN TO PARMOUT.
*************************************************
DATA DIVISION.
FILE SECTION.
FD PARM-OUT
RECORDING MODE F.
01 PARMIN-REC.
05 PSID-IN PIC 9(09).
05 PCID-IN PIC 9(08).
05 IN-PCIDSEQ PIC 9(03).
IDENTIFICATION DIVISION.
PROGRAM-ID. PROGRAM1.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMP-GRADE ASSIGN TO 'input.txt'
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-STATUS.
DATA DIVISION.
FILE SECTION.
FD EMP-GRADE.
01 NEWFILE.
05 FS-EMPID PIC 9(5).
05 FS-NAME PIC A(5).
05 FS-STREAM PIC X(5).
05 FS-GRADE PIC A(1).
05 FILLER PIC X(64).
WORKING-STORAGE SECTION.
01 WS-EOF PIC A(1) VALUE "N".
01 WS-STATUS PIC X(2).
PROCEDURE DIVISION.
MAIN-PARA.
OPEN INPUT EMP-GRADE.
PERFORM PARA1 THRU PARA1-EXIT UNTIL WS-EOF="Y".
CLOSE EMP-GRADE.
STOP RUN.
MAIN-PARA-EXIT.
EXIT.
PARA1.
READ EMP-GRADE
AT END MOVE "Y" TO WS-EOF
NOT AT END
IF FS-GRADE='A'
DISPLAY FS-EMPID , FS-NAME , FS-STREAM , FS-GRADE
END-IF
END-READ.
PARA1-EXIT.
EXIT.
input provided:
1234 sita comp A
2345 tina main B
5689 riya math A
but the output is coming :
1234 sita comp A
It is reading only the first record.
As Brian Tiffin is hinting at in the comments, it is your data which is the problem.
This:
05 FILLER PIC X(64).
Means that your records should be 64 bytes longer than they are.
If you have a fixed-length record, or only fixed-length records, under an FD, then the data all have to be the same length, and equal to what you have defined in your program.
It means, and behaviour depends on compiler, you only have one record as far as the COBOL program is concerned.
A good way to spot such things is to always count your input records, and count your output records, and records which should not be selected for output. You can then easily tell if anything has fallen between a crack.
Leaving that aside, here's your program with some adjustments:
IDENTIFICATION DIVISION.
PROGRAM-ID. PROGRAM1.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMP-GRADE ASSIGN TO 'input.txt'
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-STUDENT-GRADE-STATUS.
DATA DIVISION.
FILE SECTION.
FD EMP-GRADE.
01 NEWFILE.
05 FS-EMPID PIC 9(5).
05 FS-NAME PIC X(5).
05 FS-STREAM PIC X(5).
05 FS-GRADE PIC X(1).
05 FILLER PIC X(64).
WORKING-STORAGE SECTION.
01 WS-STUDENT-GRADE-STATUS PIC X(2).
88 END-OF-STUDENT-GRADE-FILE VALUE "10".
88 ERROR-ON-STUDENT-GRADE-FILE VALUE ZERO.
PROCEDURE DIVISION.
OPEN INPUT EMP-GRADE
* perform a paragraph to check FILE STATUS field is zero, using an 88.
PERFORM PRIMING-READ
PERFORM PROCESS-STUDENT-GRADE-FILE
UNTIL END-OF-STUDENT-GRADE-FILE
CLOSE EMP-GRADE
* perform a paragraph to check FILE STATUS field is zero, using an 88.
GOBACK
.
PRIMING-READ.
PERFORM READ-STUDENT-GRADE
.
READ-STUDENT-GRADE.
READ EMP-GRADE
* perform a paragraph to check FILE STATUS field is zero, using an 88.
.
PROCESS-STUDENT-GRADE-FILE.
IF FS-GRADE='A'
* To see the problem with your data, DISPLAY the 01-level
DISPLAY NEWFILE
DISPLAY FS-EMPID
FS-NAME
FS-STREAM FS-GRADE
END-IF
PERFORM READ-STUDENT-GRADE
.
If you use the FILE STATUS field, you should check it. Since you use it, you can use it to check for end-of-file without the AT END. If you use a "priming read" you don't need the AT END/NOT AT END tangle. If you code the minimum of full-stops/periods in the PROCEDURE DIVISION, you won't have a problem with them. Commas are never needed, so don't use them. Format your program for human readability. Use good descriptive names for everything. The THRU on a PERFORM invites the use of GO TO. As a learning, avoid the invitation.
If your class itself enforces particular ways to code COBOL, you'll have to use those ways. If so, I'd suggest you do both. The first couple of times at least, submit both to your tutor. Even if they tell you not to do that, continue doing dual examples when given tasks (just don't submit them any more). There is no reason for you to start off with bad habits.
Keep everything simple. If your code looks bad, make it look good through simplification and formatting.
Remember also that COBOL is all about fixed-length stuff. Get's us back to your original problem.
the format of input file is like this:
Region ******* Company Name
A
B
C
A
C
with many lines.
I need to get a output file to rearrange the file with headers like this:
Company in Region A:
name
name
name...
Company in Region B:
name
name
name..
Company in Region C:
name
name
name..
My question is because the region in input file is not ordered. How can I add the second Region A company back in the header "Company in Region A"? I can only read the file one time (I cannot first all do lines with region A then reopen the file to read again). And I can only have 1 output file.
You could use the Sort verb with input/output procedure to sort the file into Region Sequence.
You can find many examples in Google. This ShorExample has a short Sort example,
there is more info here
You will probably need both input and output procedures
Sort Example:
PROCEDURE DIVISION.
000-SORT SECTION.
010-DO-THE-SORT.
SORT SORT-FILE ON ASCENDING KEY SORT-KEY-1
ON DESCENDING KEY SORT-KEY-2
USING INPUT-FILE
OUTPUT PROCEDURE IS 200-WRITE-OUTPUT
THRU 230-DONE-OUTPUT.
DISPLAY "END OF SORT".
STOP RUN.
200-WRITE-OUTPUT SECTION.
210-OPEN-OUTPUT.
OPEN OUTPUT OUTPUT-FILE.
220-GET-SORTED-RECORDS.
RETURN SORT-FILE AT END
CLOSE OUTPUT-FILE
GO TO 230-DONE-OUTPUT.
MOVE SORT-RECORD TO OUTPUT-RECORD.
WRITE OUTPUT-RECORD.
GO TO 220-GET-SORTED-RECORDS.
230-DONE-OUTPUT SECTION.
240-EXIT-OUTPUT.
EXIT.
If you are doing homework, remember that the goal of homework is not to solve a problem, it is to demonstrate that you have learned the class material. So, if this is homework, create your own solution based on what you have been taught. If you are trying to solve a real-life problem, the example below might help point you in the right direction. If you have not been taught sorting using an output procedure, you do not want to use the example below to do your homework. That said, the following program works using the sample data shown with GNUCobol. Notice in particular how paragraph OUTPUT-CO-BY-REGION-REPORT is used by the SORT.
--- contents of sample data file COMPANY.DAT ---
A WAL-MART
B EXXON
C CHEVRON
B BERKSHIRE
A APPLE
C GENERAL MOTORS
IDENTIFICATION DIVISION.
PROGRAM-ID. COMPANY-BY-REGION.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT COMPANY-FILE
ASSIGN TO 'COMPANY.DAT'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT COMPANY-SORT-FILE
ASSIGN TO DISK.
SELECT REGION-REPORT-FILE
ASSIGN TO 'COMPANY-BY-REGION.RPT'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD COMPANY-FILE.
01 COMPANY-RECORD.
02 COM-REGION PIC X.
02 FILLER PIC X.
02 COM-NAME PIC X(20).
SD COMPANY-SORT-FILE.
01 COMPANY-SORT-RECORD.
02 SORT-REGION PIC X.
02 FILLER PIC X.
02 SORT-NAME PIC X(20).
FD REGION-REPORT-FILE.
01 REGION-REPORT-RECORD PIC X(20).
WORKING-STORAGE SECTION.
01 SORTED-DATA-REMAINS PIC X VALUE 'Y'.
88 NO-SORTED-DATA-REMAINS VALUE 'N'.
01 WS-SORTED-RECORD.
02 WS-REGION PIC X.
02 FILLER PIC X.
02 WS-NAME PIC X(20).
01 REGION-REPORT-HEADER.
02 FILLER PIC X(18) VALUE 'COMPANY IN REGION '.
02 HEAD-REGION PIC X VALUE SPACE.
02 FILLER PIC X VALUE ':'.
01 REGION-DETAIL.
02 DET-NAME PIC X(20).
01 PRIOR-REGION PIC X.
PROCEDURE DIVISION.
WRITE-COMPANY-BY-REGION-REPORT.
SORT COMPANY-SORT-FILE
ASCENDING KEY SORT-REGION
SORT-NAME
USING COMPANY-FILE
OUTPUT PROCEDURE OUTPUT-CO-BY-REGION-REPORT
STOP RUN
.
OUTPUT-CO-BY-REGION-REPORT.
OPEN OUTPUT REGION-REPORT-FILE
PERFORM UNTIL NO-SORTED-DATA-REMAINS
RETURN COMPANY-SORT-FILE INTO WS-SORTED-RECORD
AT END SET NO-SORTED-DATA-REMAINS TO TRUE
NOT AT END
PERFORM WRITE-COMPANY-RECORD
END-PERFORM
CLOSE REGION-REPORT-FILE
.
WRITE-COMPANY-RECORD.
IF HEAD-REGION = SPACE
OR WS-REGION NOT = PRIOR-REGION
PERFORM PRINT-HEADER
END-IF
MOVE WS-NAME TO DET-NAME
WRITE REGION-REPORT-RECORD FROM REGION-DETAIL
.
PRINT-HEADER.
IF HEAD-REGION NOT = SPACE
MOVE SPACES TO REGION-REPORT-RECORD
WRITE REGION-REPORT-RECORD
END-IF
MOVE WS-REGION TO HEAD-REGION
PRIOR-REGION
WRITE REGION-REPORT-RECORD FROM REGION-REPORT-HEADER
.
You should do this in a single pass of the file. Instead of just checking one item at a time, check all of them in the single pass...