Rotina de importação .XLS para .DBF

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Rotina de importação .XLS para .DBF

Mensagem por Paulo_CPV »

Boa tarde!

Estou desenvolvendo uma rotina de importação de uma planilha Excel para .DBF, mais está dando um erro de "Tipo incorreto de dado".

Código:

Código: Selecionar todos

 METHOD ImportaDB001() CLASS Arquivo

   LOCAL cNit001,cNit002,cNit003,cNit004  // Numero Nit
   LOCAL cMat001,cMat002,cMat003,cMat004  // Matricula
   LOCAL nVal001,nVal002,nVal003,nVal004  // Valor R$
   
   LOCAL cBase1 := ALLTRIM(oSistema:BancodeDados()+"Fluxo201301"+".xls")
   LOCAL cBase2 := ALLTRIM(oSistema:BancodeDados()+"Db004"+".dbf")
   LOCAL cBase3 := ALLTRIM(oSistema:BancodeDados()+"IndValor"+".cdx")
   
   LOCAL nCont := rCont := 0 , nLin , nCol , oExcel , oPlanilha , oCelulas
   LOCAL i := 2 , j , nLimite , c , sai := .T.
   
   oExcel := TOleAuto():New( "Excel.Application" )

   IF oExcel == NIL

      MsgStop('Excel não está instalado!','Erro')
      RETURN NIL

   ENDIF
   
   oPlanilha := oExcel:WorkBooks:Open( cBase1 )
   oCelulas := oExcel:Get( "ActiveSheet" )

   nLin := oCelulas:UsedRange:Rows:Count()
   nCol := oCelulas:UsedRange:Columns:Count()

   IF !FILE( ( cBase2 ) )

      ::AbrirArquivo("Db0004","IndValor",4,"Fluxo")

   ELSE

      DELETE FILE &cBase2
      DELETE FILE &cBase3

      ::AbrirArquivo("Db0004","IndValor",4,"Fluxo")

   ENDIF
   
   FOR j = 2 TO nLin

      c := oSistema:FormatoDados(oCelulas:Cells(j , 1):Value)
      
      IF EMPTY(c)

         nCont++
      
      ENDIF
   
   NEXT j
   
   nLimite := nLin - nCont
   
   i := 2
   
   WHILE sai
   
      ++rCont
      
      ImportaDados.progressbar_1.Value := Int(rCont/nLimite*100)
      ImportaDados.label_4.Value := STR(INT(rCont/nLimite*100)) + " %"
      ImportaDados.label_3.Value := STRZERO(i,6)
      
      cNit001 := oCelulas:Cells(i , 1):Value 
      cMat001 := oCelulas:Cells(i , 2):Value 
      nVal001 := oCelulas:Cells(i , 3):Value 
      
      cNit002 := oCelulas:Cells(i , 4):Value 
      cMat002 := oCelulas:Cells(i , 5):Value 
      nVal002 := oCelulas:Cells(i , 6):Value 
      
      cNit003 := oCelulas:Cells(i , 7):Value 
      cMat003 := oCelulas:Cells(i , 8):Value 
      nVal003 := oCelulas:Cells(i , 9):Value 
      
      cNit004 := oCelulas:Cells(i , 10):Value
      cMat004 := oCelulas:Cells(i , 11):Value
      nVal004 := oCelulas:Cells(i , 12):Value

      Fluxo->(DBAppend())
      
      Fluxo->C_001 := cNit001
      Fluxo->C_002 := cMat001
      Fluxo->C_003 := nVal001
      
      Fluxo->(DBSkip())
      
      Fluxo->C_001 := cNit002
      Fluxo->C_002 := cMat002
      Fluxo->C_003 := nVal002
      
      Fluxo->(DBSkip())
      
      Fluxo->C_001 := cNit003
      Fluxo->C_002 := cMat003
      Fluxo->C_003 := nVal003
      
      Fluxo->(DBSkip())

      Fluxo->C_001 := cNit004
      Fluxo->C_002 := cMat004
      Fluxo->C_003 := nVal004
      
      IF i = nLimite
      
         EXIT
      
      ENDIF
      
      Fluxo->(DBSkip())
      i++
   
   END

   oPlanilha:Close()
   oExcel:Quit()

RETURN NIL
Estrutura do .DBF

Código: Selecionar todos

Aadd( aarq , { 'C_001'  ,  'C'   ,  11  ,  0 } )
         Aadd( aarq , { 'C_002'  ,  'C'   ,  06  ,  0 } )
         Aadd( aarq , { 'C_003'  ,  'N'   ,  10  ,  2 } ) <---- erro aqui 
O erro está ocorrendo quando ele vai gravar no .DBF. Alguém pode me dar uma dica de como resolver este impasse?

[]'s
Paulo - Jacarei/SP
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Rotina de importação .XLS para .DBF

Mensagem por Toledo »

Amigo, como o código que você postou não tem como compilar, pois depende de outras rotinas do seu programa, fica um pouco complicado de verificar o motivo do erro. Mas de acordo com o tipo do campo Fluxo->C_003 do seu DBF, podemos presumir que em algum momento o conteúdo das variáveis nVal001, nVal002, nVal003 e nVal004 não é numérico, então você teria que verificar se o limite (nLimite) de dados do arquivo XLS não está sendo ultrapassado e pegando alguma célula vazia. Se isto não estiver ocorrendo, então você poderia tentar o seguinte:

Troque:

Código: Selecionar todos

Fluxo->C_003 := nVal001
Por:

Código: Selecionar todos

Fluxo->C_003 := Val(nVal001)
Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Rotina de importação .XLS para .DBF

Mensagem por Paulo_CPV »

Boa tarde, Toledo!

Fiz as modificações necessários e deu certo, mas agora estou com outro dilema aqui, no arquivo do Excel eu tenho uma coluna chamada Matricula onde está o número de matricula dos Servidores e quando é passada para o .DBF ele está colocando ponto no número, pois a matricula é número inteiro e no Excel a coluna está formata como texto.

Exemplo:

Código: Selecionar todos

Arquivo Excel     Arquivo .DBF

266                   266.00
5060                 5060.
Será que você pode me dar uma dica de como resolver este problema? Você pode me dizer também o que eu faço para fechar o arquivo Excel corretamente, pois quando eu vou mexer no mesmo arquivo que eu utilizei par importação ele me dá uma mensagem que o arquivo é somente de leitura, o que eu tenho que fazer? Utilizo da seguinte forma para fechar o arquivo.

Código: Selecionar todos

oExcel := TOleAuto():New( "Excel.Application" )
oPlanilha := oExcel:WorkBooks:Open( "Fluxo201301.xls" )
.
.
.
   oPlanilha:Close()
   oExcel:Quit()
[]'s
Paulo - Jacareí/SP
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Rotina de importação .XLS para .DBF

Mensagem por Toledo »

Paulo_CPV escreveu:quando é passada para o .DBF ele está colocando ponto no número
Bom, neste caso é só tratar o valor da variável cMat001 antes de gravar no DBF:

Código: Selecionar todos

cMat001:=alltrim(str(int(val(cMat001))))
Paulo_CPV escreveu:o que eu faço para fechar o arquivo Excel
Tenta o seguinte:

Código: Selecionar todos

oExcel := TOleAuto():New( "Excel.Application" )
oExcel:WorkBooks:Open( "Fluxo201301.xls" )
.
.
.
   oExcel:ActiveWorkbook:Close()
   oExcel:Quit()
Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Rotina de importação .XLS para .DBF

Mensagem por Paulo_CPV »

Bom dia!

Obrigado Toledo pelas suas dicas funcionaram sem problemas. Mais uma dúvida me surgiu, como eu seleciono uma aba do arquivo em Excel? Por exemplo:

Eu tenho:

Plan01 Plan02 Plan03

Eu quero por exemplo pegar o conteúdo da aba Plan02. Como eu posso fazer isso?


Abraços,

Paulo - Jacareí/SP
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Rotina de importação .XLS para .DBF

Mensagem por Toledo »

Amigo, faz o seguinte:

Código: Selecionar todos

oExcel:Sheets("Plan02"):Select()
oSheet:=oExcel:ActiveSheet()
Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Rotina de importação .XLS para .DBF

Mensagem por Paulo_CPV »

Bom dia!

Amigo Toledo, mais uma vez muito obrigado pela sua ajuda. Deu tudo certo.

Abraços,

Paulo - Jacareí/SP
Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Rotina de importação .XLS para .DBF

Mensagem por Paulo_CPV »

Boa tarde!

Caros colegas do grupo, eu estou criando uma rotina de importação de dados do Excel para o .DBF, a rotina está funcionando quase perfeita, só que ela agora está incluindo registros a mais. Por exemplo: Eu tenho uma planilha com 131 linhas e com 16 colunas. Sendo:

Código: Selecionar todos

Col1      Col2      Col3      Col4      Col5      Col6     Col7      Col8
         Comp.   NIT         Mat.    Valor     Comp.   NIT      Mat.     Valor

         Col9     Col10     Col11     Col12     Col13    Col14    Col15   Col16
         Comp.  NIT        Mat.      Valor      Comp.  NIT       Mat.    Valor
Estou utilizando a seguinte rotina:

Código: Selecionar todos

METHOD ImportaDB001() CLASS Arquivo // Importacao de fluxo de compensacao

   LOCAL cNit001,cNit002,cNit003,cNit004  // Numero Nit
   LOCAL cMat001,cMat002,cMat003,cMat004  // Matricula
   LOCAL nVal001,nVal002,nVal003,nVal004  // Valor R$
   LOCAL cComp01,cComp02,cComp03,cComp04  // Competencia
   
   LOCAL cBase1 , cBase2 , cBase3     // Diretorios dos arquivos
   
   LOCAL nCont := rCont := 0 , nLin , nCol , oExcel , oPlanilha , oCelulas
   LOCAL i , j , nLimite , c , sai := .T. , cAno
   
   cAno  := STR( YEAR( DATE() ) - 1 , 0 )

   cBase1 := oSistema:BancoDadosExcel() + ALLTRIM(cAno) + "\" + ALLTRIM("Fluxo2013.xls")
   cBase2 := oSistema:BancodeDados()   + ALLTRIM("Db004.dbf")
   cBase3 := oSistema:BancodeDados()   + ALLTRIM("IndValor.cdx")
 
   oExcel := TOleAuto():New( "Excel.Application" )

   IF oExcel == NIL

      MsgStop('Excel não está instalado!','Erro')
      RETURN NIL

   ENDIF
   
   oPlanilha := oExcel:WorkBooks:Open( cBase1 )
   oExcel:Sheets("Fev"):Select()
   oPlanilha := oExcel:ActiveSheet()   
   oCelulas  := oExcel:Get( "ActiveSheet" )

   nLin := oCelulas:UsedRange:Rows:Count()
   nCol := oCelulas:UsedRange:Columns:Count()

   IF !FILE( ( cBase2 ) )

      ::AbrirArquivo("Db0004","IndValor",4,"Fluxo")

   ELSE

      DELETE FILE &cBase2
      DELETE FILE &cBase3

      ::AbrirArquivo("Db0004","IndValor",4,"Fluxo")

   ENDIF
   
   FOR j = 2 TO nLin

      c := oSistema:FormatoDados(oCelulas:Cells(j , 1):Value)
      
      IF EMPTY(c)

         nCont++
      
      ENDIF
   
   NEXT j
   
   nLimite := nLin - nCont
   
   i := 2
 
   WHILE sai
   
      ++rCont
      
      ImportaDados.progressbar_1.Value := Int(rCont/nLimite*100)
      ImportaDados.label_4.Value := STR(INT(rCont/nLimite*100)) + " %"
      ImportaDados.label_3.Value := STRZERO(i,6)
//--------------------------------------------------------	  
	  cComp01 := oSistema:FormatoDados(oCelulas:Cells(i , 1):Value)
      
      cNit001 := oSistema:FormatoDados(oCelulas:Cells(i , 2):Value)
      cMat001 := oSistema:FormatoDados(oCelulas:Cells(i , 3):Value)
      nVal001 := oSistema:FormatoDados(oCelulas:Cells(i , 4):Value)
//--------------------------------------------------------	  
	  cComp02 := oSistema:FormatoDados(oCelulas:Cells(i , 5):Value)
      
      cNit002 := oSistema:FormatoDados(oCelulas:Cells(i , 6):Value)
      cMat002 := oSistema:FormatoDados(oCelulas:Cells(i , 7):Value) 
      nVal002 := oSistema:FormatoDados(oCelulas:Cells(i , 8):Value)
//--------------------------------------------------------	  
	  cComp03 := oSistema:FormatoDados(oCelulas:Cells(i , 9):Value)
      
      cNit003 := oSistema:FormatoDados(oCelulas:Cells(i , 10):Value)
      cMat003 := oSistema:FormatoDados(oCelulas:Cells(i , 11):Value)
      nVal003 := oSistema:FormatoDados(oCelulas:Cells(i , 12):Value)
//--------------------------------------------------------	  
	  cComp04 := oSistema:FormatoDados(oCelulas:Cells(i , 13):Value)
      
      cNit004 := oSistema:FormatoDados(oCelulas:Cells(i , 14):Value)
      cMat004 := oSistema:FormatoDados(oCelulas:Cells(i , 15):Value)
      nVal004 := oSistema:FormatoDados(oCelulas:Cells(i , 16):Value)
//--------------------------------------------------------	  
	  cMat001 := ALLTRIM( STR( INT( VAL( cMat001 ) ) ) )
	  cMat002 := ALLTRIM( STR( INT( VAL( cMat002 ) ) ) )
	  cMat003 := ALLTRIM( STR( INT( VAL( cMat003 ) ) ) )
	  cMat004 := ALLTRIM( STR( INT( VAL( cMat004 ) ) ) )
//-------------------------------------------------------- Grava no banco de dados
      Fluxo->(DBAppend())
	  
	  Fluxo->C_000 := cComp01
	  
      Fluxo->C_001 := oSistema:TiraMascaraNit( cNit001 )
      Fluxo->C_002 := cMat001
      Fluxo->C_003 := VAL( nVal001 )
      
      Fluxo->(DBAppend())
	  
	  Fluxo->C_000 := cComp02
	  
      Fluxo->C_001 := oSistema:TiraMascaraNit( cNit002 )
      Fluxo->C_002 := cMat002
      Fluxo->C_003 := VAL( nVal002 )
      
      Fluxo->(DBAppend())
	  
	  Fluxo->C_000 := cComp03
	  
      Fluxo->C_001 := oSistema:TiraMascaraNit( cNit003 )
      Fluxo->C_002 := cMat003
      Fluxo->C_003 := VAL( nVal003 )
      
      Fluxo->(DBAppend())
	  
	  Fluxo->C_000 := cComp04
	  
      Fluxo->C_001 := oSistema:TiraMascaraNit( cNit004 )
      Fluxo->C_002 := cMat004
      Fluxo->C_003 := VAL( nVal004 )

      IF i = nLimite .AND. ( EMPTY( cComp01 ) .OR. EMPTY( cComp02 ) ;
                          .OR. EMPTY( cComp03 ) .OR. EMPTY( cComp04 ) )
      
         EXIT
         
      ELSE
      
         i++
      
      ENDIF
 
   END

   oExcel:ActiveWorkbook:Close()
   oExcel:Quit()
   
   FECHA_JANELA

RETURN NIL
O que está acontecendo é o seguinte: Quando chega na última linha no caso da planilha é 131 e sai normal sem problemas, mas quando vou ver o arquivo .DBF ela está incluindo dois registros a mais em branco. O que poderia ser isto?

Desde já agradeço quem possa me ajudar em mais está dúvida.

Abraços,

Paulo - Jacareí/SP
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Rotina de importação .XLS para .DBF

Mensagem por Toledo »

Amigo, esta meio confuso este seu código, principalmente as linhas 134 e 135.
Paulo_CPV escreveu:Eu tenho uma planilha com 131 linhas e com 16 colunas
Nestas 131 linhas pode ocorrer de algum linha estar vazia, isto é, com alguma coluna sem preenchimento? Ou se a coluna 1 (col1) estiver preenchida, todas as outras colunas (de col2 a col16) também vão estar?

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Rotina de importação .XLS para .DBF

Mensagem por Paulo_CPV »

Boa noite!

Toledo muito obrigado mesmo pela sua ajuda, estou anexando duas imagens para você ter noção do que está acontecendo.

Planilha Excel:
Planilha.jpg
Arquivo .DBF:
ArquivoDBF.jpg
Espero que auxilie você a me dizer o que está acontecendo.

Abraços,

Paulo - Jacareí/SP
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Rotina de importação .XLS para .DBF

Mensagem por Toledo »

Paulo_CPV escreveu:mas quando vou ver o arquivo .DBF ela está incluindo dois registros a mais em branco.
Quando vi as linhas 134 e 135 do seu código, notei que no mínimo seria incluído 4 registros em branco no DBF, e até pensei que ficaria num loop infinito. Mas como você dizia que foi incluído apenas 2 registros, estranhei e fiquei meio confuso com o código. Bom, agora vendo as imagens que você postou, podemos perceber que 6 registros em branco foram incluídos.

Para corrigir, altere no seu código as linhas 101 até 141 pelo código abaixo:

Código: Selecionar todos

//-------------------------------------------------------- Grava no banco de dados
     If Empt(cComp01)
      Exit
     Endif

     Fluxo->(DBAppend())
     Fluxo->C_000 := cComp01
     Fluxo->C_001 := oSistema:TiraMascaraNit( cNit001 )
     Fluxo->C_002 := cMat001
     Fluxo->C_003 := VAL( nVal001 )
      
     If !Empt(cComp02)
      Fluxo->(DBAppend())
      Fluxo->C_000 := cComp02
      Fluxo->C_001 := oSistema:TiraMascaraNit( cNit002 )
      Fluxo->C_002 := cMat002
      Fluxo->C_003 := VAL( nVal002 )
     Endif
 
     If !Empt(cComp03)
      Fluxo->(DBAppend())
      Fluxo->C_000 := cComp03
      Fluxo->C_001 := oSistema:TiraMascaraNit( cNit003 )
      Fluxo->C_002 := cMat003
      Fluxo->C_003 := VAL( nVal003 )
     Endif

     If !Empt(cComp04) 
      Fluxo->(DBAppend())
      Fluxo->C_000 := cComp04
      Fluxo->C_001 := oSistema:TiraMascaraNit( cNit004 )
      Fluxo->C_002 := cMat004
      Fluxo->C_003 := VAL( nVal004 )
     Endif

     i++
E com estas alterações, as linhas 49 até 61 do seu código não serão necessárias.

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Rotina de importação .XLS para .DBF

Mensagem por Toledo »

Amigo, só uma correção.

As linhas as linhas 49 até 61 são necessárias sim, por causa da apresentação do Progressbar.

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Rotina de importação .XLS para .DBF

Mensagem por Paulo_CPV »

Bom dia!

Toledo, mas uma vez muito obrigado pela sua ajuda. Agora está funcionando 100%.

Abraços,

Paulo - Jacareí/SP
Responder