-larry gauthier
eas...@ismi.net
Larry,
For capable Fox file repair take a look at our 'Recover' utility
at our website: http://www.abri.com/
-----------------------------------------------------------------
Paul Lee ........... Abri Technologies ......... http://abri.com/
'Recover' - the top rated FoxPro file repair utility.
-----------------------------------------------------------------
* Syntax | llSuccess = ez_fixDb( filename )
* Action | Rewrite corrected RECCOUNT() value to DBF header.
* Returns | TRUE for success, FALSE for failure.
* Process | lcFname Name of the file to fix.
* | lnHandle File handle.
* | lcHdrInfo Header information.
* | lnHdrSize Header size.
* | lnRecLngth Record size. (Caution: could be zero.)
* | laFsize[1,1] Name of the file (m.lcFname).
* | [1,2] Size of the file.
* | [1,3] Date of latest change.
* | [1,4] Time of latest change.
* | [1,5] File attributes.
* | lnRecCnt Record count
* | lcFirst8 New answer for header.
* | lnDbfs Number of tables to fix.
* | lcFirst8 First eight bits of the number.
* |
* Note | If the record count in the header is smaller than the
correct
* | number, FoxPro ignores the error and treats the file as
truncated.
* | Will this cause trouble downstream?
* |
* Concept | Tom Bellmer (816) 854-7750
*--
PARAMETERS lcfname
PRIVATE ;
lcFname, ;
lnDbfs, ;
laDir, ;
lni
CLOSE ALL
lnDbfs = 0 && assume only one DBF to fix
*-- Check parameter
DO CASE
CASE PCOUNT() = 0 OR TYPE( "m.lcFname" ) != "C" OR LEN( m.lcFname ) = 0
*-- Fix all the DBFs in the current directory.
lnDbfs = ADIR( laDbfs, "*.DBF" )
CASE AT( '.', m.lcfname ) = 0
*-- File name was passed without file extension.
lcfname = UPPER( m.lcfname ) + ".DBF" && repair it
IF ADIR( laDir, m.lcFname ) = 0
WAIT CLEAR
WAIT WINDOW NOWAIT ;
"EZ_FIXDB: File " + m.lcfname + " does not exist." + CHR( 13 ) + ;
"Supply an extension if it's not .DBF"
RETURN .F.
ENDIF
ENDCASE
IF m.lnDbfs = 0
*-- Only one DBF to check
= ez_fixd2( m.lcFname ) && fix the table
ELSE
*-- Check all DBFs in laDbfs[]
FOR lni = 1 TO m.lnDbfs
IF m.lnDbfs > 1
= therm( m.lni * 100 / m.lnDbfs, "Checking DBF tables" )
ENDIF
= ez_fixd2( laDbfs[ m.lni, 1 ]) && fix the table
ENDFOR
= therm() && release therm() window
ENDIF
*-- Clean up
CLOSE ALL
*:=======================================================
PROCEDURE ez_fixd2
PARAMETERS m.lcFName
PRIVATE ;
lnHandle, ;
lcHdrInfo, ;
lnHdrSize, ;
lnRecLength, ;
lnRecCnt, ;
lcFirst8, ;
lnj
*-- Does the table exist?
IF ADIR( laDir, m.lcFname ) = 0
WAIT WINDOW NOWAIT ;
"EZ_FIXDB: File " + m.lcfname + " does not exist."
RETURN .F.
ENDIF
lnhandle = FOPEN( m.lcfname, 12 ) && open w/unbuffered read/write
IF m.lnhandle = -1 && test for error
WAIT WINDOW NOWAIT ;
"EZ_FIXDB: Could not open " + m.lcfname + CHR( 13 ) + ;
"File Error: " + STR( FERROR(), 2, 0 )
RETURN .F.
ENDIF
lchdrinfo = FREAD( m.lnhandle, 12 ) && read first 12 characters
*--Calculate the header length:
lnhdrsize = INT( ASC( SUBSTR( m.lchdrinfo, 9, 1 )) ;
+ ASC( SUBSTR( m.lchdrinfo, 10, 1 )) * 256 )
*--Calculate the record length:
lnreclngth = INT( ASC( SUBSTR( m.lchdrinfo, 11, 1 )) ;
+ ASC( SUBSTR( m.lchdrinfo, 12, 1 )) * 256 )
*-- ADIR() returns file statistics into the array named 'lafsize'.
= ADIR( lafsize, m.lcfname )
*-- lnRecCnt calculates the record count by subtracting the
*-- header length from the file size and dividing the result by the
*-- record length. (Yes, RECSIZE() will do that, but if we could
*-- open the file as a table, we wouldn't be here.)
IF m.lnRecLngth > 0
lnreccnt = INT(( lafsize[ 2 ] - m.lnhdrsize ) / m.lnreclngth )
*-- Modulus division returns the remainder of division by 256
*-- taken to a decreasing exponent power.
lcfirst8 = LEFT( m.lchdrinfo, 4 ) + SPACE( 4 )
FOR lnj = 3 TO 0 STEP -1
lcfirst8 = STUFF( ;
m.lcfirst8, ;
m.lnj +5, ;
1, ;
CHR( INT( m.lnreccnt / 256 ^ m.lnj )))
lnreccnt = m.lnreccnt % 256 ^ m.lnj
ENDFOR
IF lcHdrInfo = m.lcFirst8
WAIT CLEAR
WAIT WINDOW NOWAIT ;
m.lcfname + " is a table/DBF." + CHR( 13 ) + ;
"No repair necessary."
ELSE
*-- Fix the file.
= FSEEK( m.lnhandle, 0, 0 ) && go to the top of the file
= FWRITE( m.lnhandle, m.lcfirst8 ) && write 1st 4 positions &
RECCOUNT() val
= FCLOSE( m.lnhandle ) && close the file
*-- Clean up.
WAIT WINDOW NOWAIT ;
m.lcfname + " has been repaired."
ENDIF
* = INKEY( 0, "H" ) && wait, hidden cursor, no
mouse
ELSE
= ez_msg( .F., .F., ;
"Header is trashed, and shows", ;
"record length as zero.", ;
"Can't repair file. Sorry." )
ENDIF
RETURN .T. && successful end of job
*: EOF: EZ_FIXDB.PRG
>I have a small (900KB) database that broke yesterday, and I now cannot 'use'
>it because of the "not a table/DBF" error. I have looked at the file with
>LIST, and all of the data in it - and record layout - appears to be intact.
>I suspect that the only problem is with the file header. Is there a utility
>somewhere that will fix this? How about a reference on the DBF file format?
>
>-larry gauthier
> eas...@ismi.net
>
>
Larry,
This is a 95 out of 100 times a header problem .
I got an old copy of mfoxplus 2.0 that will open the dbf with
copprupted header and :
use notdbf.dbf
append blank
delete
quit
and rebuild index in current version of foxpro / vfp
See if you can find an old copy of mfoxplus,
Good luck
Willem,
the Netherlands
Is it possible that this DBF has been converted into Visual FoxPro
format?
--
Bruce Kube
Systems Analyst
Trendstat Capital Management, Inc.
(Please fix return address if responding directly via e-mail.)
The problem has been solved - I used a hex editor to nibble the file header
Bruce K wrote in message <34EAF92B.3CE5@trendstat_com.nojunk_spam>...
Is there a utility to convert the header from VFP format to 2.6 format so
it can be read by the earlier version ?
Thx, Joe
tiaaata1 <tiaa...@ix.netcom.com> wrote in article
<01bd3cbd$0255b9e0$b5e06dd1@default>...
>I have a similar problem (one alluded to by Bruce Kube). We have both
>WinFox 2.6 and VFP. Tables created in 2.6 seem "upwardly compatible", i.e.
>can be read by VFP. But the reverse is not true; the "not a table/dbf"
>error occurs. I assume this is because the format of the header record is
>different.
>
>Is there a utility to convert the header from VFP format to 2.6 format so
>it can be read by the earlier version ?
Try
copy to <overthere> type fox2x
[snip]
Sincerely,
Gene Wirchenko
C Pronunciation Guide:
y=x++; "wye equals ex plus plus semicolon"
x=x++; "ex equals ex doublecross semicolon"