Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Control break construct 3

Status
Not open for further replies.

slade

Programmer
Jun 11, 2000
823
US
This problem represents a major construct in business programming, so the time you devote to this is well spent.

Input data is usually presented to a pgm in some sort sequence, e.g:
Code:
file
  acct#1
    product1
      date1
      date2
      etc.
    product2
      date1
      date3
      date4
      etc.
  acct#2
    product1
      date3
      etc.

So you have a file level, an acct level, a product level and a date level. These levels are important because they are used to process the breaks in the program.

The general form is as follows:

perform level n until level n-1 is finished

For the file described above the perform sequence would be:

Code:
In the mainline you code: 
   perform acct-lev until file-is-finished
In the acct-lev you code: 
   perform prod-lev until acct-is-finished
In the prod-lev you code: 
   perform date-lev until prod-is-finished
In the date-lev you code: 
   perform detl-lev until date-is-finished
In the detl-lev you code: 
   Aggregate all detl recs; aggregate all level totals; etc.
   Read next I/P detl rec

OK now lets flesh this out. How do we determine when each level is finished? One way is to expand the function of the read routine to do this:

7000-read-rtn.
    move ws-ip-rec to ws-ip-prev
    read ip-file into ws-ip-rec 
      at end set ip-eof to true 
         move high-values to ws-ip-rec  
     not at end add +1 to ws-ip-cnt
   end-read
   perform 7010-set-breaks
   .
7010-set-breaks.
    if curr-acct not = prev-acct
       set acct-is-finished to true
       set prod-is-finished to true 
       set date-is-finished to true
    end-if
    if curr-prod not = prev-prod
       set prod-is-finished to true
       set date-is-finished to true
    end-if
    if curr-date not = prev-date
       set date-is-finished to true
    end-if

Second question: We haven't read any data yet, how can we test if the levels are finished? We do a priming read outside of the loops, usually in the init or mainline section. After this read, if EOF is detected, an error msg is displayed and the pgm is usually exited because no input data has been provided.

How can the loops be executed if the "is-finished" switch has already been set? They can't. So, we reset the switch before executing each lower level:
Code:
0000-main-line.
    perform 7000-read-ip
    if ip-eof
       display error msg
       stop run
    end-if 
    perform acct-lev until file-is-finished
    perform 6900-print-rpt-end
    perform 9000-end-it
    stop run
    .
acct-lev.
    perform 6000-print-rpt-heads
    set reset-acct-sw to true 
    perform prod-lev until acct-is-finished
    perform 6100-print-acct-tots 
    zero tots, etc. 
    .
prod-lev.
    set reset-prod-sw to true 
    perform date-lev until prod-is-finished
    . 
date-lev.
    set reset-date-sw to true 
    perform detl-lev until date-is-finished
    . 
detl-lev.
    move ip data to rpt-line or whatever
    perform 7000-read-ip
    .

Note that the form of each level except the detail level is:

Do pre-break stuff (print rpt heads, save data that won't be available after return from perform, etc.)

Reset the level switch.

Perform the next lower level.

Do post-break stuff (strike and/or zero or roll totals, write total recs, etc.)

At the detail level process the previous rec and read the next rec before exiting.

At entry to each level the record has already been read and is ready for processing.

Here's what a break switch would look like:
Code:
    01 ws-break-switches.
       05 ws-acct-sw                 pic x(001).
          88 acct-is-finished            value 'f'. 
          88 reset-acct-sw               value 'r'. 

This example has 2 break levels so your performs would look like:

0000-mainline.
    . 
    . 
    .
    perform 8000-init
    perform 7000-read-ip 
    if ip-eof 
       display 'no data in i/p file' 
       stop run 
    end-if
    preform 1000-process-codes until ip-eof
    . 
    . 
    . 
1000-process-codes.
    set reset-code-sw to true
    perform 1100-process-detl until code-is-finished
    .
1100-process-detl.
    collect data, etc.
    perform 7000-read-ip
    .


You have to ask: What do I do before the breaks; what do I do after. The answers to these questions may differ from project to project, but the basic concept: the cascading perform process is constant.

This is one of the two major batch processing constructs in DP. The other is the file match. When I get some time I'll post something on this.

Let me know if this helps or if you have any questions.

Jack
 
Hi,

With the level-break we also use a sort-mark. It is defined like this:

01 SORT-MARK VALUE LOW-VALUE.
03 SM-LEVEL-3.
05 SM-LEVEL-2.
07 SM-LEVEL-1
09 SM-END-OF-FILE PIC X.
07 SM-KEY-2 PIC .....
05 SM-KEY-3 PIC .....

You define a look-alike definition for the old key, belonging to the previous record.

In a read routine, you move SORT-MARK to SORT-MARK-OLD. You fill in the keys. In the at-end situation, you fill the end-of file thing with a '1'.

Each level can be tested now with one condition which contains the whole structure. So you change the structure above depending on the amount of levels and the fields which belong to those levels.

Regards,

Crox
 
Hi Crox,

I'm having a little trouble understanding the sort-mark concept. Could you provide an expanded example using code or pseudo code?

Thanx, Jack.
 
Here it is....

WORKING-STORAGE SECTION.


01 SORT-MARK VALUE LOW-VALUE.
03 SM-LEVEL-3.
05 SM-LEVEL-2.
07 SM-LEVEL-1
09 SM-END-OF-FILE PIC X.
07 SM-KEY-2 PIC .....
05 SM-KEY-3 PIC .....


01 SORT-MARK-OLD.
03 SO-LEVEL-3.
05 SO-LEVEL-2.
07 SO-LEVEL-1
09 SO-END-OF-FILE PIC X.
07 SO-KEY-2 PIC .....
05 SO-KEY-3 PIC .....



PROCEDURE DIVISION.
MAIN SECTION.
MAI-01.
PERFORM READ-FILE.
PERFORM UNTIL SM-END-OF-FILE = "1"
.... HIGHEST LEVEL CODING
PERFORM WITH TEST AFTER UNTIL SM-LEVEL-2 NOT = SO-LEVEL-2
.... ONE-LEVEL-LOWER CODING
PERFORM WITH TEST AFTER UNTIL SM-LEVEL-3 NOT = SO-LEVEL-3
...... AGAIN ONE LEVEL LOWER CODING
PERFORM READ-FILE
END-PERFORM
END-PERFORM
END-PERFORM
.
MAI-99.
EXIT.


READ-FILE SECTION.
REA-01.
MOVE SORT-MARK TO SORT-MARK-OLD.
READ ......
AT END
MOVE "1" TO SM-END-OF-FILE
NOT AT END
MOVE FI-KEY-2 TO SM-KEY-2
MOVE FI-KEY-3 TO SM-KEY-3
END-READ.
REA-99.
EXIT.


I hope this is a little bit understandable.

 
Hi Crox,

I think I've got it now. One ques though. I may not be reading the code correctly, but what will happen if level3 doesn't change, but level2 does? Will the 1st level2 get the level3 recs intended for the 2nd level2 as well as its own, with the 2nd level2 getting bypassed?

I don't know how closely our code parallels each to the other, but that's why I coded my set break pgraph the way I did, and decided to use a switch to signal the break (in addition, I liked the documentary function of the switch).

Jack

 
Hi,

every time you read, you update all your levels.

So in one test you know it all.

If level 2 changes, the test for level 3 changes also!

Try it out, we - in Holland - the ones whom are originaly trained by Volmac, now called Cap Gemini, we use this idea for more than 20 years.

It is very efficient and it is a good concept.

It is also very nice to use if you are doing a merge also called a balance-line.

I hope this helps.

Regards,

Crox

 
Hi Crox,

OK, now I see it. The sort-levels are defined in REVERSE order, from lev3 DOWN to lev1.

Thanx Jack.
 
Jack,

that way of coding a sort mark is allso known as a "Swallow's Tail", because of the shape.

Crox,

I - in Holland - was introduced to this concept by Volmac / Cap Volmac / Cap Gemini / ... [fill in] as well. It indeed IS a small world !

Regards,
Ronald.
 
Hi,

What amazes me is that, judging by the code presented at this site and others, apparently, this stuff isn't taught in the schools.

I guess, the instructors think that one approach is as valid as another. While I accept the fact that variations do exist, and come with their own set of advantages and disses, a common approach could go a long way in reducing the maintenance burden and compressing mean time to delivery for projects.
 
Jack,

my guess is that teaching COBOL in schools etc. focuses mainly on understanding the language and building some practice programs to get the hang of it. In a business environment however, robustness, efficiency and ease of maintenance are far more pressing factors, and that's where a structured programming technique (off course, there are more !) really becomes important.

Regards,
Ronald.
 
Hi Ronald,

I'm sure you're right, but my point is that control breaks and file matching account for a vast majority of the batch programs written. Because of that, these two techniques should be part of the fundamentals taught for any language used in a batch environment. BTW, as you know, these concepts are occasionally used in an on-line environment too.

I've been in this business for a long time and I've only come across one program that used one of the control break techniques presented in this thread. And a handful that used an acceptable file matching process. It'a amazing to think that these concepts were being discussed as early as the mid 60s.

Regards, Jack.
 
Hi,

it is not that strange. Batch programs are less build today. In the early days, you had only batch programs. Nowadays you see most of the time on-line programs. Also the 24 * 7 concepts makes it less easy to do batch programming.

In on-line programming environments, huge amounts of transactions are sometimes build in a two-way usable concept: usable in batch and also on-line. But if you use the transaction concept in batch, it is not easy to have profit of the good-old-batch things linke balance line and level break, because the programs are build to handle just one record at the time, getting the needed information at random, using caching to get a better performance.

Architectural concepts whom work very differently from the old ones can provide good performance in these cases.

But it is not ease to explain all of this in this forum concept.

Regards,

Crox
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top