Control Break Programs, Version 3
August 11, 2004 Dear Readers
Faithful reader Doug Eckersley sent me an example of how he would write a control break program like the one I presented in the May 12 issue. Doug mentions two things he likes about his method. First, it uses subroutines, which makes the program modular, and, second, he uses no hold fields. Here’s his code.
D K1 C 1 D K2 C 2 D K3 C 3 D Key E DS extname(SALES:*key) Begsr $Main; NewPage = *on; CompanyTotal = 0; Except REPORTHEADER; Setll *start SALES; Read SALES; Dow not %eof(SALES); Exsr $Level1; Read SALES; Enddo; Except REPORTFOOTER; Endsr; Begsr $Level1; // Store StoreTotal = 0; Except STOREHDR; Dow not %eof(SALES); Exsr $Level2; Reade %kds(Key:K1) SALES; Enddo; Except STOREFOOTER; CompanyTotal += StoreTotal; Setgt %kds(Key:K1) SALES; Endsr; Begsr $Level2 // Department DepartmentTotal = 0; Except DEPTHDR; Dow not %eof(SALES); Exsr $Level3; Reade %kds(Key:K2) SALES; Enddo; Except DEPTFOOTER; StoreTotal += DepartmentTotal; Setgt %kds(Key:K2) SALES; Endsr; Begsr $Level3; // SalesPerson SalesPersonTotal = 0; Except SPHDR; Dow not %eof(SALES); Exsr $Detail; Reade %kds(Key:K3) SALES; Enddo; Except SPFOOTER; DepartmentTotal += SalesPersonTotal; Setgt %kds(Key:K3) SALES; Endsr; Begsr $Detail; Exsr $NewPage Except DETAIL; SalesPersonTotal += SaleAmount; Endsr;
I’d like to add an observation or three. It’s true that Doug’s method doesn’t require hold fields, but it does require random I/O (that is, SETGT), which may hamper performance. The fact that Doug uses a keyed file means that he has to have an access path over the data, at least at compile time. Also, this method doesn’t work with embedded SQL.
But I sound more critical than I mean to be. Both Doug and Mike (in the July 28 issue) have presented techniques that are well thought out, and I am grateful to have learned other ways to handle a common task.
–Ted