Página 1 de 1

Rotina de importação .XLS para .DBF

Enviado: 06 Mar 2014 15:48
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

Rotina de importação .XLS para .DBF

Enviado: 06 Mar 2014 18:09
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,

Rotina de importação .XLS para .DBF

Enviado: 07 Mar 2014 15:32
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

Rotina de importação .XLS para .DBF

Enviado: 07 Mar 2014 19:06
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,

Rotina de importação .XLS para .DBF

Enviado: 10 Mar 2014 00:34
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

Rotina de importação .XLS para .DBF

Enviado: 10 Mar 2014 07:55
por Toledo
Amigo, faz o seguinte:

Código: Selecionar todos

oExcel:Sheets("Plan02"):Select()
oSheet:=oExcel:ActiveSheet()
Abraços,

Rotina de importação .XLS para .DBF

Enviado: 10 Mar 2014 11:27
por Paulo_CPV
Bom dia!

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

Abraços,

Paulo - Jacareí/SP

Rotina de importação .XLS para .DBF

Enviado: 10 Mar 2014 14:30
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

Rotina de importação .XLS para .DBF

Enviado: 10 Mar 2014 15:45
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,

Rotina de importação .XLS para .DBF

Enviado: 10 Mar 2014 20:24
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

Rotina de importação .XLS para .DBF

Enviado: 10 Mar 2014 21:30
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,

Rotina de importação .XLS para .DBF

Enviado: 11 Mar 2014 08:16
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,

Rotina de importação .XLS para .DBF

Enviado: 11 Mar 2014 11:00
por Paulo_CPV
Bom dia!

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

Abraços,

Paulo - Jacareí/SP