First I am searching the all the customer data from the database and keeping to arrays.
Based on the occurance of WS-CUST-ORDERS and WS-CUST-Gifts the count1 and count 2 will be set correspondingly.
For example let us assume count1 = 20, count2 = 15.
Here the array size is defined. So array will be created. After this process
I want to MOVE/SET the blanks to the array element if one field in element of array is satisfies the condition.
Move 1 to INDicator1
PERFORM VARYING INDicator1 FROM 1 BY 1 UNTIL
INDicator1 > count1
IF product-number OF ws-data1(INDicator1) < 101
move/SET BLANKS to ws-data1(INDicator1) <<--- This is want I want (This is similar to shrinking the array)
Add 1 to reduce-count1
SUBTRACT reduce-count1 FROM count1
Could you please let me know how reset the count of the array occurance?
Joined: 06 Jun 2008 Posts: 8220 Location: Dubuque, Iowa, USA
I want to resize the araay occurance and move BLANKS to array element.
Most NORMAL programmers would do one or the other. If you reduce the count1 variable (in your posted code), the last element of the table (or array) is the one going away -- period. If you move spaces to the seventh element of the array, then reduce the array count by one, you've actually wiped out values in two array elements -- number 7 and number 20, based upon your example.
Based upon your demonstrated level of expertise, you would be far, far, far, far better off getting rid of the OCCURS DEPENDING ON clasues and just use fixed-size tables.
Guys, thanks for responding...
Every every customer that count1 and count2 differs so I should use the DEPENING on clause and also in order to not to not to waste the memory also by defining the maximum size.
Can we resize the array(ODO once it's declared) and move BLANKS to a particular array item?
Joined: 06 Jun 2008 Posts: 8220 Location: Dubuque, Iowa, USA
Be aware that if your array is defined in WORKING-STORAGE, you will save a grand total of ZERO bytes by using OCCURS DEPENDING ON. COBOL allocates the maximum possible size for the array in WORKING-STORAGE so using OCCURS versus OCCURS DEPENDING ON won't impact the memory used.
If the array is defined as part of an FD, and the DEPENDING ON variables are not part of that same FD definition, you are BEGGING for S0C4 storage abends in the future. Unlike WORKING-STORAGE, OCCURS DEPENDING ON arrays in an FD or LINKAGE SECTION will actually vary in size and hence you must be very, very, very careful when using such variables or you attempt to access storage you are not allowed to and an abend occurs.
Finally, why are you wanting to not "waste" memory? If your system is anywhere near current, your program probably has 2 GB (or more) of memory to use so there's not much chance of your "wasted" memory causing any problems.
Even after a few explanations, it is still hard to understand what you want to do...
Even if you define an OCCURS DEPENDING ON table, the amount of memory used in the program will stay the same (allocated to the maximum value).
There will be no "shrinking".
The second ODO will always be located at the same place, whether there are 1, 2, 3 or 20 or 99 occurrences in the first ODO.
I'm also at a loss as to what is actually required.
I haven't used multiple ODOs with the newest compilers, but this is how it used to work. Well, not a full explanation, but of the storage "movements".
05 SOME-STUFF-OF-ALL-SORTS-OF-TYPES PIC X(300).
05 NUMBER-OF-CUSOMTER-ORDERS COMP PIC S9(4).
05 NUMBER-OF-CUSTOMER-GIFTS COMP PIC S9(4).
10 FILLER OCCURS 0 TO 100 TIMES
DEPENDING ON NUMBER-OF-CUSTOMER-ORDERS.
15 CUSTOMER-ORDER-STUFF PIC X(100).
10 FILLER OCCURS 0 TO 100 TIMES
DEPENDING ON NUMBER-OF-CUSTOMER-GIFTS.
15 CUSTOMER-GIFT-STUFF PIC X(100).
Explanation holds(held) whething in file, working-storage or linkage sections, unless otherwise stated.
SAY-WE-HAVE-A-FILE-RECORD, CUSTOMER-ORDERS and CUSTOMER-GIFTS are all "variable length" group items. Look at the map of your data from the compiler, and you'll see they appear differently than other items.
Point 1, "more difficult" (until you know how) to locate in a dump.
The start position of CUSTOMER-GIFTS depends on the length of CUSTOMER-ORDERS.
Point 2, to find data from a dump which for items after a variable length field is again more difficult. See Point 1.
Every time the value of NUMBER-OF-CUSOMTER-ORDERS changes, the length of SAY-WE-HAVE-A-FILE-RECORD and CUSTOMER-ORDERS and the start position of CUSTOMER-GIFTS are all automatically re-calculated.
Every time the value of NUMBER-OF-CUSOMTER-GIFTS changes, the length of SAY-WE-HAVE-A-FILE-RECORD and CUSTOMER-GIFTS is automatically re-calculated.
Point 3, there is a lot of processing going on "under the covers" every time you MOVE ZERO or ADD +1 or whatever to the counts.
In working-storage, the amount of storage allocated is the maximum amount of entries specified (in this case 100 on each ODO). This cannot be increased or decreased at run-time. The amount of storage is unchanged. The part of that storage which is used is what is variable.
Point 4, no storage is saved in your program by using ODO.
In the file section, the ODOs are what makes those particular records variable in length. Cobol reads the record, and then will calculate the start positions and lengths of the three variable-length items. Note, if there is inconsistency between the counters and the record-length, then your data is screwed as soon as you read the record.
Point 5, for variable length items in a file, the counter(s) must be included in the file, and before the definition of the variable part.
In the linkage section, no storage is defined, so no storage is saved.
There are assorted "advanced" techniques for using ODO in the linkage section, but I don't think it appropriate to expand on that for this TS at the moment.
Say NUMBER-OF-CUSTOMER-ORDERS and NUMBER-OF-CUSTOMER-GIFTS are set to one and the fields CUSTOMER-ORDER-STUFF and CUSTOMER-GIFT-STUFF are populated appropriately.
Now, add one to NUMBER-OF-CUSTOMER-ORDERS.
SAY-WE-HAVE-A-FILE-RECORD and CUSTOMER-ORDERS have their lengths re-calculated to reflect the new value of NUMBER-OF-CUSTOMER-ORDERS. The start position of CUSTOMER-GIFTS is recalculated.
What happens to the data already in CUSTOMER-GIFTS?
Nothing unless you make it happen yourself, and, since it is no-longer pointed-to by CUSTOMER-GIFTS, you have to have done it already. If you do nothing, you are just about to overwrite it with the 2nd occurence of CUSTOMER-ORDERS. CUSTOMER-GIFTS now points to some rubbish, possibily a valid-looking previous entry (worst case) or possibly just rubbish (preferable, as easier to spot afterwards).
Point 6, although lengths and start positions are automatically calculated where necessary, the data itself is never moved unless you do it.
I can go on, but I think this is enough.
If you still want to use ODO even, let alone multiple ODO's, then do a lot of work to absolutely understand them first, and ensure that your development and support colleagues fully understand them as well.
Otherwise, just consider your file and system as trash waiting to happen.
The Orders and Gifts arrays depend on count 1 and count 2. These are not in the record and MUST be for you to create the varying record you want.
Some of our files use this approach to save more than 95% of the space required to store the data in fixed format. Well, the new layouts do - the originals were fixed-length so no one would have to think (analysts or programmers). Now that this is standard, it is quite clear to everyone.
In a "sparsely populated" table, the savings can be very significant. With "not many records", the question is So What?
There are other techniques, like have two records, each with one ODO.
To proceed with the example here - once it has the counts on the record itself - I'd suggest writing a module to do the i/o for the file. This module can "normalise" the odos on the way in, and odo them on the way out.
All the programs using the data have a definition of the record with no odos, no added complexity to worry about
One more shot and then I'm done unless Anil returns.
I've been checking, and this is from the Enterprise Cobol Programming Guide, Appendix B
When you increment the value of the ODO object and add an element to a table,
you can inadvertently overlay the variably located data items that follow the table.
To avoid this type of error, do these steps:
1. Save the variably located data items that follow the table in another data area.
2. Increment the value of the ODO object.
3. Move data into the new table element (if needed).
4. Restore the variably located data items from the data area where you saved
The lengths are not re-calculated every time the ODO object (name on the DEPENDING ON) changes like I said they used to be, but when an item affected by a variable-length table is referenced. This would be important when looking at a dump. The lengths present in the dump would actually be the lengths when it was last necessary to calculate them, not the lengths reflected by the current value of the ODO item.
From the Language Reference:
The object of the OCCURS DEPENDING ON clause must not occupy any
storage position within the range of the table (that is, any storage position
from the first character position in the table through the last character
position in the table).
This might be a clue as to why TS thought the counters should not be in his 01. A guess. If correct, it is a misunderstanding of the above, which is saying that the ODO object must not be within the range of the storage occupied by the OCCURS.
This is confusing, I have to say, as it would be difficult to achieve.
At the time that the group item, or any data item that contains a subordinate
OCCURS DEPENDING ON item or that follows but is not subordinate to the
OCCURS DEPENDING ON item, is referenced, the value of the object of the
OCCURS DEPENDING ON clause must fall within the range integer-1 through
The implication here is that there is some sort of "bounds" checking. This did not used to be the case, and I guess only by looking at the pseudo-assembler generated would be know if this is the case or not now.
Compiler option SSRANGE will apply to OCCURS DEPENDING ON, but that is seperate from the above.