Clipper On Line • Ver Tópico - Rotina de importação .XLS para .DBF

Rotina de importação .XLS para .DBF

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

 

Rotina de importação .XLS para .DBF

Mensagempor Paulo_CPV » 06 Mar 2014 15:48

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:

 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

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
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Rotina de importação .XLS para .DBF

Mensagempor Toledo » 06 Mar 2014 18:09

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:
Fluxo->C_003 := nVal001

Por:
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
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Rotina de importação .XLS para .DBF

Mensagempor Paulo_CPV » 07 Mar 2014 15:32

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:

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.

oExcel := TOleAuto():New( "Excel.Application" )
oPlanilha := oExcel:WorkBooks:Open( "Fluxo201301.xls" )
.
.
.
   oPlanilha:Close()
   oExcel:Quit()


[]'s
Paulo - Jacareí/SP
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Rotina de importação .XLS para .DBF

Mensagempor Toledo » 07 Mar 2014 19:06

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:

cMat001:=alltrim(str(int(val(cMat001))))


Paulo_CPV escreveu:o que eu faço para fechar o arquivo Excel

Tenta o seguinte:
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
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Rotina de importação .XLS para .DBF

Mensagempor Paulo_CPV » 10 Mar 2014 00:34

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
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Rotina de importação .XLS para .DBF

Mensagempor Toledo » 10 Mar 2014 07:55

Amigo, faz o seguinte:

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
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Rotina de importação .XLS para .DBF

Mensagempor Paulo_CPV » 10 Mar 2014 11:27

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
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Rotina de importação .XLS para .DBF

Mensagempor Paulo_CPV » 10 Mar 2014 14:30

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:

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:

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
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Rotina de importação .XLS para .DBF

Mensagempor Toledo » 10 Mar 2014 15:45

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
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Rotina de importação .XLS para .DBF

Mensagempor Paulo_CPV » 10 Mar 2014 20:24

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
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Rotina de importação .XLS para .DBF

Mensagempor Toledo » 10 Mar 2014 21:30

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:

//-------------------------------------------------------- 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 de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Rotina de importação .XLS para .DBF

Mensagempor Toledo » 11 Mar 2014 08:16

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
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Rotina de importação .XLS para .DBF

Mensagempor Paulo_CPV » 11 Mar 2014 11:00

Bom dia!

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

Abraços,

Paulo - Jacareí/SP
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez




Retornar para MiniGui

Quem está online

Usuários vendo este fórum: Google [Bot] e 6 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro