I'm trying to write a subprogram in COBOL to make a logfile called from my main program. I don't want the logfile is cleared every time I call the subprogram so I use 'open extend'. The problem is because of an unknown reason it won't work, the program does nothing. When i change 'open extend' into 'open output' it works but I don't want the file is overwritten every time.
IDENTIFICATION DIVISION.
PROGRAM-ID. LOGGER.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT LOGFILE ASSIGN TO "LOGFILE.txt"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD LOGFILE.
copy "FDLOGGER.cpy".
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 LOGFILEBOODSCHAP PIC X(150) value spaces.
Procedure division USING LOGFILEBOODSCHAP.
pgm.
open EXTEND LOGFILE
Move Current-time to TIJD
Move Current-date to DATUM
Move LOGFILEBOODSCHAP to BOODSCHAP
write logrecord
close LOGFILE
exit program
.
Well, it's a guess, as you have not provided much, but if "LOGFILE.txt" does not exist, you will need OPTIONAL on your SELECT.
Suggest you put FILE STATUS checking in your code.
I know your question is very old here. But I was still having the same problem today and after a few hours I discover that GnuCOBOL 2.0 with OpenCobolIDE 4.7.6 that I am using generates error 35 when trying to use OPEN EXTEND. I solved it in a not very elegant way, but it works perfectly. I am sharing the solution I found.
IDENTIFICATION DIVISION.
PROGRAM-ID. CREATFIL.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION ALL INTRINSIC.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FD-VIRTUAL ASSIGN TO "CADFILE.TXT"
ORGANIZATION IS LINE SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-GET-ERROR.
DATA DIVISION.
FILE SECTION.
FD FD-VIRTUAL.
01 FS-BOOK.
05 NOME PIC X(40).
WORKING-STORAGE SECTION.
77 WS-GET-ERROR PIC XX.
LOCAL-STORAGE SECTION.
01 TB-VIRTUAL.
05 TB-BOOK.
10 LS-NOME PIC X(40).
77 LS-ENTER PIC X.
77 WS-RESP PIC A VALUE "Y".
PROCEDURE DIVISION.
OPEN EXTEND FD-VIRTUAL.
IF WS-GET-ERROR = "35"
OPEN OUTPUT FD-VIRTUAL
END-IF
IF WS-GET-ERROR = "00"
PERFORM UNTIL UPPER-CASE(WS-RESP) NOT = "Y"
DISPLAY X"0D"
DISPLAY "Name: " WITH NO ADVANCING
ACCEPT LS-NOME
WRITE FS-BOOK FROM TB-BOOK
DISPLAY "More record (Y) for YES " WITH NO ADVANCING
DISPLAY "- any key for NOT: "
WITH NO ADVANCING
ACCEPT WS-RESP
IF UPPER-CASE(WS-RESP) NOT = "Y"
EXIT PERFORM
END-IF
END-PERFORM
END-IF.
CLOSE FD-VIRTUAL.
DISPLAY X"0D".
DISPLAY "Press <ENTER> to finish... " WITH NO ADVANCING.
ACCEPT LS-ENTER.
STOP RUN.
END PROGRAM CREATFIL.
Observe the instruction
OPEN EXTEND FD-VIRTUAL.
IF WS-GET-ERROR = "35"
OPEN OUTPUT FD-VIRTUAL
END-IF
Related
I'm trying to open a sequential dataset.
I get the file status 37, for which IBM says:
An OPEN statement was attempted on a file that would not support the
open mode specified in the OPEN statement. Possible violations are:
The EXTEND or OUTPUT phrase was specified but the file would not support write operations.
The I-O phrase was specified but the file would not support the input and output operations permitted.
The INPUT phrase was specified but the file would not support read operations.
I suspect the third, because the relevant bits of my program are :
*----------------------
INPUT-OUTPUT SECTION.
*----------------------
FILE-CONTROL.
* input file 1
SELECT INPUT-1-FILE
ASSIGN TO EXAMPLE
ORGANIZATION IS RELATIVE
ACCESS MODE IS DYNAMIC
RELATIVE KEY IS INPUT-1-ACCESS-KEY
FILE STATUS IS INPUT-1-FS
.
****************
DATA DIVISION.
****************
*--------------
FILE SECTION.
*--------------
* fichier 1
FD INPUT-1-FILE
.
01 INPUT-1-LINE.
05 filler PIC X(300).
*-------------------------
WORKING-STORAGE SECTION.
*-------------------------
77 INPUT-1-ACCESS-KEY PIC 9(3) comp value 1.
01 INPUT-1-FS PIC 99 value 00.
*********************
PROCEDURE DIVISION.
*********************
OPEN INPUT INPUT-1-FILE
DISPLAY INPUT-1-FS
And the DD card in my JCL looks like :
EXAMPLE DD DISP=SHR,DSN=MY.DATASET.NAME
We're using COBOL v5, so I checked IBM's relevant docs, but I can't find any reason that my file is not openable in input mode.
Here are my dataset's characteristics:
And the result of a VSAM listcat:
In your program, ORGANIZATION IS RELATIVE means the input file must be a relative record data set (RRDS) VSAM file, which can be defined using the IDCAMS DEFINE command. What could be happening is that if the file you open is a sequential file, you get a file status of 37. More information about IDCAMS DEFINE is mentioned in IBM Redbook "VSAM Demystified" section 1.5.3, 'Relative record data set'.
You can make the input file a VSAM file with something like the following:
//[YOURID] JOB ,
// MSGCLASS=S,REGION=0M,COND=(9,LT),NOTIFY=&SYSUID,TIME=(1,1)
//*********************************************************************
//* Create a VSAM
//*********************************************************************
//S1IDCAMS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DELETE ([YOURID].P00695.VSAMRRDS) CLUSTER PURGE
DEFINE CLUSTER (NAME([YOURID].P00695.VSAMRRDS) -
NUMBERED -
RECORDSIZE(80 80) -
BUFFERSPACE(2048) -
SHAREOPTIONS(4 3) -
VOLUMES(SYS162)) -
DATA (NAME([YOURID].P00695.VSAMRRDS.DATA) -
TRACK(1,1) -
CISZ (1024))
/*
//S2REPRO EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//VSAM DD DISP=SHR,DSN=[YOURID].P00695.VSAMRRDS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
REPRO OUTFILE(VSAM) INFILE(INREC)
/*
//INREC DD *
XXXXXXX060ALISONALISONALISONALISONALISONALISONALISONALISONAL ISONALIS
XXXXXXX060ALISONALISONALISONALISONALISONALISONALISONALISONAL ISONALIS
/*
In the IBM docs linked in the question (page 126: FILE-CONTROL paragraph) it is said that the relative access mode is only available for VSAM files :
Problem: the input file is currently not a VSAM file.
Solution: make the input file a VSAM file.
This worked:
DD card in the JCL when creating the input file:
//FOO DD DISP=(NEW,CATLG,DELETE),
// SPACE=(TRK,(1000,1000),RLSE),
// LRECL=300,
// RECORG=RR,
// DSN=MY.DATASET.NAME
The RECORG parameter makes the dataset an RRDS. The lines don't have an easily defined key, so I couldn't use a KSDS and I need the random access, so no ESDS either.
DD card for reading the dataset:
//BAR DD DISP=SHR,DSN=MY.DATASET.NAME
And then in the COBOL program (in FILE-CONTROL):
SELECT INPUT-FILE
ASSIGN TO BAR
ORGANIZATION IS RELATIVE
ACCESS MODE IS DYNAMIC
RELATIVE KEY IS INPUT-FILE-KEY
FILE STATUS IS INPUT-FILE-STATUS
.
If you want to open a sequential dataset for read, you need to open it for Input (done!), have it in the JCL with DISP=SHR (you could try with OLD, but don't need it), and have ACCESS IS SEQUENTIAL.
ACCESS IS RELATIVE as noted by other users is for VSAM only, and your IDCAMS output shows that this is not a VSAM file. If it's just a sequential dataset, you don't need a key either.
I'm working with some old VB6 code and it's still new to me. I know that in VB6 you assign an integer to represent a file. I have a program that uses quite a few files and it's tough to tell what file it's working with when it will only display the number when I mouse over the variable. (pic below).
So in the example above, how do i know what file #5 is?
Thanks
You might have to modify the program to 'register' filenames with their file numbers:
Dim FileRegister as Collection
Dim FileName as String
Dim FileNumber as Integer
...
FileRegister.add FileName, str(FileNumber)
Open FileName For Output as #FileNumber
...
FileRegister.Remove str(FileNumber)
Close #FileNumber
Search the code for the variable name? Do you have MZTools? It's a free plugin with excellent search facilities.
Trace the code execution back to see where the unit number comes from? Use the call stack view when debugging, or use MZTools to list all calls to any routine.
(Last resort) add logging.
Every time a file is opened, log the filename and unit number.
Every time a file is closed, log the unit number.
You could leave the logging in the production code, maybe with a way to turn it on/off at runtime. It could be useful again.
In COBOL i want to read a line sequential file. The first line occurs one time. The second and the thirth line can be repeated multiple (unknown) times. I really don't know how to do it.
I think the file description is something like this:
01 DBGEGEVENS PIC X(200).
01 PROJECT. (occurs unknown times)
03 PROJECTCODE PIC X(10).
03 CSVPAD PIC X(200).
It depends on the file format
Do you want a VB file format ???? then
FILE-CONTROL.
SELECT In-File ASSIGN .....
DATA DIVISION.
FILE SECTION.
FD Comp-File.
01 DBGEGEVENS PIC X(200).
01 PROJECT.
03 PROJECTCODE PIC X(10).
03 CSVPAD PIC X(200).
with
Read In-File
Read In-File
Read In-File
You would use DBGEGEVENS for the first record and project for secon or subsquent records
For Fixed width file format
FILE-CONTROL.
SELECT Comp-File ASSIGN .....
DATA DIVISION.
FILE SECTION.
FD Comp-File.
01 input-record.
WORKING-STORAGE SECTION.
01 DBGEGEVENS PIC X(200).
01 PROJECT.
03 PROJECTCODE PIC X(10).
03 CSVPAD PIC X(200).
with
Read In-File into DBGEGEVENS
Read In-File into PROJECT.
Read In-File into PROJECT.
Either should work, depending on which file format you use
The code given indicates a VB file - record one is 200 bytes, while the other records are 210 bytes. There should be an indicator on the records that describes what they are and their purpose. Ultimately, you'd be best served by reading them into WORKING-STORAGE - and I'd ask whomever is passing you the file what indicators are available. If, however, you know for a fact that record one is the only 200 byte record in the file, that would be treated as a header read - read once into its definition - while the remaining 210 byte records (and I want to emphasize the definition provided describes 210 bytes) would be read into a WORKING-STORAGE area fitting their definition.
We have a system based on AcuCobol and vision-files.
We need to dump the entire datafiles in to txt-based files to be imported in to a sql server.
We are using vutil to dump the data right now, but it's creating a fixed-width file and we would want this to be a delimited file of some sort. The command we are using right now is this:
vutil -unload -t sourcefile destinationfile
Now does anyone have any experiance with this, and if so, what would be the best utility for this?
what I'll do to get the job done is this:
Unload your table with a JCL into a file.
Use this file in a batch,
with a copybook matching the description of the table :
(ex: if your table has 3 columns [ID], [NAME] and [ADDRESS], then create a copy CC-1 with:
O1 CC-1
05 ID PIC X (16).
05 NAME PIC X (35).
05 ADDRESS PIC X (35).
For each line move the line into the copy CC-1.
Create a second copy CC-2
O1 CC-2
05 ID PIC X (16).
05 FILLER PIC X VALUE ';'.
05 NAME PIC X (35).
05 FILLER PIC X VALUE ';'.
05 ADDRESS PIC X (35).
05 FILLER PIC X VALUE ';'.
Do a move corresponding of CC-1 to CC-2
Write in the output.
This for each line. You get in the output a CSV file of all your data.
You can reuse the batch and JCL, you just have to change the size of the records and the descriptions of the copy to match the table you are unloading.
Free and easy. :)
Google is your friend... I did a quick search and came up with NextForm which claims to convert Vision to CSV (and other formats).
From the "fine print" it looks like you can download a trial copy but will have to fork out about $400.00 to get a licenced version (that won't drop random records).
I have absolutely no experience with this product so cannot tell you if it really does the job or not.
Edit
Sometimes it is more productive to work with rather than fight against a legacy system.
Have you looked at AcuODBC? This lets Windows programs read/import
Vision files. You could potentially use this to access Vision files from any Windows ODBC enabled application. I believe you may need to compile a data dictionary to make this work, but it could provide a bridge between where you are and where you want to be.
Another approach might be to write your own dump programs in AcuCobol. Read a record, format and
write it. Writting a Cobol program of this complexity should not be too challenging a task provided the files
do not have a complex structure (eg. multiple record types/layouts in the same file, or repeating fields within a
single record).
Your task will be significantly more complex if a single Vision file needs to be post-processed into
multiple SQL Server tables. Unfortunately, complex conversions are fairly
common with Cobol legacy systems
because of their tendancy to use rich/complex/denormalized file structures (unlike SQL which works best with
normalized tabular data).
If the Vision files are more complex that a single SQL Server table, then maybe you could consider using the
AcuXML Interface
to dump the files into XML and then use an XSLT processor to create CSV or whatever other format you
need from there. This would allow you to work with fairly complex Cobol record structures. Again,
this approach means writting some fairly basic AcuCOBOL font end programs.
Based on your comments to my original post, you are not a die-hard Cobol programmer. Maybe it would be
a good idea to team up with someone in your shop that has a working knowledge of the language and
environment before pushing this any further. I have a feeling that this task is going to be a bit more complicated than "dump and load".
If you have Acubench under the Tools Menu there is an option for Vision File Utility, from there you can Unload your Vision Data to a text file which is tab delimited.
From there you can import to Excel as a tab delimited file and then re-save as a csv file.
I am trying to find out a way to check whether a file is already opened in COBOL, so that I can open it if it is closed or close it if it is opened.
Thnx.
Check the FILE STATUS and act accordingly.
Try the following:
Add a FILE-STATUS under the FILE-CONTROL, for example:
FILE-CONTROL.
SELECT MYFILE ASSIGN MYDD
ORGANIZATION SEQUENTIAL
ACCESS SEQUENTIAL
FILE STATUS MYFILE-STATUS.
Declare a FILE STATUS variable in WORKING-STORAGE
as a PIC X(2) value, for example:
01 MYFILE-STATUS PIC X(2).
88 MYFILE-ALREADY-OPEN VALUE '41'.
Then in the PROCEDURE DIVISIONissue an OPEN for your
file. Immediately following that, test the value of FILE STATUS
as in:
OPEN MYFILE....
IF MYFILE-ALRADY-OPEN
CLOSE MYFILE...
END-IF
IF MYFILE-STATUS <> '00'
perform some sort of general error routine
END-IF
Values of FILE STATUS where the first character is not a '9', are
COBOL standard values so testing for '41' to detect an already open file
should work on all COBOL implementations. Beware when the first character is a '9',
these are vendor specific file status codes. Check out the following link for
a good introduction to using COBOL FILE STATUS: http://www.simotime.com/vsmfsk01.htm
Your compiler may also provide a external API, such as CBL_CHECK_FILE_EXIST which can be found on Micro Focus COBOL, AcuCOBOL and Fujutsu COBOL.
For example, on Micro Focus COBOL:
copy "cblproto.cpy".
program-id. MYMAIN.
working-storage section.
01 .
05 file-details cblt-fileexist-buf.
procedure division.
call 'CBL_CHECK_FILE_EXIST' using 'mymain.cbl '
file-details
if return-code not = 0
display "File mymain.cbl does not exist (or error)"
else
display "File mymain.cbl size is " cblt-fe-filesize
of file-details
end-if
end program MYMAIN.