Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
'Not a Table' error in VFP 5.0
Message
General information
Forum:
Visual FoxPro
Category:
Databases,Tables, Views, Indexing and SQL syntax
Miscellaneous
Thread ID:
00183515
Message ID:
00183542
Views:
16
>Our network server had a mishap recently and now a data table (not part of a DBC) cannot be opened by the app or from VFP. The error returned is Error 15: Not a table.
>
>Is there a freeware utility available that can repair the header of this file? Or is there another option?
>
>TIA

Hi Bryan,

This is what I include in my applications. It has worked well for me.

Note also that it was still written under dos, so the user interface is not the prettiest.

Marc
***
***	CrashRec.Prg
***

*
*	MG 07/10/94
*

*
*	This program scans the dbfs in a passed directory (xDatadir).
*	Each file is diagnosed.  If it can be 'USE'd exclusively it passes
*	the test.  If it cannot be used because it is in used by someone else
*	it assumed to pass the test.  
*	
*	If on the other hand it cannot be used, then it mus be recovered.
*	This is done by adjusting the number of records in the header to
*	the other parameters of the file (The file length in bytes, the 
*	record length and the header length following the dbfs header).
*
*	Recovery for a file can be prevented by pressing escape when 
*	prompted.   The number of missing records is displayed as well as
*	whether or not figures balance out.  If they do not balance out, 
*	it is adviseable, but not required, to investigate further before
*	allowing the recovery.
*
*	DISCLAIMER
*	----------
*
*	The program is used at the risk of the person who invokes it.  	
*
*	LIMITATION
*	----------
*
*	This program only solves one of the many corruptions that a database
*	can encounter.  Specifically, dbfs that where being updated during
*	a server crash tend to respond favorably to this recovery program.
*
*	In fact after running the program, you will 
*	probably be able to USE the files again, but some of your data will
*	be lost.
*
*	Explicitly, but not exhaustively left out of this program, are 
*	corrupted memofiles.
*
	

parameter xDatadir
private all like x*

xP=0
xR=0
xR1=0
xL=0
xF=0

if parameters()=0	
	xDataDir=""
endif


define window CrashRec;
	from 5,5 to srows()-3,75;
	title "Crash recovery"
	
activate window CrashRec

=adir(xFiles,(xDatadir+"*.dbf"))

? " Please note that this program could inflict major damage to "
? " your data."
? " You use it at your own risk."

xSetEsc= set("ESCAPE")="ON"
set escape off

wait "Press any key to proceed, or ESCAPE to terminate"

if lastkey()=27
	if xSetEsc
		set escape on
	endif
	clear window
	release window
	return
endif

if xSetEsc
	set escape on
endif

? "There are "
?? alltrim(str(alen(xFiles,1)))
?? " dbfs to be checked" 
?


xErrStat= 0
xErrHandl= on("Error")

xEl=0
for xEl=1 to alen(xFiles,1)
	if !xDiagnose()
		if !xRecover()
			exit
		endif
	endif
	wait "" timeout 2
endfor

do xCleanup

***
*** -----------------------------------
***

procedure xAdjust

wait "adjusting" window nowait

xB7= int(xR1/256^3)
xRest= xR1-xB7*256^3

xB6= int(xRest/256^2)
xRest= xRest-xB6*256^2

xB5= int(xRest/256)
xB4= xRest-xB5*256

xChr7= chr(xB7)
xChr6= chr(xB6)
xChr5= chr(xB5)
xChr4= chr(xB4)


xH= fopen(xDatadir+xFiles(xEl,1),12)

xDummy= fseek(xH,4)
xDummy= fwrite(xH,xChr4)

xDummy= fseek(xH,5)
xDummy= fwrite(xH,xChr5)

xDummy= fseek(xH,6)
xDummy= fwrite(xH,xChr6)

xDummy= fseek(xH,7)
xDummy= fwrite(xH,xChr7)

=fClose(xH)

wait clear

***
*** -----------------------------------
***

procedure xCleanup

on error &xErrHandl
release window CrashRec

***
*** -----------------------------------
***

procedure xDiagnose

? "Checking "+xFiles(xEl,1)
xErrStat=0

on error do xError

use xdatadir+xFiles(xEl,1) exclu in 0

on error &xErrHandl

do case
case xErrStat=0
	use
	? "Passed"
	?
	return
case xErrStat=1
	use
	? "Must be recovered"
	return .f.
case xErrStat= 2
	? "File is in use"
	? "Assumed ok"
	?
case xErrStat= 3
	? "File is in use by current station "
	? "Assumed ok"
	?
endcase

***
*** -----------------------------------
***

procedure xError

on error &xErrHandl

xErr= error()

do case
case (xErr= 125) or (xErr=108)
	*
	*	File in use ...  assume it is ok
	*
	xErrStat=2
	return	
case xErr= 15
	*
	*	"Not a DBF file ...‚
	*
	xErrStat= 1
case xErr= 3
	*
	*	"File in use"
	*
	xErrStat= 3
otherwise
	? "Terminal Error"
	do xCleanup
	&xErrHandl
endcase

***
*** -----------------------------------
***

procedure xRPL

xH= fopen(xDatadir+xFiles(xEl,1),12)

xR=0
xDummy= fseek(xH,4)
xBuffer= fread(xH,1)

xR= asc(xBuffer)
xDummy= fseek(xH,5)
xBuffer= fread(xH,1)
xR= asc(xBuffer)*256+xR

xDummy= fseek(xH,6)
xBuffer= fread(xH,1)
xR= asc(xBuffer)*256^2+xR

xDummy= fseek(xH,7)
xBuffer= fread(xH,1)
xR= asc(xBuffer)*256^3+xR

*

xP=0
xDummy= fseek(xH,8)
xBuffer= fread(xH,1)
xP= asc(xBuffer)

xDummy= fseek(xH,9)
xBuffer= fread(xH,1)
xP= asc(xBuffer)*256+xP

*

xL=0
xDummy= fseek(xH,10)
xBuffer= fread(xH,1)
xL= asc(xBuffer)

xDummy= fseek(xH,11)
xBuffer= fread(xH,1)
xL= asc(xBuffer)*256+xL

=fClose(xH)

***
*** -----------------------------------
***

procedure xRecover

? "File length= "
xF= xFiles(xEl,2)
?? xF

xR=0
xP=0
xL=0

do xRPL

? "Number of records= "
?? alltrim(str(xR))

? "Position of the first data record= "
?? alltrim(str(xP))

? "Length of one record= "
?? alltrim(str(xL))
?

if xL=0
	? "File could not be recovered"
	wait window
	return
endif

xR1= (xF-1-xP) / xL

if xR1<>int(xR1)
	? xR1
	? "Figures do not balance out"
else
	? "Figures balance out"
endif
xR1= int(xR1)
?? " - Lost records= "
?? alltrim(str(xR-xR1))
wait "Press Escape if you do not want to recover this file" 
if lastkey()=27
	? "This database has not been recovered"
	return 
endif

do xAdjust

if xDiagnose()
	? "Recovered"
else
	? "Could not recover this database"
endif
?

If things have the tendency to go your way, do not worry. It won't last. Jules Renard.
Previous
Reply
Map
View

Click here to load this message in the networking platform