I inherited some code that hard-codes delimiter values as 1-byte hex-code representations in a group of literal values. The literal values are hard-coded in the UNSTRING statement below within the "DELIMITED BY" clause (see example below). The code works fine, but often new vendors supplying new input files use a different delimiter. Everytime a new delimiter value is encountered, the code must be updated by adding in a new literal value for that new delimiter and adding it to the "DELIMITED BY" clause. Not very flexible.
I came up with the bright idea to make the delimiter values file or table driven (so far so good).
We decided to go with an input file where heach line would have a 1 byte field for the hex-character value of the delimiter, and a several byte field for some sort of description value. The file could hold 1 to many delimiter values.
The thought was to load the delimiter values into an internal table of some sort indexed by integer (x).
1. Problem #1: Can I even build a dynamic table in COBOL that will only contain the number of rows that there are file entries for? COBOL doesn't seem to like allocating things at runtime - only at compiletime - meaning creating some static table of xxx number of rows.
2. Problem #2: I've got some table of 1 - n number of rows. Each indexed by some integer value (x). How do I replace the hard-coded literals in the "DELIMITED BY" clause using the indexed table rows? Would it be possible to dynamically build the entire UNSTRING statment so that the correct number of indexed table row values get created with their corresponding "OR" statments in the "DELIMITED BY" clause?
Seems like way too much effort to replace a few hard coded values in a statement dynamically over going in and simply adding them to the code using the existing process...
Any thoughts or suggestions?
DELIMITED BY WS05-LITERAL-ASTERISK <=== These literals are currently hard-coded in the program
OR WS05-LITERAL-TILDE representing the delimiters used in our input files today.
OR WS05-LITERAL-CARRIAGE-RETN New delimiter values from new vendors occur regularly.
. . .
. . .
TALLYING IN WS06-PARSED-COUNT
MOVE WS06-THIS-ONE TO WS06-HOLD-FIELD
. . .
. . .
Pinned topic Dynamically building "DELIMITED BY" list in UNSTRING statment?
Answered question This question has been answered.
Unanswered question This question has not been answered yet.
Updated on 2011-10-21T18:13:54Z at 2011-10-21T18:13:54Z by SystemAdmin
SystemAdmin 110000D4XK403 Posts
Re: Dynamically building "DELIMITED BY" list in UNSTRING statment?2011-10-21T18:13:54ZThis is the accepted answer. This is the accepted answer.Answer to problem #1: If you are using IBM Enterprise COBOL, you can allocate memory with CEEGTST and use Occurs Depending On to have a dynamically sized table with only the number of rows required. I'm not sure on which operating systems CEEGTST is available, z/OS at least I'm sure.
Most programmers just use a static table in Working-Storage that is sized to be large enough to handle all the elements they will ever need in a particular situation. If your situation is individual hex bytes being used as delimiters, a 255 element table is likely to be sufficient.
One possible answer to problem #2: If it were me, I would read in the hex values from a file, placing them in my Working-Storage DLIM-TBL table, incrementing NB-ENTRIES for each value read...
01 WORK-AREAS. 05 NB-ENTRIES PIC 9(003) COMP-3 VALUE 0. 05 THE-ONE-DLIM PIC X(255) VALUE HIGH-VALUES. 05 DLIM. 10 DLIM-TBL OCCURS 255 PIC X.
...then replace all those different possible delimiter values with one value I specify...
INSPECT WS06-SOME-INPUT-REC CONVERTING DLIM(1:NB-ENTRIES) TO THE-ONE-DLIM(1:NB-ENTRIES)
...then do the UNSTRING with the DELIMITED phrase specifying the one value I specified...
UNSTRING WS06-SOME-INPUT-REC DELIMITED HIGH-VALUES INTO ...