Subject Re: Error Code 239 IDAPI error
From Mervyn Bick <invalid@invalid.invalid>
Date Sun, 22 Oct 2023 11:34:34 +0200
Newsgroups dbase.getting-started

On 2023/10/20 14:48, MichaelItaliano wrote:
> Hi Mervyn,
>
> Very basic standard code, like USE &filenamestr in slect()
> set index to tag Modified
> set filter  to modified = "Y"
> go top
> set filter to
> use
>
> I believe some thing has changed in the versions, all of a sudden I am getting drop outs I never had before.
>
> Akshat may be onto something with timers
>
In theory, there should be no regressions and "old" code should work
without problems in new versions of dBASE.  In practice, as you've
found, that's not always true.  dBASE 2019 was "optimized" but this was
for OODML.  It is quite possible that this has caused the problem.  In
as much as nowadays focus is on OODML, the testing of the XDML side of
dBASE 2019 may have been skimped so the regression was missed.

Creating objects in loops and not properly releasing them is a possible
cause of your problem but I would have expected this to also to have
been a problem before you moved to dBASE 2019.  This suggests that the
problem is with your XDML code.  I would get rid of the XDML code in the
three modules giving trouble as a first step.  SOD's Law will ensure
that it will be the third module that is the culprit. :-)

In your XDML code above, unless the MODIFIED tag is based on a complex
index expression, i.e on more than one field, activating the index is
redundant.  Setting the filter to modified = 'Y' will ensure that the
resulting rowset contains just the selected records in natural order.
Unless you need to get access to all the records in the table after you
have processed the selected records, clearing the filter is also
redundant. The USE command destroys the entire rowset in memory.

To replace the XDML code above, a query object with the following for
the sql property should do the trick.

sql = "select * from tablename where modified = 'Y'"

If you need the rowset ordered by the contents of just one field

sql = "select * from tablename where modified = 'Y' order by fieldname"

The ORDER BY clause makes the rowset read-only.  If you need to write to
the rowset, perhaps to change the value in modified to 'N' after the
record has been processed, create a simple index on the field fieldname.
  The index does not need to be active (you should never activate an
index where an ORDER BY clause is used anyway) it simply has to exist.

If the rowset needs to be ordered on more than one field you should use
neither a WHERE clause nor an ORDER BY clause.  Use an index and a
filter as you have done in XDML.

Query objects are not "reusable" in that the table can't be changed
simply by passing in a new table name.  You will, therefore, need to
create a separate instance of the query object for each table you need
to deal with.  Only make each query active, which will create a new
up-to-date rowset, as you need to use it and immediately set the active
property false when you're done with it.

Mervyn.