All is said, but to expand a bit:
RECCOUNT() is always the count of all records, including deleted and not yet removed by PACK. It's fastest, as it doesn't need to count, it just gets the current count value maintained in the DBF file header to have a check about file corruption. Off topic: File size of a healthy DBF is HEADER()+RECSIZE()*RECCOUNT()+1. The 1 is for an EOF byte. RECSIZE() is really equal for all records, even with varchar fields, though they are not just a fixed size reference to the fpt file, as memo fields are.
If you need a count as currently filtered records (via SET FILTER including the implicit filtering by SET DELETED) then COUNT To lnCount is giving the count of currently visible records. CALCULATE helps to do other things than counting. Both COUNT and CALCULATE have their own FOR clause for additional filters, if you SELECT table/SET FILTER TO RECNO()=1 and COUNT FOR RECNO()>1 you get 0, both filters are additive, the COUNT FOR filter does not override the workarea filter.
As Vilhelm-Ion said SQLs COUNT() is good in conjunction with WHERE and GROUP BY, but SQL always goes down to the DBFs, it does respect the deleted setting, but no further filters, only its own WHERE clause, so that's unlike the COUNT FOR behaviour.
All of these things and slight differrences have their place and use. Partly, but not mainly, the best performance RECCOUNT() is a good reason to query INTO CURSOR (having its own RECCOUNT) rather then SET FILTER. Besides that the grid scrollbar behaves nicer with a query result set than with a filtered table or filter cursor.
Bye, Olaf.