O que vocês estão pedindo, não é uma coisa simples de se fazer. Tudo depende das mensagens de erros e a situações prevíveis que possam ocorrer. Sugiro que estudem bem o ERRORSYS.PRG, as variáveis estão disponíveis em forma de objetos. Os includes, não tem mistério, aqui no exemplo abaixo eu usei "FILEIO.CH" porque manipulo arquivo em baixo nível. E se eu tivesse que explicar tudo que eu faço no meu sistema de tratamento de erro, iria demandar muito tempo e seria desnecessário. Segue parte da minha rotina:
Código: Selecionar todos
/***
*
* Errorsys.prg
*
* Standard Clipper error handler
*
* Copyright (c) 1990-1993, Computer Associates International, Inc.
* All rights reserved.
*
* Compile: /m /n
*
*/
#INCLUDE "FILEIO.CH"
Procedure ErrorSys()
ErrorBlock({|oError|LogError(oError)})
return
Function LogError( oErr )
Local cScreen := SaveScreen() ,;
cCorAnt := SetColor() ,;
cLogFile := Space(12) ,;
nWorkArea := Select() ,;
nRange := ( Maxcol()+1 ) * 2 ,;
nStart := 1
Local aArqTemp, VNUM, VPROC, OpcAlert, XERRO
Local nFhandle , nCount , nForLoop , nMemHandle ,;
nMemLength , nMemWidth , nMemCount , cOutstring ,;
cSubstring , cVarName , cVarType , cTemp ,;
nLenTemp , nBytes , cVarRec , vOpc
Local cExt, I, SO_UMA
If ( oErr:GenCode() == 5 )
SetColor( cCorAnt )
Return 0
Endif
If ( oErr:GenCode() == 21 .And. oErr:OsCode() == 32 .And. oErr:CanDefault() )
NetErr(.T.)
SetColor( cCorAnt )
Return .F.
EndIf
If ( oErr:GenCode() == 40 .And. oErr:CanDefault() )
NetErr(.T.)
SetColor( cCorAnt )
Return .F.
EndIf
if oErr:Description()=="Corruption detected"
_DBF_:=""
IF RIGHT(ALLTRIM(oErr:FileName()),4)=".DBF"
_DBF_:=UPPER(oErr:FileName())
ELSE
_DBF_:=UPPER(ALIAS())
ENDIF
IF !EMPTY(_DBF_)
IF lOkDbf( _DBF_, _PAT_ )=.F. // Esta função verifica o hearder do DBF
/* Mover arquivo dbf para uma pasta, a fim de que posteriormente seja verificado a possibilidade
de recuperar dados. Eu utilizo o FILEFIX (do antigo Norton) e criar novo arquivo DBF no local */
ENDIF
ENDIF
/* Crio um arquivo .bat para executar rotina de indexação
*/
Endif
Segue a rotina de verificação do header do dbf, que pode estar junto no mesmo arquivo ERRORSYS.PRG:
Código: Selecionar todos
FUNCTION lOkDbf( cNameExt, cPath )
LOCAL lReturn := .T.
LOCAL nHnd, cBytes, nNumRecs, nHdrSize, nRecSize, nFileSize, nRecs
LOCAL cError, cErrorLog
nHnd := FOpen(cPath + '\' + cNameExt, FO_READ+FO_SHARED)
FSeek(nHnd,4,FS_SET) // Posiciona no come‡o do arquivo
cBytes:='0000' // Numero registros segundo tabela
FRead(nHnd,@cBytes,4)
nNumRecs:=Bin2L(cBytes)
cBytes:='00' // Tamanho do Header
FRead(nHnd,@cBytes,2)
nHdrSize:=Bin2I(cBytes)
cBytes:='00' // Tamanho do Registro
FRead(nHnd,@cBytes,2)
nRecSize:=Bin2I(cBytes)
nFileSize:=FSeek(nHnd,0,FS_END) // Tamanho da Tabela
nRecs:=(nFileSize-nHdrSize)/nRecSize // Numero de registros reais
IF nRecs != Round(nRecs,0) // dBase, Fox (tem 1 byte a mais)
nRecs:=(nFileSize - nHdrSize - 1) / nRecSize
ENDIF
FClose(nHnd)
// Se n„o coincidem (Numero reg. segundo tabela e o que calculado)
IF nRecs != nNumRecs
lReturn := .F.
ENDIF
RETURN lReturn
Espero que isto traga inspiração para que vocês mesmos façam a sua propria rotina. Pesquisem outros exemplos, como descritos nestes tópicos:
https://pctoledo.org/forum/viewto ... n+Detected
https://pctoledo.org/forum/viewto ... prg#p65658
https://pctoledo.org/forum/viewto ... 707#p43707
Tem inclusive no primeiro link acima, uma idéia e exemplo do Maligno que utiliza-se da verificação CR32 que também seria uma boa saída para verificar seu o dbf foi alterado por fora do sistema.
Também tem na seção de Downloads um exemplo de tratamento de erros e se não me engano trata sobre Corruption detected, só teria que mudar CDX para NTX (caso seja essa a RDD):
https://pctoledo.org/forum/fileba ... t=s&page=1