Jump to content
Fivewin Brasil

Buscar informações corrompidas dentro de um Arquivo Dbf.


Valdir

Recommended Posts

Amiguinhos,

Segue mais uma dica:

Teste de Integridade de .DBF

#INCLUDE "FILEIO.CH" 

FUNCTION lOkDbf( cNameExt, cPath ) 
LOCAL lReturn := .T. 
LOCAL nHnd, cBytes, nNumRecs, nHdrSize, nRecSize, nFileSize, nRecs 
LOCAL cError, cErrorLog 

// Abrimos en exclusiva. Si no es posible, alguien lo esta usando (NO dañado) 
IF (nHnd := FOpen(cPath + '\' + cNameExt, FO_READWRITE + FO_EXCLUSIVE)) > 0 
   FSeek(nHnd,4,FS_SET) 
   // Numero registros segun tabla 
   cBytes := '0000' 
   FRead(nHnd,@cBytes,4) 
   nNumRecs := Bin2L(cBytes) 
   // Tamaño Header 
   cBytes := '00' 
   FRead(nHnd,@cBytes,2) 
   nHdrSize := Bin2I(cBytes) 
   // Tamaño Registro 
   cBytes := '00' 
   FRead(nHnd,@cBytes,2) 
   nRecSize := Bin2I(cBytes) 
   // Tamaño Tabla 
   nFileSize := FSeek(nHnd,0,FS_END) 
   // Numero de registros real 
   nRecs := (nFileSize - nHdrSize) / nRecSize 
   // Si el archivo se manipulo con dBase, Fox ... tiene 1 byte mas 
   IF nRecs != Round(nRecs,0) 
      nRecs := (nFileSize - nHdrSize - 1) / nRecSize 
   ENDIF 
   // Si los registros segun la tabla y los calculados no coinciden 
   IF nRecs != nNumRecs 
      cError := "Número de registros incorrecto en fichero " + cNameExt 
      cErrorLog := cError + " en" + CRLF + Trim(cPath) + ' :' + CRLF + CRLF +; 
      " Registros iniciales " + sTr(nNumRecs,7) + CRLF +; 
      " Registros detectados " + sTr(nRecs,7) + CRLF + CRLF +; 
      "Asegúrese de guardar la última copia de seguridad y" + CRLF +; 
      "realice una copia suplementaria ANTES DE corregir el" + CRLF +; 
      "problema." 
      IF MsgNoYes( cErrorLog + CRLF + CRLF +; 
         "¿ Desea corregir el problema ?", "Error de apertura") 
         FSeek(nHnd,4,FS_SET) 
         FWrite(nHnd,L2Bin(Round(nRecs,0)),4) 
         MsgInfo('El problema ha sido corregido.' + CRLF + CRLF +; 
                 'Antes de continuar el uso normal del programa' + CRLF +; 
                 'debe realizarse una "Indexación de ficheros".','Aviso Importante') 
      ENDIF 
   ENDIF 
   FClose(nHnd) 
ENDIF 
RETURN lReturn

function MsgNoYes( mensagem )
    if Alert( mensagem, { "Sim", "Nao" } ) == 1
       return .t.
    endif
    return .f.
    
function MsgInfo( mensagem )
    Alert( mensagem )
    return .t.

Um fato interessante dos problemas encontrados em .DBF relativos a sujeira está relacionado aos caches das estações e ao uso do Internet Explorer.

O uso do IE enquanto se manipula .DBFs faz com que a sujeira dele se misture aos dados das tabelas, sobrepondo registros ou intercalando entre eles.

Encontrar estes caracteres estranhos em campos caracteres e memos é fácil, mas quando os mesmos estão em campos numéricos, data, etc aí complica e as funções triviais não funcionam e quebram.

Friso que somente encontrei estes problemas com o IE, outros browsers não me deram problemas.

Solução:

- Não usar o IE em estações.

- Configurar o cache e a forma de descarrego.

- Melhorar o trato dos Commits()

- Nunca usar pastas TEMP ou TMP como área de descarego do sistema.

- Separar parte da memória como disco virtual( imDiskTK ) e usá-la como cache do sistema.

Link to comment
Share on other sites

Fiz um teste com este programa, abrindo o .dbf pelo editor for DOS, e fui até o fim do arquivo, e tirei algo, o resultado, não me foi satisfatório. Não senti firmeza. Mas como não tenho nenhum arquivo corrompido, fico na dúvida.



// DBFOK.PRG

#include "FiveWin.ch"
#Include "Fileio.Ch"

STATIC oWnd

function Main()

LOCAL cNomeArq, cPath, oBar

cNomeArq := "CUSTOMER.DBF"
cPath := "C:\TESTE"

DEFINE WINDOW oWnd TITLE "Verificar Integridade do DBF"

DEFINE BUTTONBAR oBar _3D OF oWnd

DEFINE BUTTON OF oBar ACTION lOkDbf( cNomeArq, cPath )

SET MESSAGE OF oWnd TO "Verificar Integridade do DBF" ;
NOINSET CLOCK DATE KEYBOARD

ACTIVATE WINDOW oWnd

return nil

FUNCTION lOkDbf( cNomeArq, cPath )

LOCAL lReturn := .T.
LOCAL nHnd, cBytes, nNumRecs, nHdrSize, nRecSize, nFileSize, nRecs
LOCAL cError, cErrorLog

IF FILE( cPath+"\"+cNomeArq )
// ? cNomeArq, cPath, "ARQUIVO ENCONTRADO"
ELSE
? "ARQUIVO NAO LOCALIZADO"
RETURN( .F. )
ENDIF

// Abrimos en exclusiva. Si no es posible, alguien lo esta usando (NO dañado)
IF (nHnd := FOpen(cPath + '\' + cNomeArq, FO_READWRITE + FO_EXCLUSIVE)) > 0

FSeek(nHnd,4,FS_SET)

// Numero registros segun tabla
cBytes := '0000'
FRead(nHnd,@cBytes,4)
nNumRecs := Bin2L(cBytes)

// Tamaño Header
cBytes := '00'
FRead(nHnd,@cBytes,2)
nHdrSize := Bin2I(cBytes)

// Tamaño Registro
cBytes := '00'
FRead(nHnd,@cBytes,2)
nRecSize := Bin2I(cBytes)

// Tamaño Tabla
nFileSize := FSeek(nHnd,0,FS_END)

// Numero de registros real
nRecs := (nFileSize - nHdrSize) / nRecSize
// Si el archivo se manipulo con dBase, Fox ... tiene 1 byte mas

IF nRecs != Round(nRecs,0)
nRecs := (nFileSize - nHdrSize - 1) / nRecSize
ENDIF

// Si los registros segun la tabla y los calculados no coinciden
IF nRecs != nNumRecs
cError := "Número de registros incorretos no arquivo " + cNomeArq
cErrorLog := cError + " em" + CRLF + Trim(cPath) + ' :' +CRLF+CRLF+ ;
" Registros Iniciais: " + sTr(nNumRecs,7) + CRLF +;
" Registros detectados " + sTr(nRecs,7) + CRLF + CRLF +;
"Assegure-se de guardar a ultima copia de seguranca" + CRLF +;
"realize uma copia suplementar antes de corrigir o" + CRLF +;
"problema."

IF MsgNoYes( cErrorLog + CRLF + CRLF +;
"Deseja corrigir o problema ?", "Error de abertura")

FSeek(nHnd,4,FS_SET)
FWrite(nHnd,L2Bin(Round(nRecs,0)),4)

MsgInfo('O problema foi corrigido.' + CRLF + CRLF +;
'Antes de continuar o uso normal do programa' + CRLF +;
'Realize a Indexacao dos arquivos".','Aviso Importante')

ENDIF

ELSE

? cNomeArq+" NAO ESTA CORROMPIDO, DBFOK!"

ENDIF

FClose(nHnd)

ENDIF

RETURN lReturn

function MsgNoYes( mensagem )

if Alert( mensagem, { "Sim", "Nao" } ) == 1
return .t.
endif

return .f.

function MsgInfo( mensagem )

Alert( mensagem )

return .t.


abs

Link to comment
Share on other sites

Oi Kapi!

"fui até o fim do arquivo, e tirei algo, o resultado, não me foi satisfatório."

Isso parece lógica FUZZY (tem explicação no wikipedia) :-))

Esta rotina que o Rochinha postou, só verifica se o número de registros reais (tam.-do-arquivo - tam.-header) / tam.registro é igual a valor do número de registros cadastrados no header (se não for igual, tem a opção de corrigir).

Anexei um arquivo DBF (modificado) para V. testar.
[ ]'s, Euclides
POW! Agora que eu vi a mensagem:
"Você não tem permissão para fazer upload deste tipo de arquivo"
(é só 'abrir' um arquivo DBF com um editor-hexa e alterar o valor na posição # 4)
Sorry
Link to comment
Share on other sites

Oi Kapi!

"fui até o fim do arquivo, e tirei algo, o resultado, não me foi satisfatório."

Isso parece lógica FUZZY (tem explicação no wikipedia) :-))

Esta rotina que o Rochinha postou, só verifica se o número de registros reais (tam.-do-arquivo - tam.-header) / tam.registro é igual a valor do número de registros cadastrados no header (se não for igual, tem a opção de corrigir).

Anexei um arquivo DBF (modificado) para V. testar.
[ ]'s, Euclides
POW! Agora que eu vi a mensagem:
"Você não tem permissão para fazer upload deste tipo de arquivo"
(é só 'abrir' um arquivo DBF com um editor-hexa e alterar o valor na posição # 4)
Sorry

kkkkkkkkkkkkkkkkkk, peça autorização ao Gilmer para permissão de UpLoad Euclides. Obg. abs.

Envie-me o DBF modificado em: joao@pleno.com.br email/skype - abs.

Link to comment
Share on other sites

Pessoal...

Ainda não tive tempo de realizar os testes...

Más pelo visto, o tema é por demais complicado.

Tentarei testar neste final de semana, depois reporto os resultados.

Por enquanto, obrigados à todos que se envolveram.

Abração.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...