Home > Archive > Cobol > July 2006 > Need program to count delimiters
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Need program to count delimiters
|
|
| sasquatch53@gmail.com 2006-06-28, 6:55 pm |
| I need a utility that validates the number of delimiters in a file on
our MVS mainframe. I'm sure this is a fairly common requirement when
loading data into a data warehouse.
I was thinking that COBOL would probably be the best thing to write it
in. The latest release of COBOL we have is "Enterprise COBOL for z/OS
and OS/390 3.2". Our MVS level is "MVS LEVEL: 0510.05 z/OS V1R7".
We are using JES2.
I know a little bit of COBOL but it would take me a couple of w s (or
more) to hack something together.
Is there anybody out there that could provide me with the basic COBOL
program that I could modify if required?
The input file is Variable Blocked (VB) but it would be nice if the
program would work for VB or Fixed Block (FB) files.
I'd like to pass in three variables:
LRECL = The logical record length of the file (would this be
required?).
DELIM = Delimiter character in HEX (in my case it's a HEX 2F).
DCOUNT = Delimiter count as an INTEGER.
There are no packed fields in these records. The entire record should
be able to be treated as a single character field.
The program should output records that have the matching number of
delimiters to one DD dataset and records that don't have the matching
number of delimiters to another DD dataset.
I looked at the COBOL manual on line and it looks like there is a
function called INSPECT that counts characters across a record/field.
Would this work?
Tim Lindsey
| |
| James J. Gavan 2006-06-28, 6:55 pm |
| sasquatch53@gmail.com wrote:
BOTTOM POSTING :
> I need a utility that validates the number of delimiters in a file on
> our MVS mainframe. I'm sure this is a fairly common requirement when
> loading data into a data warehouse.
>
> I was thinking that COBOL would probably be the best thing to write it
> in. The latest release of COBOL we have is "Enterprise COBOL for z/OS
> and OS/390 3.2". Our MVS level is "MVS LEVEL: 0510.05 z/OS V1R7".
> We are using JES2.
>
> I know a little bit of COBOL but it would take me a couple of w s (or
> more) to hack something together.
>
> Is there anybody out there that could provide me with the basic COBOL
> program that I could modify if required?
>
> The input file is Variable Blocked (VB) but it would be nice if the
> program would work for VB or Fixed Block (FB) files.
>
> I'd like to pass in three variables:
> LRECL = The logical record length of the file (would this be
> required?).
> DELIM = Delimiter character in HEX (in my case it's a HEX 2F).
> DCOUNT = Delimiter count as an INTEGER.
>
> There are no packed fields in these records. The entire record should
> be able to be treated as a single character field.
>
> The program should output records that have the matching number of
> delimiters to one DD dataset and records that don't have the matching
> number of delimiters to another DD dataset.
>
> I looked at the COBOL manual on line and it looks like there is a
> function called INSPECT that counts characters across a record/field.
> Would this work?
>
> Tim Lindsey
>
Not familiar with mainframes but if the IBM Enterprise you are using has
OO - then you could use Java.
The INSPECT statement is very flexible - check out your IBM on-line help
(not the Language Reference Manual, necessarily) for various examples.
The following is a bit crude but should give you some idea as to what
you can do - I'm using commas instead of your Hex 2F :-
Jimmy
*>--------------------------------------------------------------
Program-id. InspectTallying.
WORKING-STORAGE SECTION.
*> Two input file records, varying in length :-
01 Record-1.
05 Rec1-FieldCount pic 9(03) value 5.
05 Rec1-Data pic x(21) value
"ABCD,EFG,HIJ,KLM,NOP,".
01 Record-2.
05 Rec2-FieldCount pic 9(03) value 6.
05 Rec2-Data pic x(28) value
"123,456,78910,111213,1415,16".
*> Note : I've left off the final comma after '16' above
01 ws-Record.
05 pic x occurs 1 to 100 depending on ws-Length.
01 Kounter-1 pic 9(03).
01 Kounter-2 pic 9(03).
01 ws-Length pic 9(03).
Procedure Division.
move Rec1-FieldCount to Kounter-1
compute ws-Length = function length (Rec1-Data)
*> I'm using REFERENCE MODIFICATION below
move Rec1-Data to ws-Record(1:ws-Length)
perform THE-INSPECT
move Rec2-FieldCount to Kounter-1
compute ws-Length = function length (Rec2-Data)
*> I'm using REFERENCE MODIFICATION below
move Rec2-Data to ws-Record(1:ws-Length)
perform THE-INSPECT
STOP RUN.
THE-INSPECT.
Initialize Kounter-2
INSPECT ws-Record TALLYING Kounter-2 for all ","
if Kounter-2 = Kounter-1
display "Valid Record"
else display "Invalid Record"
End-if
*>--------------------------------------------------------------
| |
|
| Example:
move zero to delimiter-count.
perform until eof-flag = 'Y'
read input-file
at end move to 'Y' eof-flag
not at end
inspect input-record tallying delimiter-counter
for all x'2F'
end-read
end-perform.
Test for whether you want FB or VB and mod
accordingly.
You're going to need two FDs one VB and one FB.
Not able to test this but I think this will work.
Somebody check me if I make a mistake.
FD FB-INPUT
label records are standard
block contains 0 records
record contains 0 characters
recording mode is F.
01 FB-record pic x(32760).
This will enable you read any FB file.
FD VB-INPUT
label records are standard
block contains 0 records
record is varying from 1 to 32756 characters
depending on RDW
recording mode is V.
01 VB-record pic x(32756).
working-storage section.
01 workarea.
05 RDW pic 9(9).
This should enable you to read any VB file. When you
read the record it will put the length in RDW (Record
Descriptor Word)
Good Luck.
| |
| hcmason@sbcglobal.net 2006-06-29, 6:55 pm |
| Hi:
Back in the day, I used to use both string and unstring with pointer
option to
string things together in cobol...
This was helpful in printer commands...
System Test FBM Legacy MWI DB2 Tables & Data to Oracle OWH
I think it would be difficult to write a generalized program for each
file. programs usually are data dependant, and the record layout tends
to drive your code...
D1000-STRING-THAT-THING.
512700 STRING AREA-OF-HOLD
512800 DELIMITED BY '%'
512900 INTO STRING-WORK-AREA
513000 WITH POINTER WS-STRING-POINTER.
string and unstring will be useful to handle the string or pulling
apart of the data...
sasquatch53@gmail.com wrote:
> I need a utility that validates the number of delimiters in a file on
> our MVS mainframe. I'm sure this is a fairly common requirement when
> loading data into a data warehouse.
>
> I was thinking that COBOL would probably be the best thing to write it
> in. The latest release of COBOL we have is "Enterprise COBOL for z/OS
> and OS/390 3.2". Our MVS level is "MVS LEVEL: 0510.05 z/OS V1R7".
> We are using JES2.
>
> I know a little bit of COBOL but it would take me a couple of w s (or
> more) to hack something together.
>
> Is there anybody out there that could provide me with the basic COBOL
> program that I could modify if required?
>
> The input file is Variable Blocked (VB) but it would be nice if the
> program would work for VB or Fixed Block (FB) files.
>
> I'd like to pass in three variables:
> LRECL = The logical record length of the file (would this be
> required?).
> DELIM = Delimiter character in HEX (in my case it's a HEX 2F).
> DCOUNT = Delimiter count as an INTEGER.
>
> There are no packed fields in these records. The entire record should
> be able to be treated as a single character field.
>
> The program should output records that have the matching number of
> delimiters to one DD dataset and records that don't have the matching
> number of delimiters to another DD dataset.
>
> I looked at the COBOL manual on line and it looks like there is a
> function called INSPECT that counts characters across a record/field.
> Would this work?
>
> Tim Lindsey
| |
| Colin Campbell 2006-06-29, 9:55 pm |
| Using UNSTRING on the record with COUNT IN in the DELIMITED phrase would
give a count of all delimiters in the record with a single statement.
I'm not positive, but I expect that the identifier associated with the
COUNT IN phrase has to be initialized (set to zero) before processing
each record. The IBM documentation I read didn't make this clear.
| |
| HeyBub 2006-06-29, 9:55 pm |
| Colin Campbell wrote:
> Using UNSTRING on the record with COUNT IN in the DELIMITED phrase
> would give a count of all delimiters in the record with a single
> statement. I'm not positive, but I expect that the identifier
> associated with the COUNT IN phrase has to be initialized (set to
> zero) before processing each record. The IBM documentation I read
> didn't make this clear.
COUNT provides the number of characters transferred, not the number of
delimiters.
| |
| sasquatch53@gmail.com 2006-07-12, 6:55 pm |
| I've got the program working and can even pass in the delimiter value
and target delimiter count.
But, I always have to set the maximum record length (show below as
32756) to the actual LRECL of the incoming VB file less 4 bytes. I want
this program to work with any VB file. If I have to hard code this in
that will not work.
You show the RDW in the working storage section in your sample but do I
need to do a MOVE command to load it or something?
Here is the program I have so far. Keep in mind that I know very little
about COBOL so any constructive feedback is welcome.
IDENTIFICATION DIVISION.
PROGRAM-ID. VARSRCH.
INSTALLATION. IBM 370.
DATE-WRITTEN. JULY 10,2006.
DATE-COMPILED.
SECURITY. RACF.
*
EJECT
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
*-------------- INPUT FILE ------------------------------------
SELECT FILE-IN ASSIGN TO UT-S-FILEIN.
*-------------- OUTPUT FILE -----------------------------------
SELECT FILE-OUT ASSIGN TO UT-S-FILEOUT.
SELECT FILE-ERR ASSIGN TO UT-S-FILEERR.
DATA DIVISION.
FILE SECTION.
FD FILE-IN
LABEL RECORDS ARE STANDARD
BLOCK CONTAINS 0 RECORDS
RECORD IS VARYING FROM 1 TO 32752 CHARACTERS
DEPENDING ON RDW
RECORDING MODE IS V
DATA RECORD IS FILE-IN-RECORD.
01 FILE-IN-RECORD.
05 FILLER OCCURS 1 TO 32752 DEPENDING ON RDW PIC X(01).
FD FILE-OUT
LABEL RECORDS ARE STANDARD
BLOCK CONTAINS 0 RECORDS
RECORD IS VARYING FROM 1 TO 32752 CHARACTERS
DEPENDING ON RDW
RECORDING MODE IS V
DATA RECORD IS FILE-OUT-RECORD.
01 FILE-OUT-RECORD.
05 FILLER OCCURS 1 TO 32752 DEPENDING ON RDW PIC X(01).
FD FILE-ERR
LABEL RECORDS ARE STANDARD
BLOCK CONTAINS 0 RECORDS
RECORD IS VARYING FROM 1 TO 32752 CHARACTERS
DEPENDING ON RDW
RECORDING MODE IS V
DATA RECORD IS FILE-ERR-RECORD.
01 FILE-ERR-RECORD.
05 FILLER OCCURS 1 TO 32752 DEPENDING ON RDW PIC X(01).
EJECT
****************************************
*******************
WORKING-STORAGE SECTION.
01 FILLER PIC X(33) VALUE
'** WORKING STORAGE BEGINS HERE **'.
****************************************
*******************
EJECT
****************************************
*******************
01 RDW PIC 9(4) COMP.
****************************************
*******************
01 SWITCHES.
05 INPUT-EOF-SW PIC X(01) VALUE 'N'.
88 INPUT-EOF VALUE 'Y'.
****************************************
*******************
01 WS-PARM-DATA.
05 FILLER PIC X(14).
05 WS-DELIMITER PIC X(01).
05 FILLER PIC X(16).
05 WS-DELIMITER-CNT PIC 9(03).
05 FILLER PIC X(46).
****************************************
*******************
01 FILLER PIC X(33) VALUE
'** MISCELLANEOUS BEGINS HERE =>'.
01 MISCELLAEOUS-AREA.
05 NUM-OF-DELIM PIC 9(04).
EJECT
****************************************
*******************
* HOLD INPUT AREA.
****************************************
*******************
****************************************
*******************
* COUNTERS ARE KEPT FOR STATISTICS, AUDIT, AND TRENDING
* PURPOSES.
****************************************
*******************
01 PROCESS-COUNTERS.
05 RECS-IN PIC S9(9) COMP VALUE ZERO.
05 OUT-RECS PIC S9(9) COMP VALUE ZERO.
05 ERR-RECS PIC S9(9) COMP VALUE ZERO.
EJECT
PROCEDURE DIVISION.
****************************************
*******************
*
****************************************
*******************
0000-MAINLINE.
****************************************
*******************
* MAIN PROCESSING SEQUENCE.
****************************************
*******************
DISPLAY '=========== VARSRCH STARTING ============'.
PERFORM 1000-INITIALIZE.
PERFORM 2000-PROCESS-INPUT
UNTIL INPUT-EOF.
PERFORM 9900-DONE.
EJECT
1000-INITIALIZE.
****************************************
*******************
* INITIALIZE WS AND READ FIRST RECORD
****************************************
*******************
MOVE 'N' TO INPUT-EOF-SW.
OPEN INPUT FILE-IN.
OPEN OUTPUT FILE-OUT
FILE-ERR.
ACCEPT WS-PARM-DATA.
PERFORM 8000-READ-INPUT.
IF INPUT-EOF
DISPLAY 'INPUT FILE EMPTY'
END-IF.
EJECT
2000-PROCESS-INPUT.
****************************************
*******************
* PROCESS RECORDS.
****************************************
*******************
MOVE 0 TO NUM-OF-DELIM.
INSPECT FILE-IN-RECORD
TALLYING NUM-OF-DELIM
FOR ALL WS-DELIMITER.
IF NUM-OF-DELIM = WS-DELIMITER-CNT
PERFORM 8100-WRITE-OK-RECORD
ELSE
PERFORM 8200-WRITE-ERR-RECORD
END-IF.
PERFORM 8000-READ-INPUT.
8000-READ-INPUT.
****************************************
*******************
* READ INPUT RECORDS
****************************************
*******************
MOVE SPACES TO FILE-IN-RECORD.
READ FILE-IN
AT END
MOVE 'Y' TO INPUT-EOF-SW
NOT AT END
ADD +1 TO RECS-IN
END-READ.
8100-WRITE-OK-RECORD.
****************************************
*******************
*
****************************************
*******************
MOVE FILE-IN-RECORD TO FILE-OUT-RECORD.
WRITE FILE-OUT-RECORD.
ADD +1 TO OUT-RECS.
8200-WRITE-ERR-RECORD.
****************************************
*******************
*
****************************************
*******************
MOVE FILE-IN-RECORD TO FILE-ERR-RECORD.
WRITE FILE-ERR-RECORD.
ADD +1 TO ERR-RECS.
9900-DONE.
****************************************
*******************
* PROGRAM WRAP UP.
****************************************
*******************
CLOSE FILE-IN
FILE-OUT.
DISPLAY 'INPUT RECORDS: ' RECS-IN.
DISPLAY 'GOOD RECORDS: ' OUT-RECS.
DISPLAY 'ERRORS FOUND: ' ERR-RECS.
GOBACK.
|
|
|
|
|