Just to explain, why some solutions here count records: In DBFs you can have RECCOUNT()>0, while there are no records. Because if you delete records, they are only marked deleted. This is done, because removing the bytes of the record physically means you'd need to rewrite all records after this one and in the mean case this means writing half the file size, just to remove the bytes of one record. Therefore there only is a byte in each record, that's not part of the record data and is set to 42 for deleted records.
RECCOUNT() simply is reading the reccount from the DBF header (it's structure is explained in the VFP help) and that counter is only incremented, when new records are added, not decremented, if records are deleted. So it also counts deleted records and you can compute the dbf file size via 1+HEADER()+RECCOUNT()*RECSIZE().
RECCOUNT() is fine anyway, because you would rather only have an empty table after creating it or as a result table, and then RECCOUNT() will be 0, it's seldom you delete all records of a table, if you would want that, you'd rather ZAP than DELETE ALL and thereby really physically reset the DBF to be just the header and EOF byte without any records.
But to be sure about that and nevertheless not need to count, you could query just the first undeleted record you find into a cursor, this will give you an unusual approach:
Code:
SELECT TOP 1 RECNO() FROM theTable ORDER BY 1 INTO CURSOR curEmpty
If RECCOUNT("curEmpty")=0
* the table is empty
EndIf
As you only want to see, if the table is empty, you don't need the count, neither the count including deleted records nor the count of undeleted records. The query will instead query the top 1 record and stop there. If there is one you know the table is not empty, if there is none, you know the table is empty.
The advantage of that solution is, it will be fast and only query a single record, even if there are many. It won't retrieve the row itself, just the recno of the first undeleted record, but the resultset doesn't matter. If it's RECCOUNT() is 0, the table is empty.
On the other side RECCOUNT() is just reading 4 bytes of the DBF header, as already said, that's even faster, and can be relevant if you apply it to a resultset cursor or table, directly after creating it. That's what I use and why I use it. There can't be a deleted record in curEmpty.
Even if you SET DELETED OFF and allow VFP to query deleted records, the result curEmpty would never have deleted records, instead it would have the deleted record from the source table(s) as undeleted records of the result. The deletion mark byte is not inherited by querying data, resultsets are new records and therefore get no deletion mark byte set. That's the danger of SET DELETED OFF, you need to be sure you want that, eg when you want to find a record to RECALL it. The normal case is SET DELETED ON anyway.
Oh, and there is another simple solution:
Code:
set deleted off && if it isn't anyway
use sometable
if eof()
* table is empty, because
* VFP autolocates the first undeleted record and goes to eof(), if there are only deleted records.
endif
Bye, Olaf.