Página 2 de 2

Importar arquivo CSV para DBF

Enviado: 04 Jun 2023 14:20
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



Importar arquivo CSV para DBF

Enviado: 05 Jun 2023 11:06
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

Importar arquivo CSV para DBF

Enviado: 05 Jun 2023 15:51
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...

Importar arquivo CSV para DBF

Enviado: 06 Jun 2023 13:50
por paiva
boa tarde
nao é DBF queria testar a geração de INDICE temporário em Memoria.

Paiva

Importar arquivo CSV para DBF

Enviado: 06 Jun 2023 14:32
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...

Importar arquivo CSV para DBF

Enviado: 06 Jun 2023 16:01
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.

Importar arquivo CSV para DBF

Enviado: 06 Jun 2023 17:12
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...

Importar arquivo CSV para DBF

Enviado: 06 Jun 2023 21:21
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.