                     dBASE Cross Tabulation
        (PC Magazine Vol 5 No 22 Dec 23, 1986 Power User)

     Occasionally, you need COUNTs for all possible combinations of
certain fields in dBASE files.  Multiway tabulation (e.g., "How are
people in a database distributed by sex and age?") is a fairly common
tool in statistics, and it is sometimes seen in other contexts.  To do
this with a series of COUNTs or TOTALs, however, requires that the
whole sequence of instructions be assembled from scratch for each
specific query.
     XTAB.PRG offers a more general solution, though it can process
only one table at a time.  To use the program, issue the command:

DO XTAB

The procedure GETs the data filename, the number of variables (i.e.,
fields or expressions) to be tabulated, and the name of each one.
Then it creates a summary database to store the resulting table (ending
in .DBX) and begins processing.
     Editor's Note:  Life would be simpler if dBASE would allow you to
TOTAL ON more than one field.  Then, to your original file you could
just add a numeric field caller counter (a length of 4 would usually
be sufficient), REPL ALL counter WITH 1,INDEX ON key expression, and
TOTAL ON key expression.

** XTAB.PRG
SET TALK OFF
CLEAR
nvar=0
origfile=SPAC(20)
@  3,0 SAY "CROSS TAB PROGRAM"
@  5,0 SAY "Which file? " GET origfile
READ
origfile=TRIM(origfile)
@  7,0 SAY "How many variables?" GET nvar
READ
SELE 1
USE &origfile ALIA origfile
keyexp=""
* keyexp = list of vars delimited with plus signs
i=1
DO WHILE i<=nvar .AND. LEN(keyexp)<250
  nomvar=SPAC(25)
  @ 8+i,0 SAY "Variable "+STR(i,2)+" field/expression? " GET nomvar
  READ
  nomvar=TRIM(nomvar)
  IF TYPE([&nomvar})='N'
    * Note: change below if decimals
    keyexp=keyexp+'STR('+nomvar+',10,0)'
  ELSE
    keyexp=keyexp+nomvar
  ENDIF
  IF i<nvar
    keyexp=keyexp+"+[ ]+"
  ENDIF
  i=i+1
ENDDO
* create summary file
SET SAFE OFF
COPY STRU EXTENDED TO tempsum
SELE 2
USE tempsum
DELE FOR RECNO()>2
PACK
GOTO 1
REPL field_name WITH "TOT",field_type WITH "N",;
     field_len WITH 5,field_dec WITH 0
sumname=TRIM(origfile)+".dbx"
CREATE &sumname FROM tempsum
USE &sumname
ERAS tempsum.dbf
* scanning the data file
? "Standby ....processing"
SELE 1
INDEX ON &keyexp TO temp
SET INDEX TO temp
SET SAFE ON
keyref=&keyexp
DO WHILE .NOT. EOF()
  COUN WHILE &keyexp=keyref TO ncount
  SELE 2
  APPEND BLANK
  REPL tot WITH ncount,key WITH keyref
  SKIP
  SELE 1
  keyref=&keyexp
ENDDO
CLEAR
SELE 2
DISP OFF ALL tot,key
CLOSE DATA
* Optional: ERAS temp.ndx
SET TALK ON
RETU
