ID: Q124386
The information in this article applies to:
The COUNT TO command does not return a true count of records when tables are set up in a one-to-many relationship (one parent record to many child records) because it can't exclude the child records.
There are several possible workarounds for this situation. The first, and perhaps the best, alternative is to use an SQL SELECT command with a WHERE clause on the table that has the records you want to count. Here's an example:
SELECT * FROM INVOICES WHERE CNO = CUSTOMER.CNO INTO CURSOR TEMP
Once the information is in the cursor TEMP, you can derive the total number
of records that met the WHERE clause condition by checking the _TALLY
variable. _TALLY holds the number of records returned by the SQL SELECT
statement.
As an alternative, you can determine how many parent records meet the FOR clause by using the SET SKIP TO command to break the one-to-many relationship before executing the COUNT TO command. After you get the count, re-establish the relationship.
This behavior is by design.
According to Help in FoxPro for Windows, the COUNT TO command:
... counts the records within a scope of records for which
the FOR or WHILE conditions are true. If SET TALK is ON, the
record count is displayed in this form
nnnnnn records
Records marked for deletion are included in the count if SET
DELETED is OFF.
The COUNT TO command supports a FOR clause to limit the scope of records
counted. If the command includes a scope clause, it will only operate on
the table in the active work area. However, if that table is engaged in a
one-to-many relationship (one parent record to many child records), the
COUNT TO command can't count just the parent records because the child
records are part of the active work area scope.
Create and run a program containing this code:
CLOSE ALL SET SAFETY OFF USE SYS(2004)+"\Tutorial\Customer" IN 1 USE SYS(2004)+"\Tutorial\Invoices" IN 2 SELECT 2 INDEX ON cno TAG cno ADDITIVE SET ORDER TO TAG cno OF SYS(2004)+"\tutorial\invoices.cdx" SELECT 1 SET RELATION TO cno INTO invoices ADDITIVE SET SKIP TO invoices DEFINE WINDOW browwin FROM 0,0 TO 20,70 MOVE WINDOW browwin CENTER BROWSE WINDOW browwin NOWAIT LOCATE FOR customer.cno = "A2695" IF (FOUND())
WAIT WINDOW "Found record ok."
ENDIF
COUNT TO myvar FOR customer.cno = "A2695"
LOCATE FOR customer.cno = "A2695"
WAIT WINDOW "COUNT shows " + ALLTRIM(STR(myvar))+" records for A2695"
The COUNT TO command reports that there are five records in the parent table that meet the FOR clause, not one, which is really the case. The COUNT TO command includes the child records that are displayed in the one- to-many relationship in the parent table. While the number returned is, in fact, valid for the number of records in the child table, it is not valid for the number of records in the parent table.
NOTE: If you use the COUNT TO command to find out how many child records each parent has, the number returned by the COUNT TO command will be valid only if there are two or more child records. In a one-to-many relationship, FoxPro doesn't show a single child record in the parent table. As a result, you can't use COUNT TO to determine if there is one and only one child record for any given parent.
Additional reference words: FoxWin 2.60a COUNT TO SUM KBCategory: kbprg kbprb KBSubcategory: FxprgGeneral
Last Reviewed: June 27, 1995