Fixing 'Not a DBF' source code

Fixing 'Not a DBF' source code

Post by Tom Bellm » Fri, 12 May 1995 04:00:00



I'm new to this group, but have seen several posting from persons encountering 'not a DBF'.  This
error is sometimes caused by the RECCOUNT() value not being in sync with the actual file size.
My experience has been that dBASE III Plus would open this files and then this could be solved
by PACKing the table.  Anyway, this may help some of you... enjoy.

**********************************************************************
*  Program Name:   FIXRECNT.PRG
*  Purpose:        Rewrite correct RECCOUNT() value to DBF header
*  Written by:     Tom Bellmer  (816) 854-7750
*  Copyright:      (c) 1993, Sprint
*  Date Written:   06/28/93
*  Modified:       08/11/93
*  Usage:          If dbf name = TEMP.DBF
*        DO fixrecnt WITH "temp.dbf" OR =fixrecnt("temp.dbf")
*********************************************************************
PARAMETERS lcfname
PRIVATE ALL LIKE l*

IF AT('.',lcfname) = 0
        ? CHR(7)
        WAIT WINDOW "File name with extension is required..."
        RETURN
ENDIF

lnhandle     =FOPEN(lcfname,12)         && Open w/unbuffered read/write
IF lnhandle  = -1                               && Test for error
        WAIT WINDOW "Error: "+STR(FERROR(),2)
        RETURN
ENDIF
lchdrinfo  =FREAD(lnhandle,12)          && Read first 12 characters

* Calculate the header length
lnhdrsize  = INT(ASC(SUBSTR(lchdrinfo,09,01)) ;
                           + ASC(SUBSTR(lchdrinfo,10,01)) * 256)
* Calculate the record length
lnreclngth = INT(ASC(SUBSTR(lchdrinfo,11,01)) ;
               + ASC(SUBSTR(lchdrinfo,12,01)) * 256)

************************************************************************
*  ADIR returns file statistics into the array named 'lafsize'.  The
*  variable 'lnreccnt' calculates the record count by subtracting the
*  header length from the file size and dividing the result by the
*  record length.
************************************************************************
=ADIR(lafsize,lcfname)
lnreccnt   = INT((lafsize[2] - lnhdrsize) / lnreclngth)

************************************************************************
*  Modulus division is used to return the remainder of division by 256
*  taken to a decreasing exponent power.
************************************************************************
lcfirst8   = LEFT(lchdrinfo,4) + SPACE(4)
FOR lni = 3 TO 0 STEP -1
        lcfirst8 = STUFF(lcfirst8,lni+5,1,CHR(INT(lnreccnt / 256^lni)))
        lnreccnt = lnreccnt % 256^lni
ENDFOR

=FSEEK(lnhandle,0,0)                    && Go to the top of the file
=FWRITE(lnhandle,m.lcfirst8)    && Write 1st 4 positions & RECCOUNT() val
=FCLOSE(lnhandle)                               && Close the file

RETURN
* EOF fixrecnt.prg