Re: Sometimes I just wonder, "WHY?!"
Posted in 1994
> An alternative might be to use global variables for running totals, etc., and > initialize them outside of the REPORT module. Can anyone comment > definitively on that idea? > > Walt. A real problem with GLOBALS is if you do any significant work outside the REPORT routing. One of the biggest problems is that when you write a REPORT routine, you tend to think of program flow linearly, but that's not how a REPORT works. Things tend to fire on a whim in a report. Here's a quick bad example: GLOBALS DEFINE run_tot SMALLINT END GLOBALS MAIN DEFINE i,j SMALLINT START REPORT r1 FOR i = 1 TO 3 LET run_tot = 0 FOR j = 1 TO 3 LET run_tot = run_tot + j OUTPUT TO REPORT r1 (i,j) END FOR END FOR FINISH REPORT r1 END MAIN REPORT r1(i,j) DEFINE i,j SMALLINT OUTPUT REPORT TO "r1.out" ORDER EXTERNAL BY i FORMAT ON EVERY ROw PRINT "i=", i using "###", " j=", j using "###" AFTER GROUP OF i PRINT "run_tot = ",run_tot END REPORT At first glance, we're adding up and maintaining run_tot in a fairly obvious manner. Summming it up for each line. However, if you look at the report: i= 1 j= 1 i= 1 j= 2 i= 1 j= 3 run_tot = 1 i= 2 j= 1 i= 2 j= 2 i= 2 j= 3 run_tot = 1 i= 3 j= 1 i= 3 j= 2 i= 3 j= 3 run_tot = 6 You'll notice that it's not quite right. Only the last run_tot is correct. This is because the report is out of phase with the data. The AFTER GROUP doesn't fire until the row has changed (otherwise, how can it know?), and by that time run_tot has been reset. This is a fun thing to play with in large reports that you've never seen before. A great head-banging experience. You can use global variables, but just be cautious. Luck, Will (villy@collinscomp.com)