« We keep meaning to shut it down, but... | Main | HP's latest layoffs chop a fresh slice of jobs »

September 15, 2015

COBOL Tools for Comma Separated Values

CSV exampleIt's been a long time since I wrote in COBOL, and I have an elementary question about creating a comma-delimited file. If I want...

"item one", "item two","","","item three"

How do I create the "," between item one and item two?

And the ","",""," would it be the same?  Just put that inside double quotes?

Something tells me that there is an escape sequence, but the mind is not cooperating. 

Walter Murray, who worked in HP’s Language Labs before moving on to other 3000 work, replies

The STRING statement is helpful. I don't advocate using an apostrophe to delimit nonnumeric literals, preferring to stick with standard COBOL. And yes, QUOTE is a figurative constant guaranteed to give you a quotation mark.

Murray offers a COBOL sample program to illustrate.
000100  IDENTIFICATION DIVISION.                            
000200  PROGRAM-ID. COBTEST.                                
000610  DATA DIVISION.                                      
000620  WORKING-STORAGE SECTION.                            
000630  77  ONE-COMMA    PIC X       VALUE ",".             
000640  01  1ST-ITEM     PIC X(6)    VALUE "ITEM 1".        
000650  01  2ND-ITEM     PIC X(6)    VALUE "ITEM 2".        
000660  01  3RD-ITEM     PIC X(6)    VALUE "ITEM 3".        
000670  01  MY-RECORD    PIC X(72).                         
000700  PROCEDURE DIVISION.                                 
000800  1000-START.                                         
000900      INITIALIZE MY-RECORD                            
001000      STRING  QUOTE 1ST-ITEM QUOTE ONE-COMMA          
001010              QUOTE 2ND-ITEM QUOTE ONE-COMMA          
001011              QUOTE          QUOTE ONE-COMMA          
001012              QUOTE          QUOTE ONE-COMMA          
001013              QUOTE 3RD-ITEM QUOTE                    
001014              DELIMITED SIZE                          
001015              INTO MY-RECORD                          
001016      DISPLAY MY-RECORD                               
001020      STOP RUN.       
001100  END PROGRAM COBTEST.

And the output...

"ITEM 1","ITEM 2","","","ITEM 3"

Tony Summers adds

It's worth putting a final comma at the end of the line, otherwise some versions of Excel can make the last column very wide.

Ken Roberston notes

One item worth noting, is that right before the STRING statement, you should move spaces to your output buffer.  STRING will not clear the buffer, so if your current string expression turns out to be shorter than your last, whatever was there before will remain - and you will get bad values in your output.

MOVE SPACES TO OSTRING
STRING XYZ etc. 
  INTO OSTRING

WRITE BIGREC FROM OSTRING

Finally Robert Mills has a macro for COBOL that creates a CSV record (copy and paste to retrieve all the characters in every line of the macro).

*> *************************************************************************
*> %AppendCsv(Field#,CsvRecord#)
*> -------------------------------------------------------------------------
*> Append Field to CsvRecord. If Field contains a comma (,) then Field is
*> quoted (") before being added. Quotes (") within Field will be replaced
*> with single-quotes (').
*> *************************************************************************

01 AppendCsv-macro.
05 AppendCsv-comma-count pic s9(04) comp value zero.
05 AppendCsv-field pic x(512) value spaces.
05 AppendCsv-field-length pic s9(04) comp value zero.
05 AppendCsv-index pic s9(04) comp value zero.
05 AppendCsv-pointer pic s9(04) comp value zero.

$define %AppendCsv=
initialize AppendCsv-macro
move function trim(!1) to AppendCsv-field
move length(function trim(AppendCsv-field)) to AppendCsv-field-length
move length(function trim(!2, trailing)) to AppendCsv-pointer
if AppendCsv-pointer > 1 then
move "," to !2(!3:1)
add 1 to AppendCsv-pointer end-add
end-if
perform
varying AppendCsv-index from 1 by 1
until AppendCsv-index > AppendCsv-field-length
if AppendCsv-field(AppendCsv-index:1) = "," then
add 1 to AppendCsv-comma-count end-add
end-if
if AppendCsv-field(AppendCsv-index:1) = quote then
move "'" to AppendCsv-field(AppendCsv-index:1)
end-if
end-perform
if AppendCsv-field-length > zero then
if AppendCsv-comma-count > zero then
string
quote, function trim(AppendCsv-field), quote delimited by size
into !2 with pointer AppendCsv-pointer
end-string
else
string
function trim(AppendCsv-field) delimited by size
into !2 with pointer AppendCsv-pointer
end-string
end-if
end-if#

03:58 PM in Hidden Value, Homesteading | Permalink

Bookmark and Share

Use our search engine to find 20 years
of HP 3000 news and articles

Comments

Comments

The comments to this entry are closed.