|
Home > Archive > Programming with dBASE > December 2005 > Nested loops not looping as expected
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Nested loops not looping as expected
|
|
| Pieter van Heerden 2005-12-28, 11:23 am |
| This could link to my experience with the FOR ... ENDFOR construct posted earlier today.
I have three nested DO WHILE loops. The outer and inner loops work as expected, but the middle loop does not loop....
In the following code, loop one runs through a list of weather stations, extrated from Table1. Loop 2 extracts monthly data out of a second data table related to the station specified in Loop 1. A third data table that provides for daily data, needs to
be expanded out of the data of table 2. The loops were designed to do this.
The problem is that while the outer and inner loops run as expected, the middle loop does not loop at all, a once-only through is what happens to this loop.
Could this problem be related to what we had under certain circumstances in the dBase DOS days with the SCAN ... ENDSCAN construct where nesting was not allowed under certain circumstances? If so, could a workaround be a nested FOR ... ENDFOR construct?
I could not find any mention of nesting being a problem with DO WHILE or DO UNTIL constructs in dBase for Windows.
// Array with days ot the month for the 12 months
adays = & #123;31,28,31,30,31,
30,31,31,30,31,30,31
}
// Query1: get a list of (weather) station names for outer loop
q1 = new query()
q1.database = d
q1.sql = "select * from et02unique"
q1.active = true
q1r = q1.rowset
q1f = q1.rowset.fields
// Query3: data table to be expanded from the monthly data table (query2)
// so that daily values could be enterred
q3 = new query()
q3.database = d
q3.sql = "select * from et03"
q3.active = true
q3r = q3.rowset
q3f = q3.rowset.fields
q1r.first()
// Outer loop: cycle through stations
do while not q1r.endofset
// Query2: extract only monthly data related to the specific station of Query1
q2 = new query()
q2.database = d
q2.sql = "select * from et02 where stationno = :stationno"
q2.params["stationno"] := q1f["stationno"].value
q2.active = true
q2r = q2.rowset
q2f = q2.rowset.fields
q2r.first()
// Middle loop: cylce through once-a-month entries
do while not q2r.endofset
i = 1
// Inner loop: cycle through days of the month to build and populate a
// daily data table for eventual daily entries
// Once-a-month entries of query2 will also be incorporated into this table
do while i <= adays[month(q2f["rdate"].value)]
q3r.beginappend()
q3f["stationno"].value := q1f["stationno"].value
q3f["rdate"].value := q2f["rdate"].value - ; int(adays[month(q2f["rdate"].value)] / 2) + i
i += 1
// Print output line for checking results during development
? q1f["stationno"].value, q2f["rdate"].value, q3f["rdate"].value
enddo
q2r.next()
enddo
q2.active = false
q1r.next()
enddo
q3.active = false
q1.active = false
| |
| Robert Bravery 2005-12-28, 1:23 pm |
| Hi,
I suspect that you are getting to the endofset. the qr2.next() probably
moves the rowset to endofset, the begining of the loop then evaluates as
false and exits. To thest this out, put a q2e.next(0). You should then get
an endless loop
Robert
"Pieter van Heerden" <psvh@mweb.co.za> wrote in message
news:l3Coom8CGHA.1488@news-server...
> This could link to my experience with the FOR ... ENDFOR construct posted
earlier today.
>
> I have three nested DO WHILE loops. The outer and inner loops work as
expected, but the middle loop does not loop....
>
> In the following code, loop one runs through a list of weather stations,
extrated from Table1. Loop 2 extracts monthly data out of a second data
table related to the station specified in Loop 1. A third data table that
provides for daily data, needs to be expanded out of the data of table 2.
The loops were designed to do this.
>
> The problem is that while the outer and inner loops run as expected, the
middle loop does not loop at all, a once-only through is what happens to
this loop.
>
> Could this problem be related to what we had under certain circumstances
in the dBase DOS days with the SCAN ... ENDSCAN construct where nesting was
not allowed under certain circumstances? If so, could a workaround be a
nested FOR ... ENDFOR construct?
>
> I could not find any mention of nesting being a problem with DO WHILE or
DO UNTIL constructs in dBase for Windows.
>
>
> // Array with days ot the month for the 12 months
> adays = & #123;31,28,31,30,31,
30,31,31,30,31,30,31
}
> // Query1: get a list of (weather) station names for outer loop
> q1 = new query()
> q1.database = d
> q1.sql = "select * from et02unique"
> q1.active = true
> q1r = q1.rowset
> q1f = q1.rowset.fields
> // Query3: data table to be expanded from the monthly data table (query2)
> // so that daily values could be enterred
> q3 = new query()
> q3.database = d
> q3.sql = "select * from et03"
> q3.active = true
> q3r = q3.rowset
> q3f = q3.rowset.fields
> q1r.first()
> // Outer loop: cycle through stations
> do while not q1r.endofset
> // Query2: extract only monthly data related to the specific station of
Query1
> q2 = new query()
> q2.database = d
> q2.sql = "select * from et02 where stationno = :stationno"
> q2.params["stationno"] := q1f["stationno"].value
> q2.active = true
> q2r = q2.rowset
> q2f = q2.rowset.fields
> q2r.first()
> // Middle loop: cylce through once-a-month entries
> do while not q2r.endofset
> i = 1
> // Inner loop: cycle through days of the month to build and populate
a
> // daily data table for eventual daily entries
> // Once-a-month entries of query2 will also be incorporated into
this table
> do while i <= adays[month(q2f["rdate"].value)]
> q3r.beginappend()
> q3f["stationno"].value := q1f["stationno"].value
> q3f["rdate"].value := q2f["rdate"].value - ;
int(adays[month(q2f["rdate"].value)] / 2) + i
> i += 1
> // Print output line for checking results during development
> ? q1f["stationno"].value, q2f["rdate"].value, q3f["rdate"].value
> enddo
> q2r.next()
> enddo
> q2.active = false
> q1r.next()
> enddo
> q3.active = false
> q1.active = false
>
>
>
| |
| Pieter van Heerden 2005-12-31, 3:23 am |
| Size does count!
The outer loop of the nested loops has a rowset with about 5000 records, no problem there. The loop that gives problems is a subset out of a table with 1.75 million records and 100 Mb in size. The problem seems to be that the loop does not happen becaus
e the result of the sql statement is a solitary record, instead of all the record required. The problem is not working with a subset, the biggest of which I work with is aboutr 9000 records, but getting the subset out of the table!!!! Is this normal b
ehaviour?
I have reduced the table size by splitting the main table to about half its size, and now the system runs as expected!
One could apparently extract all the records specified by the sql statement by linking an indexname to the rowset, but then funnily enough the rowpointer of the outside loop jumps to the last row of the table, even though this row might not be part of the
rowset = Explain that one?!
One observation is that if the table is small enough to show "rownumber/total rows" on the status bar, then the problem encountered does not appear. If the status bar shows only "rownumber", we seem to be on the road to problems with nested loops.
This leads to the supposition that, irrespective of program capacities, computer capacity could play a major role in terms of what could be handled. In my case: Penium II, 1.8MHz, 512 RAM (259 free), 58GB free hard disc space, 2Gb virtual memory and ru
nning under Windows XP, upgraded with service pack 2. Is this not enough to manage a file of 100Mb?
Running through the big table without nested loops, gives no problems, behaviour is as expected.
I have tried "Do while ... enddo", "Do ... until" and "For ... next" loops as part of the nested story, with equal lack of success.
Comments/advice?
Pieter van Heerden Wrote:
> This could link to my experience with the FOR ... ENDFOR construct posted earlier today.
>
> I have three nested DO WHILE loops. The outer and inner loops work as expected, but the middle loop does not loop....
>
> In the following code, loop one runs through a list of weather stations, extrated from Table1. Loop 2 extracts monthly data out of a second data table related to the station specified in Loop 1. A third data table that provides for daily data, needs t
o be expanded out of the data of table 2. The loops were designed to do this.
>
> The problem is that while the outer and inner loops run as expected, the middle loop does not loop at all, a once-only through is what happens to this loop.
>
> Could this problem be related to what we had under certain circumstances in the dBase DOS days with the SCAN ... ENDSCAN construct where nesting was not allowed under certain circumstances? If so, could a workaround be a nested FOR ... ENDFOR construct
?
>
> I could not find any mention of nesting being a problem with DO WHILE or DO UNTIL constructs in dBase for Windows.
>
>
> // Array with days ot the month for the 12 months
> adays = & #123;31,28,31,30,31,
30,31,31,30,31,30,31
}
> // Query1: get a list of (weather) station names for outer loop
> q1 = new query()
> q1.database = d
> q1.sql = "select * from et02unique"
> q1.active = true
> q1r = q1.rowset
> q1f = q1.rowset.fields
> // Query3: data table to be expanded from the monthly data table (query2)
> // so that daily values could be enterred
> q3 = new query()
> q3.database = d
> q3.sql = "select * from et03"
> q3.active = true
> q3r = q3.rowset
> q3f = q3.rowset.fields
> q1r.first()
> // Outer loop: cycle through stations
> do while not q1r.endofset
> // Query2: extract only monthly data related to the specific station of Query1
> q2 = new query()
> q2.database = d
> q2.sql = "select * from et02 where stationno = :stationno"
> q2.params["stationno"] := q1f["stationno"].value
> q2.active = true
> q2r = q2.rowset
> q2f = q2.rowset.fields
> q2r.first()
> // Middle loop: cylce through once-a-month entries
> do while not q2r.endofset
> i = 1
> // Inner loop: cycle through days of the month to build and populate a
> // daily data table for eventual daily entries
> // Once-a-month entries of query2 will also be incorporated into this table
> do while i <= adays[month(q2f["rdate"].value)]
> q3r.beginappend()
> q3f["stationno"].value := q1f["stationno"].value
> q3f["rdate"].value := q2f["rdate"].value - ; int(adays[month(q2f["rdate"].value)] / 2) + i
> i += 1
> // Print output line for checking results during development
> ? q1f["stationno"].value, q2f["rdate"].value, q3f["rdate"].value
> enddo
> q2r.next()
> enddo
> q2.active = false
> q1r.next()
> enddo
> q3.active = false
> q1.active = false
>
>
>
|
|
|
|
|