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:
Por:
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:
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:
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:
Arquivo .DBF:
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