Skip to main content

Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

I am assuming that Net Express is the product that you are using, is that correct?

If you define the file as SEQUENTIAL and it has variable length records then it will have a binary header in the file and each record will contain a length field.

I think that what you are looking for is a LINE SEQUENTIAL file where the CRLF character will automatically be appended to the end of each variable length record.

There is a file handler configuration option named STRIPSPACE that would have to be set to OFF in order to keep spaces at the end of the record up to the length of the record specified.

Create a configuration file called extfh.cfg and set the environment variable EXTFH to point to it.

If this is Net Express then you can set this directly in the project properties under IDE.

the file should contain:

[XFH-DEFAULT]
STRIPSPACE=OFF

The following test program will do what you want.
It is a modified version of your example:

      id division.                                                  
      program-id.  testvarying.                                      
      environment division.                                          
      input-output section.                                          
          select my-file assign to "myfile.txt"                      
                         organization is line sequential            
                         file status is file-status.                
      data division.                                                
      file section.                                                  
      FD MY-FILE                                                    
         RECORDING MODE IS V                                        
         RECORD IS VARYING IN SIZE FROM 10 TO 20 CHARACTERS          
         DEPENDING ON WS-RECORD-SIZE.                                
      01 MY-RECORD.                                                  
         05  MY-DATA     PIC X(20).                                  
      working-storage section.                                      
      01 ws-record-size  pic 9(3).                                  
      01 WS-TYPE1.                                                  
           05 data1      pic x(10).                                  
      01 WS-TYPE2.                                                  
           05 data2      pic x(20).                                  
      01 file-status     pic x(2).                                  
      procedure division.                                            
         open output my-file                                        
         MOVE SPACES TO WS-TYPE1.                                    
         MOVE "11111" to data1                                      
         MOVE 10 TO WS-RECORD-SIZE.                                  
         MOVE WS-TYPE1 TO MY-RECORD.                                
         WRITE  MY-RECORD.                                          
         MOVE SPACES TO WS-TYPE2.                                    
         MOVE "222" to data2                                        
         MOVE 20 TO WS-RECORD-SIZE.                                  
         MOVE WS-TYPE2 TO MY-RECORD.                                
         WRITE  MY-RECORD.                                          
         close my-file.                                              


Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

Thanks Chris for your prompt and detailed (and very informative) reply. Yes, I'm using Net Express 5.1.

My concern in using  the configuration option STRIPSPACE in the extfh.cfg file as this would apply to all files defined as Line Sequential. This will not work for me as sometimes we require the spaces to be suppressed and other times we don't.

In Net Express, in the Project menu, the Properties option is greyed out.

==================================================================================================================

Thank you Chris and Dan for your answers to my question. I'm new to this forum and could not see where to answer your individual posts. The only thing I saw that allowed me to respond was the edit icon on my previous post!

Chris, is there any way to use the file name tag in the EXTFH.CFG with a derived file name? My problem is that the output text file that's created has a file name that consists partly of the current date (e.g. ABCDEFG_CCYYMMDD.txt).

Dan, the text file(s) created is sent to several different client sites and I have no idea what programs are processing them. Thank you so much for the detailed explanation. What I'm trying to accomplish is use one SELECT statement for a file that is to be used to generate three different output text files. I open and close the file three times so that works well. File one created has records that are 100 chars long, file two records are 200 chars long and file three records are 300 chars long. Previously I used the ORGANIZATION LINE SEQUENTIAL mode and that worked fine since the users did not complain about the variable length records (spaces at the end being truncated). However, a new client has requested that the records be fixed length.

Since I need to get the change out the door quickly I landed up with three SELECT statements but would really like to be able to work it the original way I planned to. The individual file name in the EXTFH.CFG seems to be the way to go but I need to be able to use a file name that's created on the fly.


#VariableLengthRecords

Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

The STRIPSPACE=OFF can be applied to a specific file by placing a file name tag in the extfh.cfg.

[XFH-DEFAULT]
BASENAME=ON
[MYFILE.TXT]
STRIPSPACE=OFF

If the properties option is greyed out it means that you don't have a project loaded so you must just be loading your source code directly in the IDE. I would highly recommend using a project file as it gives you a much better way of organizing your source and exectable builds. See the documentation here under Getting Started-->Using Net Express.

If you are not using a project then you can also set the EXTFH environment variable at the system level under Control Panel-->System->Advanced-->Environment Variables set EXTFH under System variables.


Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

The section of the documentation that describes this is Programming > File handling > Reference > File structures.  There are two general categories: File With Headers and Files Without headers.

If you declare a sequential file as RECORDING MODE V, then you are declaring a Variable Format Record Sequential File.  If you write data to such a file, then use a hex editor to examine the file on disk, you will see it will include an overall file header, plus a header in front of each record.  The headers are part of the internal representation, and are invisible to a COBOL program that declares the file as Variable Format Record Sequential File.  You needn't declare a WS-RECORD-SIZE PIC 9(004) COMP and you needn't write a CRLF record terminator, instead the record size is held internally in each record header, and this is handled behind the scenes.

Why did you get the idea to include a WS-RECORD-SIZE and add an extra two bytes in the record description and put CRLF in them before writing each record?   This is usually not necessary if COBOL programs will be the only software reading or interpreting the file.  Do you also need non-COBOL software to be able to read and interpret the file?

Perhaps what you really want is a File Without Headers.  The first type of sequential file without headers is a Line Sequential file.  This is declared ORGANIZATION LINE SEQUENTIAL, without the RECORDING MODE clause.  The representation on disk does not include headers.  Each record is terminated by a CRLF (on Windows) or just an LF (on UNIX).  You needn't declare extra bytes in the record definition for the record terminator characters because they get added automatically.

By default trailing spaces are stripped before each record in Line Sequential file is written, but you can control this using the STRIPSPACE file handler configuration option.

Line Sequential Files are not designed to represent binary data.  The fields in the record description should all be USAGE DISPLAY.  This is because a binary field might accidentally contain the bit pattern matching a CR or an LF, which would be misinterpreted as a record delimiter.  If you must represent binary data within a Line Sequential File, you can specify the INSERTNULL file handler configuration option, which will insert a NULL i.e. x"00" character before each non-printing character to "escape" it.  When the file is read back, the file handler strips these NULLs and preserves the non-printing characters.

Another type of sequential file without headers is a Record Sequential file.  This is declared ORGANIZATION RECORD SEQUENTIAL, without the RECORDING MODE clause.  It has no headers and also no record delimiters.  Every record has the same length, so no headers are needed.  Under such conditions, you could declare an extra two bytes in the record description and put CRLF in them before writing each record.  In this way, the file would appear to non-COBOL software as a text file, delimited in the usual Windows way with CRLF.  Record sequential files can successfully represent binary data because there is no chance any of the data will be misinterpreted as being a record delimiter, since there are no headers or delimiters to begin with.

These are your options.  Which one seems to best fit your needs?


Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

Thanks Chris for the example.

Is there any way to use the file name tag in the EXTFH.CFG with a derived file name? My problem is that the output text file that's created has a file name that consists partly of the current date (e.g. ABCDEFG_CCYYMMDD.txt).


Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

Thanks Dan for the great explanation.

The text file(s) created is sent to several different client sites and I have no idea what programs are processing them. What I'm trying to accomplish is use one SELECT statement for a file that is to be used to generate three different output text files. I open and close the file three times so that works well. File one created has records that are 100 chars long, file two records are 200 chars long and file three records are 300 chars long. Previously I used the ORGANIZATION LINE SEQUENTIAL mode and that worked fine since the users did not complain about the variable length records (spaces at the end being truncated). However, a new client has requested that the records be fixed length.

Since I need to get the change out the door quickly I landed up with three SELECT statements but would really like to be able to work it the original way I planned to. The individual file name in the EXTFH.CFG seems to be the way to go but I need to be able to use a file name that's created on the fly.


Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

You can do this on the fly file naming if you assign the file to an environment variable and then set the variable from within the program.

          select my-file assign to external myvariable
                         organization is line sequential
                         file status is file-status.

                display "MYVARIABLE" upon environment-name          
                display "newfile.txt" upon environment-value        
                open output my-file                                

In the extfh.cfg file you would specify the following:

[XFH-DEFAULT]
BASENAME=ON
[INTERNAL:myvariable]
STRIPSPACE=OFF

So whatever MYVARIABLE is set to when the file is opened will be used as the name of the file and the stripspace=off will take effect.


Hello.

I'm trying to write variable length records to a SEQUENTIAL file. I don't want the trailing spaces to be removed. I add on two chars at the end of each record type and populate them with CRLF. My results are not what I expected. The output file appears to have binary characters and the rows are not the length of the value in WS-RECORD-LENGTH. My FD statement is:

  FD MY-FILE

         RECORDING MODE IS V

         RECORD IS VARYING IN SIZE FROM 191 TO 370 CHARACTERS DEPENDING ON WS-RECORD-SIZE.

   01 MY-RECORD.

         05  MY-DATA     PIC X(370)

In Working Storage

01 WS-TYPE1.                         (record length191)

     05

     05 WS-CRLF1   PIC X(2).

01 WS-TYPE2.                        (record length 370)

     05

     05 WS-CRLF2   PIC X(2).

Here's the code to populate the record.

MOVE SPACES TO WS-TYPE1.

MOVE blah blah

MOVE WS-RECORD-DELIMITER TO WS-CRLF1.      (has hex values of CRLF)

MOVE 191 TO WS-RECORD-SIZE.                                (PIC 9(004) COMP)  

MOVE WS-TYPE1 TO MY-RECORD.

WRITE  MY-RECORD.

Any suggestions will be greatly appreciated

Awesome!! That's what I was looking for. Thank you.