I wonder if I once told you about using ZAP in grid cursors. They are part of a technique called "safe select".
Maybe you got it from
where Andy Kramek coined the term, perhaps, he's also using the alias name "junk" for a temporry cursor. This technique is meant to use, if your grid recordsource is an SQL query. And you repeatedly need to requery with different parameters or where clause. You always just zap a grid cursor, never a DBF, for the safety reasons and concerns MarK points out from Tamar Granors Hacker's Guide.
You artificially make up the situation by using a query to fill your BINILI alias from itself. Well, that's pointing out you actually don't need this. The safe select situation is doing these steps:
1. Create a grid cursor, Andy Kramek showcases this as creation of such a cursor
Code:
*** Create the working cursor
SELECT * FROM account WHERE 0 = 1 INTO CURSOR curacct READWRITE
2. Whenever other data should be listed, query that into cursor junk, ZAP in curacct and APPEND FROM DBF('junk').
The aim here is to show a list of accounts, and the UI allows users to filter for account in different ways, which could be done with further queries in the same structure, just with other where clauses than 0=1, which is in short meaning .f., so the initial curacct cursor is empty. Every future list has other filter criteria and always stems from the same type of query from all data in account.dbf, but doing this directly again
INTO CURSOR curacct would cause the grid to lose its structure. So you select into a temporary junk cursor, zap the grid cursor and append the new result to scrap it afterwards. But also you depend on a query, as one list miight be all "meyer" accounts and the next all with a certain minimum amount in their depot. The lists change arbitrarily, the source of data always is account.dbf and the previous list is not needed anymore.
In your situation, you also start with an empty list. But you don't query different lists of products with varying where clauses, do you? You know every barcode scan or every pick of a user in an online shop to put something into the items list will add one single record to the already existing list, or up the qty by one. So in your situation you don't change from say select * from products where barcodde=x to select * from products where barcodde=y, you just add the one record of the barcode to your already existing list. And the easiest way to do this is start with an empty grid cursor you createe by a CREATE CURSOR statement and then insert into it and delete from it as you go, but you never reselect it, you don't even initially select data into it. Heere you don't even need an SQL query like I gave with where barcode=x, you can just SEEK x to go to the product with a certain barcode and then insert into curitems from fields of the product table.
This situation doesn't require safe select, it's over the top for this and it's nonsensical as you use the grid cursor as the source of the data for the grid cursor, you already have the grid cursor and all its data, you just need to either change qty, if it drops to 0 delete the record and if a record with the scanned barcode doesn't exist yet (the regular case, indeed) insert it. You always only have operations on one record, you don't ever pick a completely different list of source data. That's where you are safe by never needing to recreate the grid cursor, once it is created, it is only modified and stays the same file, the same dbf file or the same tmp file. See the section in Andy Krameks blogpost where he demonstrates the tmp file name of the cursor with the same alias name changes, which is the core reason the grid misbehaves and you need this technique. Where that's not the case you also don't need safe select.
Chriss