Por via das dúvidas, compile o programa anexo e rode na pasta onde estão as tuas tabelas. Vamos ver se detecta algo.
Código: Selecionar todos
// -------------------------------------------------------------------------------------
//
// TBCheck.Prg - Alexandre Santos - 26-03-2010
// Compilar ===> Clipper TBCheck /N
//
//--------------------------------------------------------------------------------------
#include "Box.Ch"
#include "SetCurs.Ch"
#include "Directry.Ch"
PROCEDURE TbCheck()
LOCAL aFiles, nLen, nPos, aErr, nRetCode, nCursor
nCursor := SetCursor( SC_NONE )
SetColor( "W+/W" )
CLS
DispBox( 0,0,MaxRow() - 1, MaxCol(), B_SINGLE + " " )
BEGIN SEQUENCE
nRetCode := Alert( "Este programa verificará a integridade de seus arquivos DBF/DBT na pasta corrente." + ;
"Deseja continuar?", { "Sim", "Nao" }, "W+/B" )
IF nRetCode != 1
BREAK
ENDIF
aFiles := Directory( "*.DBF" )
IF Empty( aFiles )
Alert( "Não foram encontrados arquivos DBF na pasta corrente.",, "W+/B" )
BREAK
ENDIF
aErr := {}
nLen := Len( aFiles )
FOR nPos := 1 TO nLen
@ MaxRow(), 1 Say PadR( "Processando arquivo " + aFiles[ nPos ][ F_NAME ] + ". Aguarde...", 70 )
nRetCode := ValidDBF( FileBase( aFiles[ nPos ][ F_NAME ] ) )
IF nRetCode != 0
AAdd( aErr, " " + aFiles[ nPos ][ F_NAME ] + " - " + MsgDecode( nRetCode ) )
ENDIF
NEXT
@ MaxRow(), 1 Say PadR( LTrim( Str( nLen ) ) + " arquivos analisados.", 70 )
IF Len( aErr ) == 0
Alert( "Fim de processamento.;Nenhum erro foi encontrado.",, "W+/B" )
ELSE
MsgShow( aErr )
ENDIF
END SEQUENCE
SetCursor( nCursor )
SetPos( 0, 0 )
RETURN
//--------------------------------------------------------------------------
// Testar se o DBF a ser aberto é válido.
//
// 0 - Everything ok
// -1 - File is corrupt
// -2 - File does not exist
// -3 - DBF file is set to read only
// -4 - Memo file is missing
// >0 - A DOS error
// 2 - File not found
// 3 - Path not found
// 4 - Too many files open
// 5 - Access denied
// 6 - Invalid handle
// 8 - Insufficient memory
// 15 - Invalid drive specified
// 19 - Attempted to write to a write-protected
// 21 - Drive not ready
// 23 - Data CRC error
// 29 - Write fault
// 30 - Read fault
// 32 - Sharing violation
// 33 - Lock Violation
//
// Exemplo: If ValidDBF( <xcFile>) != 0
// Alert( <xcFile> + " : " <cMessage> )
// Endif
//
//--------------------------------------------------------------------------
Function ValidDbf( cFile )
#define VALID_SIGNATURE_BYTES { 3, 131, 139, 245 }
#define DBT_FILE_NEEDED_BYTES { 131, 139, 245 }
#define MEMO_FILE_EXTENSIONS { "DBT", "DPT", "FPT" }
#include "SET.CH"
#include "FILEIO.CH"
Local cDir := Set(_SET_DEFAULT)
Local cBuf := Space( 12 )
Local nSign := 0
Local nReturn := 0
Local nBlocks := 0
Local nSize := 0
Local nRecs := 0
Local nRecSize:= 0
Local nOffset := 0
Local x
Local nHandle
nHandle := FOpen( cDir + cFile + ;
If( At( ".", Upper( cFile ) ) > 0, "", ".DBF" ), FO_READWRITE + FO_SHARED )
If nHandle != -1
FRead( nHandle, @cBuf, 12 )
nSize := FSeek(nHandle, 0, FS_END )
FClose( nHandle )
nSign := Asc( cBuf )
If Ascan( VALID_SIGNATURE_BYTES, nSign ) > 0
nRecs := Bin2l( Subs( cBuf, 5, 4 ) )
nRecSize := Bin2w( Subs( cBuf, 11, 2 ) )
nOffset := Bin2w( Subs( cBuf, 9, 2 ) )
If nRecs > 0
nReturn := If( Abs( ( nRecs * nRecSize ) + nOffset - nSize ) < 3, 0, -1 )
Else
nReturn := If( nOffset <= nSize + 1, 0, -1 )
Endif
Else
nReturn := -1
Endif
If nReturn == 0
If ( x := Ascan( DBT_FILE_NEEDED_BYTES, nSign ) ) > 0
nReturn := -4
nHandle := FOpen( cdir + cFile + "." + MEMO_FILE_EXTENSIONS[ x ], FO_READWRITE )
If nHandle != -1
If MEMO_FILE_EXTENSIONS[ x ] == "DBT"
cBuf := Space( 4 )
FRead( nHandle, @cBuf, 4 )
nSize := FSeek( nHandle, 0, FS_END )
nBlocks := Bin2l( cBuf ) * 512
If nSize <= ( nBlocks + 1 ) .and. nSize > ( nBlocks - 512 )
nReturn := 0
Endif
// Movi para depois do segundo Endif abaixo...
// FClose( nHandle )
Else
nReturn := 0
Endif
// Para clareza no cod retorno, se não encontrou o Memo associado, retorna -4;
// de outra forma retorna FError()
ElseIf FError() != 2
nReturn := FError()
Endif
FClose( nHandle )
Endif
Endif
Else
If Ferror() == 5
nReturn := -3
Else
nReturn := Ferror()
Endif
Endif
Return nReturn
//------------------------------------------------------------------------------
STATIC FUNCTION MsgDecode( nErr )
LOCAL nPos
STATIC aMsg
IF aMsg == NIL
aMsg := {}
AAdd( aMsg, { -1, "File is corrupt" } )
AAdd( aMsg, { -2, "File does not exist" } )
AAdd( aMsg, { -3, "DBF file is set to read only" } )
AAdd( aMsg, { -4, "Memo file is missing" } )
AAdd( aMsg, { 2, "File not found" } )
AAdd( aMsg, { 3, "Path not found" } )
AAdd( aMsg, { 4, "Too many files open" } )
AAdd( aMsg, { 5, "Access denied" } )
AAdd( aMsg, { 6, "Invalid handle" } )
AAdd( aMsg, { 8, "Insufficient memory" } )
AAdd( aMsg, { 15, "Invalid drive specified" } )
AAdd( aMsg, { 19, "Attempted to write to a write-protected" } )
AAdd( aMsg, { 21, "Drive not ready" } )
AAdd( aMsg, { 23, "Data CRC error" } )
AAdd( aMsg, { 29, "Write fault" } )
AAdd( aMsg, { 30, "Read fault" } )
AAdd( aMsg, { 32, "Sharing violation" } )
AAdd( aMsg, { 33, "Lock Violation" } )
ENDIF
nPos := AScan( aMsg, { |e| e[1] == nErr } )
RETURN If( nPos > 0, aMsg[ nPos][2], "Erro desconhecido" )
//------------------------------------------------------------------------------
STATIC PROCEDURE MsgShow( aErr )
LOCAL nChoice := -1, cColor := SetColor( "W+/W, W+/N" )
SetCursor( SC_NONE )
DispBox( 4,5,20,65, B_SINGLE )
@ 4, 7 Say " Erros encontrados: " Color "W+/R"
@ 20, 7 Say " <Esc> para sair " Color "W+/W"
WHILE ( nChoice := Achoice( 6, 6, 19, 64, aErr, .T. ) ) != 0
ENDDO
SetColor( cColor )
RETURN
//------------------------------------------------------------------------------
/***
*
* FileBase( <cFile> ) --> cFileBase
*
* Extract the eight letter base name from a filename
*
*/
FUNCTION FileBase( cFile )
LOCAL nPos // Marks the position of the last "\", if any
LOCAL cFileBase // Return value containing the filename
DO CASE
CASE ( nPos := RAT( "\", cFile )) != 0
// Strip out full path name leaving only the filename (with
// extension)
cFileBase := SUBSTR( cFile, nPos + 1 )
CASE ( nPos := AT( ":", cFile )) != 0
// Strip drive letter if cFile contains only drive letter
// no subdirectories
cFileBase := SUBSTR( cFile, nPos + 1 )
OTHERWISE
// Assume it's already taken care of
cFileBase := cFile
ENDCASE
// Strip out the file extension, if any
IF ( nPos := AT( ".", cFileBase )) != 0
cFileBase := SUBSTR( cFileBase, 1, nPos - 1 )
ENDIF
RETURN ( cFileBase )
//------------------------------------------------------------------------------