Importar arquivo CSV para DBF

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

thekey
Usuário Nível 1
Usuário Nível 1
Mensagens: 33
Registrado em: 17 Abr 2008 16:37
Localização: Governador Valadares MG

Importar arquivo CSV para DBF

Mensagem por thekey »

Olá galera, não sou um bom colaborador do Fórum, pois só visito quando o bicho tá pegando.
Mas sempre que procuro algo que não acho. Eu posto a solução quando descubro aqui.
Espero que este belíssimo fórum, que muito me ajuda, se perpetue por muito tempo.

Ao assunto, sobre CSV to DBF, eu estava procurando uma FUNÇÃO que o fizesse automaticamente e não encontrei aqui.

Verifiquei que várias das soluções postadas, não tinham características de uma verdadeira função para usarmos na conversão.

Assim criei abaixo uma função chamada CsvToDBF().
Ela cria o DBF destino com nomes de campos genericos servido para qualquer conteudo do CSV.
Ela cria automaticamente a estrutura basica do DBF destino temporario. Podendo o programador utilizar este DBF temporario do jeito que quiser.
Segue:

Código: Selecionar todos

******************************************************
func CsvToDbf(vvvCSV,vvvCabec,vvvSeparador,vvvTamMax)
******************************************************
*Converte .CSV para .DBF. com opcao de criar
*campos com mesmo nome dos cabecalhos, ou com
*nomes de campos apenas numerados.
*ONDE:   vvvCSV        Nome do ARQUIVO.CSV ou Outro Tipo .TXT 
*        vvvCabec      .t. Ler 1a linha  (Padrao)  
*                      .f. Nao ler 1a Linha 
*        vvvSeparador  Sinal Separador, padrao (;)
*        vvvTamMax     Tamanho maximo dos campos padrao (20) 
*
*Utiliza AREA PROVISORIA 7 (Select 7).
*Retorna .t. ou .f. se conversao for sucesso ou erro.
**************************************************************
//Guardando Area corrente
vvvarea0=alltrim(str(select(dbf())))

vvvCSV=upper(vvvCSV)
if vvvTamMax=nil
   vvvTamMax=20
Endif
if at(".CSV",vvvCSV)=0
   vvvCSV=vvvCSV+".CSV"
endif
vvvDBF=strtran(vvvCSV,".CSV",".DBF")
if file(vvvDBF)
   //Se ja existir DBF com o nome do CSV retorne erro.
   return .f.
endif
If vvvSeparador=Nil
   vvvSeparador=";"
Endif
if vvvCabec=nil
   vvvCabec=.t.
endif

//Criando Estrutura do DBF Destino
vvvhCSV=fopen(vvvCSV)
vvvContaCampo=1
vvvLinha=freadLine(vvvhCSV)
vvvEstrut={}
vvvFinalizar=.f.
do while .t.
   if at(vvvSeparador,vvvLinha)=0
      vvvFinalizar=.t.
   endif
   vvvCampo="CAMPO"+strzero(vvvContaCampo,3)
   aadd(vvvEstrut,{vvvCampo,"C",vvvTamMax,0})
   vvvLinha=right(vvvlinha,len(vvvLinha)-at(vvvSeparador,vvvLinha))
   vvvContaCampo++
   if vvvFinalizar=.t.
      exit
   Endif
Enddo
dbcreate(vvvDBF,vvvEstrut)
fclose(vvvhCSV)

//Preenchendo novo DBF
Select 7
use &vvvDBF

//O Comando abaixo poderia ser utilizado finalizando
//a funcao neste ponto. Porem, encontro problemas na importacao quando
//existe algum caractere estranho dentro do CSV. Como por exemplo Alt+160.
//comando: Append From &vvvCSV DELIMITED WITH ({,vvvSeparador})
     
vvvhCSV=fopen(vvvCSV)
vvvContaCampo=1
vvvLinha=freadLine(vvvhCSV)
vvvFinalLinha=.f.
vvvContaLinha=1
do while .not. feof(vvvhCSV)
   if at(vvvSeparador,vvvLinha)=0
      vvvLinha=vvvLinha+vvvSeparador
      vvvFinalLinha=.t.
   endif
   vvvCampo="CAMPO"+strzero(vvvContaCampo,3)
   vvvConteudo = left(vvvLinha,at(vvvSeparador,vvvLinha)-1)
   vvvLinha=right(vvvlinha,len(vvvLinha)-at(vvvSeparador,vvvLinha))
   if lastrec() < vvvContalinha
      append blank
   Endif
   replace &vvvCampo with vvvConteudo
   vvvContaCampo++
   If vvvFinalLinha=.t.
      vvvLinha=freadLine(vvvhCSV)
      vvvContaCampo=1
      vvvFinalLinha=.f.
      vvvContaLinha++
   endif
Enddo
Close
fclose(vvvhCSV)
Select &vvvArea0


paiva
Usuário Nível 3
Usuário Nível 3
Mensagens: 300
Registrado em: 04 Ago 2005 10:28

Importar arquivo CSV para DBF

Mensagem por paiva »

Itamar BOM dia

Aproveitando rs

dbDrop("mem:"+cArqTmp,,"DBFCDX") //Apaga DBF na memória se existir
05 DbCreate("mem:"+cArqTmp,aDbStrut,'DBFCDX',.T.,"tmp") //Cria e abre DBF temporário

para criar em Memoria basta colcoar Mem:\usr\sfa\indice01.cdx ?

poderia corrigir/modificar no que uso atualmente ?

set index to
xerase = pdir+alltrim(pusuario)
erase &xerase

ofiltro = .....

if !empty(ofiltro)
ofiltro = ofiltro + " .and. crpedf->dt_fatura > tdtini_filtro .and. crpedf->dt_fatura < tdtfim_filtro "
else
ofiltro = ofiltro + "crpedf->dt_fatura > tdtini_filtro .and. crpedf->dt_fatura < tdtfim_filtro "
endif
*set filter to &Ofiltro
index on empresa+filial+gmprod->nome+pedido to &xerase for &ofiltro
set index to &xerase

quero ver se funciona/melhora na minha versao do xhb (bem antiga ) rs

desde já agradeço

Paiva
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Importar arquivo CSV para DBF

Mensagem por alxsts »

Olá!

Para usar DBF em memória, precisa adicionar a linha abaixo no início do teu PRG:

Código: Selecionar todos

REQUEST HB_MEMIO  // <=== esta linha
REQUEST DBFCDX

PROCEDURE Main()
  
   LOCAL ...
.

Na compilação, incluir hbmemio.hbc

Código: Selecionar todos

Em Harbour:
hbmk2 teste hbmemio.hbc
Como você diz que usa xHarbour antigo, não sei se vai dar certo...
[]´s
Alexandre Santos (AlxSts)
paiva
Usuário Nível 3
Usuário Nível 3
Mensagens: 300
Registrado em: 04 Ago 2005 10:28

Importar arquivo CSV para DBF

Mensagem por paiva »

boa tarde
nao é DBF queria testar a geração de INDICE temporário em Memoria.

Paiva
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Importar arquivo CSV para DBF

Mensagem por alxsts »

Olá!

Veja se ajuda:

Código: Selecionar todos

REQUEST HB_MEMIO
REQUEST DBFCDX

FUNCTION Teste()

   LOCAL aLayOut := {}

   AAdd( aLayOut, { "MEM_COD"  , "C", 010, 000 } )
   AAdd( aLayOut, { "MEM_COMP",  "N", 011, 002 } )
   AAdd( aLayOut, { "MEM_ADI1",  "N", 006, 002 } )
   AAdd( aLayOut, { "MEM_DT1",   "C", 001, 000 } )
   AAdd( aLayOut, { "MEM_BASE",  "N", 011, 002 } )
   AAdd( aLayOut, { "MEM_MGL",   "N", 010, 003 } )
   AAdd( aLayOut, { "MEM_DT2",   "C", 001, 000 } )
   AAdd( aLayOut, { "MEM_UNI",   "N", 011, 002 } )
   AAdd( aLayOut, { "MEM_ADI2",  "N", 006, 002 } )
   AAdd( aLayOut, { "MEM_DT3",   "C", 001, 000 } )
   AAdd( aLayOut, { "MEM_LIQ",   "N", 011, 002 } )
   AAdd( aLayOut, { "MEM_DES",   "N", 006, 002 } )
   AAdd( aLayOut, { "MEM_DT4",   "C", 001, 000 } )
   AAdd( aLayOut, { "MEM_PROM1", "N", 011, 002 } )
   AAdd( aLayOut, { "MEM_PROM2", "N", 011, 002 } )
   AAdd( aLayOut, { "MEM_SITUA", "C", 030, 000 } )

   RddSetDefault( "DBFCDX" )

   // Cria um DBF...
   // The <lOpenNew> parameter specifies if the already created database is to be opened, and where.
   // If NIL, the file is not opened. If .T. (true), it is opened in a new work area, and if .F. (false)
   // it is opened in the current work area, closing any file already occupying that area. 
   // DbCreate( <cDatabase> , ;
   //           <aStructure>, ;
   //          [<cDriver>]  , ;
   //          [<lNewArea>] , ;
   //          [<cAlias>]     ) --> NIL

   DbCreate( "mem:Teste.DBF", aLayOut, "DBFCDX" , .T., "Teste" )

   // Criar índice em memória
   // OrdCreate( <cIndexFile> , ;
   //           [<cIndexName>], ;
   //            <cIndexExpr> , ;
   //            <bIndexExpr> , ;
   //           [<lUnique>]     ) --> NIL

   OrdCreate( "mem:Teste, "mem_cod", "mem_cod"  )

   Browse()

   DbCloseArea()

   DbDrop( "mem:Teste.DBF", "DBFCDX" )  /* Free memory resource */
   DbDrop( "mem:Teste.CDX", "DBFCDX" )  /* Free memory resource */

RETURN NIL
Nunca tentei criar um índice em memória para um DBF em disco. Tente aí e retorne...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Importar arquivo CSV para DBF

Mensagem por JoséQuintas »

Tem que forçar a linquedição da lib, acho que é hbmemio.hbc ou algo assim.
Sem linqueditar a LIB não funciona.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Importar arquivo CSV para DBF

Mensagem por alxsts »

Olá!
JoséQuintas escreveu:Sem linqueditar a LIB não funciona.
Isto sabemos.
paiva escreveu:quero ver se funciona/melhora na minha versao do xhb (bem antiga ) rs
Minha dúvida é saber se no xHarbour dá para usar os arquivos .Hbc... sei que dá pra usar HbMk2. Sendo assim, deve dar para usar os .Hbc. O padrão do xHarbour é compilar com HbMake. Aí é que não sei se vai funcionar...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Importar arquivo CSV para DBF

Mensagem por JoséQuintas »

Acabei respondendo o que já estava respondido.

Quanto a usar HBC no XHarbour e HBMK2, dá pra usar, mas como não é ferramenta padrão pra ele, nem devem existir arquivos HBC.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder