Página 1 de 1
Cópia entre bancos de dados
Enviado: 31 Out 2009 10:10
por gilsonpaulo
Novamente eu aqui com mais uma pergunta de principiante.
Tenho dois bancos.:
estoque.dbf
markup,N,6,2
fracao,N,10,3
prdbas.dbf
pc_mark,N,8,3
pc_cncvp,N,11,5
O que preciso fazer:
Código: Selecionar todos
forbas->pc_mark:= estoque->markup
forbas->pc_cncvp:= esoque->fracao
Como fazer esta cópia arrumando estas decimais.
Porque pela diferenca de decimais da erro de data type error na hora da cópia.
Re: Cópia entre bancos de dados
Enviado: 31 Out 2009 11:12
por gvc
Deve estar dando erro com esses campos:
fracao,N,10,3
pc_cncvp,N,11,5
O tamanho de inteiros em fracao é maior que a de pc_cncvp.
De inicio, eu tentaria usar variáveis de memória.
_mark := estoque->markup
_fracao := estoque->fracao
forbas->pc_mark:= _markup
forbas->pc_cncvp:= _fracao
Vc tb pode tentar:
forbas->pc_mark := val(str(estoque->markup, 8, 3))
forbas->pc_cncvp := val(str(estoque->fracao, 11, 5))
Eu estou imaginando que é um erro de digitação:
forbas->pc_cncvp:= esoque->fracao
Re: Cópia entre bancos de dados
Enviado: 31 Out 2009 11:31
por gilsonpaulo
Com variaveis de memória tambem deu erro, mas vou tentar com val(str())
Re: Cópia entre bancos de dados
Enviado: 31 Out 2009 12:01
por Toledo
Amigos, geralmente a mensagem de erro "data type error" quer dizer que os campos são de tipos (caracter, numérico, data, lógico) incompativeis. Eu acho que o fato dos campos terem apenas o tamanho diferentes, não ia gerar este erro. O máximo os valores seriam truncados.
Nos campos (fracao,N,10,3) e (pc_cncvp,N,11,5) os valores inteiro poderiam truncar, por exemplo:
O campo fracao pode receber o máximo o valor: 999999.999
Agora no campo pc_cncvp o máximo seria: 99999.99999
Neste exemplo, o valor inteiro para fracao poderia chegar a 999 mil e 999, enquanto em pc_cncvp seria de 99 mil 999. Então se você atribuir o valor de 999999 no campo pc_cncvp, iria truncar o valor e iria aparecer um monte de asteríscos.
Abraços
Re: Cópia entre bancos de dados
Enviado: 31 Out 2009 14:43
por PAULO S
Concordo com o Toledo.
Para campos numéricos de tamanhos diferentes não deveria dar este tipo de mensagem de erro.
Provavelmente esta mensagem refere-se a tipos diferentes de campos.
Portanto deve-se verificar se não existe este tipo de incompatibilidade durante o processo de cópia.
Re: Cópia entre bancos de dados
Enviado: 31 Out 2009 15:19
por gvc
Concordo com o mestre Toledo.
Mas os campos são numéricos, assim não me preocupei com isso.
O que reparei mas não relatei, é que o nome do DBF esta diferente do ALIAS utilizado. (prdbas e forbas)
Pode ser até outro arquivo, mas é o [gilsonpaulo] que terá que verificar e informar.
Re: Cópia entre bancos de dados
Enviado: 01 Nov 2009 09:22
por gilsonpaulo
Desculpe, foi erro meu de digitação.
Código: Selecionar todos
prdbas->pc_mark:= estoque->markup
prdbas->pc_cncvp:= estoque->fracao
Mas na rotina do sistema esta correta a digitação.
To quebrando a cabeça ate agora.
Re: Cópia entre bancos de dados
Enviado: 01 Nov 2009 12:06
por gvc
Mande as estruturas dos arquivos e a parte do fonte que faz a atualização. Eu gostaria de testar.
gvcortez@uol.com.br
Re: Cópia entre bancos de dados
Enviado: 01 Nov 2009 14:20
por alxsts
Olá!
Gilson:
Achei estranho este erro. Tem certeza que não é
Data width error? Se for mesmo
Data type error, verifique se o erro não é em outra linha.
prdbas->pc_cncvp:= estoque->fracao
prdbas->pc_cncvp, N, 11, 5 estoque->fracao, N, 10, 3
Em Clipper, quando você cria um campo numérico, 11,5, quer dizer que ele tem 11 bytes no total, sendo 5 inteiros, 5 decimais e mais o ponto decimal, que conta também.
Assim, o campo estoque->fração (N,10,3) tem 10 bytes, sendo 6 inteiros, três decimais e o ponto decimal. Quando você move os dados, a parte inteira do campo fração não cabe na parte inteira do campo pc_cncvp. A solução é aumentar este campo para, no mínimo 13,5. Veja o exemplo:
Código: Selecionar todos
PROCEDURE DbCopy()
// Clipper DbCopy /n/w
Local nFor
SetColor( "B/W, W+/B" )
DbCreate( "Estoque", { { "Markup", "N", 6, 2 }, { "Fracao", "N", 10, 3 } } )
DbCreate( "Prdbas" , { { "Pc_Mark", "N", 8, 3 }, { "Pc_Cncvp", "N", 13, 5 } } )
Use Prdbas Shared New
Use Estoque Shared New
FOR nFor := 1 TO 10
Estoque->( DbAppend() )
Estoque->Markup := 123.45
Estoque->Fracao := 123456.789
NEXT
Estoque->( DbGoTop() )
WHILE Estoque->( ! Eof() )
prdbas->( DbAppend() )
prdbas->pc_mark:= estoque->markup
prdbas->pc_cncvp:= estoque->fracao
Estoque->( DbSkip() )
ENDDO
Prdbas->( DbGoTop(), Browse() )
DbCloseAll()
FErase( "Estoque.Dbf" )
FErase( "Prdbas.Dbf" )
__Quit()
//------------------------------------------------------------------------------
No exemplo acima, se você trocar a linha:
Código: Selecionar todos
DbCreate( "Prdbas" , { { "Pc_Mark", "N", 8, 3 }, { "Pc_Cncvp", "N", 13, 5 } } )
por:
Código: Selecionar todos
DbCreate( "Prdbas" , { { "Pc_Mark", "N", 8, 3 }, { "Pc_Cncvp", "N", 11, 5 } } )
vai ganhar de presente um erro
Data width error.
Re: Cópia entre bancos de dados
Enviado: 01 Nov 2009 15:28
por gilsonpaulo
O grande problema é que os dois sistemas não são meus, só fui chamado para fazer a importação dos dados de um sistema para o outro, sendo assim não posso alterar a estrutura dos bancos.
O que estive pensando seria em converter o campo para caracter com str(campo) e depois com alguma função adicionar as casa decimais que estão faltando e reconverter os dados para numericos.
Re: Cópia entre bancos de dados
Enviado: 01 Nov 2009 15:30
por gilsonpaulo
Mande as estruturas dos arquivos e a parte do fonte que faz a atualização. Eu gostaria de testar.
Gvc, assim que chegar em casa lhe passo os bancos.
Re: Cópia entre bancos de dados
Enviado: 01 Nov 2009 22:03
por alxsts
Olá!
Quando você move os dados, a parte inteira do campo fração não cabe na parte inteira do campo pc_cncvp.
Será que vai adiantar converter o campo para
string e modificar a parte fracionária? Continuo pensando que o problema é o estouro da capacidade do campo, em sua parte inteira. Se fizer o que está pensando, vai redundar no mesmo erro... Não é possível entrar em contado com o fornecedor do programa e reportar o problema? Talvez com uma conversa você consiga alterar a estrutura do DBF.
E o erro: é
Data width error ou
Data type error?
Re: Cópia entre bancos de dados
Enviado: 04 Nov 2009 15:13
por gilsonpaulo
Turma resolvi o problema.:
Não esta todo pronto, mas resolvi o problema com as decimais
Código: Selecionar todos
#include 'common.ch'
#include 'inkey.ch'
#include 'setcurs.ch'
function main()
clear screen
select 1
use fornec exclusive alias fornec new
if neterr()
ope=MsgBox1("Erro na abertura exclusiva do arquivo FORNEC")
if ope = 1
close all
return
endif
endif
go top
index on cgc to icgcfor
set index to icgcfor
select 2
use estoque exclusive alias estoque new
if neterr()
ope=MsgBox1("Erro na abertura exclusiva do arquivo ESTOQUE")
if ope = 1
close all
return
endif
endif
go top
index on codprod to icodprod
set index to icodprod
select 3
use clientes exclusive alias clientes new
if neterr()
ope=MsgBox1("Erro na abertura exclusiva do arquivo CLIENTES")
if ope = 1
close all
return
endif
endif
go top
index on cgc to icgccli
set index to icgccli
select 4
use forbas.d40 exclusive alias forbas new
if neterr()
ope=MsgBox1("Erro na abertura exclusiva do arquivo FORBAS")
if ope = 1
close all
return
endif
endif
go top
index on nr_cgcpf to inrcgcpff
set index to inrcgcpff
select 5
use prdbas.d40 exclusive alias prdbas new
if neterr()
ope=MsgBox1("Erro na abertura exclusiva do arquivo PRDBAS")
if ope = 1
close all
return
endif
endif
go top
index on cd_prd to icdprdba
set index to icdprdba
select 6
use prdest.d40 exclusive alias prdest new
if neterr()
ope=MsgBox1("Erro na abertura exclusiva do arquivo PRDEST")
if ope = 1
close all
return
endif
endif
go top
index on cd_prd to icdprdes
set index to icdprdes
select 7
use clibas.d40 exclusive alias clibas new
if neterr()
ope=MsgBox1("Erro na abertura exclusiva do arquivo CLIBAS")
if ope = 1
close all
return
endif
endif
go top
index on nr_cgcpf to inrcgcba
set index to inrcgcba
select 8
use clidet.d40 exclusive alias clidet new
if neterr()
ope=MsgBox1("Erro na abertura exclusiva do arquivo CLIDET")
if ope = 1
close all
return
endif
endif
go top
index on nr_cgcpf to inrcgcde
set index to inrcgcde
ope=MsgBox2("Deseja executar a convers„o da base de dados?")
if ope=2
close all
return
endif
select fornec
go top
set color to gr+/b,gr+/b
@ 11,01 clear to 13,78
@ 11,01 to 13,78 color "gr+/b"
do while .not. eof()
select forbas
go top
seek padl(strtran(strtran(strtran(fornec->cgc,"."),"-"),"/"),15," ")
if found()
@ 12,02 say "Atualizando.:FORBAS->"+" "+rtrim(fornec->fornecedor) color "gr+/b"
if rlock()
forbas->nr_cgcpf:= strtran(strtran(strtran(fornec->cgc,"."),"-"),"/")
forbas->nr_doc:= strtran(strtran(strtran(fornec->ie,"."),"-"),"/")
forbas->ds_razsc:= fornec->fornecedor
forbas->ds_fanta:= fornec->fantasia
forbas->ds_end:= fornec->endereco
forbas->nr_cep:= strtran(strtran(fornec->cep,"-"),"/")
forbas->ds_munic:= fornec->cidade
forbas->id_ufemis:= fornec->estado
forbas->cd_uf:= fornec->estado
forbas->nr_fone:= fornec->telefone
forbas->nr_fax:= fornec->fax
forbas->cd_for:= str(fornec->codigo)
forbas->ds_email:= fornec->e_mail
forbas->ds_site:= fornec->homepage
forbas->ds_bair:= fornec->bairro
unlock
endif
else
@ 12,02 say "Incluindo...:FORBAS->"+" "+rtrim(fornec->fornecedor) color "gr+/b"
append blank
if rlock()
forbas->nr_cgcpf:= strtran(strtran(strtran(fornec->cgc,"."),"-"),"/")
forbas->nr_doc:= strtran(strtran(strtran(fornec->ie,"."),"-"),"/")
forbas->ds_razsc:= fornec->fornecedor
forbas->ds_fanta:= fornec->fantasia
forbas->ds_end:= fornec->endereco
forbas->nr_cep:= strtran(strtran(fornec->cep,"-"),"/")
forbas->ds_munic:= fornec->cidade
forbas->id_ufemis:= fornec->estado
forbas->cd_uf:= fornec->estado
forbas->nr_fone:= fornec->telefone
forbas->nr_fax:= fornec->fax
forbas->cd_for:= str(fornec->codigo)
forbas->ds_email:= fornec->e_mail
forbas->ds_site:= fornec->homepage
forbas->ds_bair:= fornec->bairro
unlock
endif
endif
select fornec
skip
enddo
select estoque
go top
do while .not. eof()
select prdbas
go top
seek estoque->codprod
_markup:=strtran(str(estoque->markup),".")+"0"
_markup1:=converte(_markup,2)
_fracao:=strtran(str(estoque->fracao),".")+"00"
_fracao1:=converte(_fracao,4)
if found()
@ 12,02 say "Atualizando.:PRDBAS->"+" "+estoque->descprod color "gr+/b"
if rlock()
prdbas->cd_prd:= estoque->codbarra
prdbas->ds_prd:= estoque->descprod
prdbas->ds_tec:= estoque->descprod
prdbas->cd_unva:= estoque->unidade
prdbas->cd_linpr:= estoque->secao
prdbas->cd_fabpr:= estoque->codfabrica
prdbas->pc_cnvcp:= _fracao1
prdbas->st_reg:= estoque->ativo
prdbas->vl_cpa:= estoque->custo
prdbas->dt_prcat:= dtos(estoque->ucdata)
prdbas->pc_mark:= _markup1
prdbas->vl_prcat:= estoque->prcvenda
prdbas->id_prctl:= estoque->controlado
prdbas->cd_eanpr:= estoque->codprod
unlock
endif
else
@ 12,02 say "Incluindo...:PRDBAS->"+" "+estoque->descprod color "gr+/b"
append blank
if rlock()
prdbas->cd_prd:= estoque->codbarra
prdbas->ds_prd:= estoque->descprod
prdbas->ds_tec:= estoque->descprod
prdbas->cd_unva:= estoque->unidade
prdbas->cd_linpr:= estoque->secao
prdbas->cd_fabpr:= estoque->codfabrica
prdbas->pc_cnvcp:= _fracao1
prdbas->st_reg:= estoque->ativo
prdbas->vl_cpa:= estoque->custo
prdbas->dt_prcat:= dtos(estoque->ucdata)
prdbas->pc_mark:= _markup1
prdbas->vl_prcat:= estoque->prcvenda
prdbas->id_prctl:= estoque->controlado
prdbas->cd_eanpr:= estoque->codprod
unlock
endif
endif
select estoque
skip
enddo
clear screen
return nil
*=============================================================================
Static Function Converte(cNumero,nDecimal)
Return(Val(cNumero:=Stuff(cNumero,Len(cNumero)-nDecimal,0,'.')))
Valeu a ajuda de todos
Re: Cópia entre bancos de dados
Enviado: 04 Nov 2009 19:39
por alxsts
Olá!
Que bom que resolveu! É sempre ótimo se livrar de um problema.
Estava observando o código e penso que pode ficar mais rápido. Peço licença para fazer alguns comentários:
- antes de um SEEK ou DbSeek() não é necessário fazer GO TOP ou DbGoTop().
- depois de um APPEND BLANK ou DbAppend() não é necessário fazer um RLock() pois o registro que acabou de ser incluído já vem com um
lock ativo. Mas é sempre bom fazer um teste para verificar se o append foi concluído (NetErr()).
- como você abriu todos os arquivos no modo exclusivo, nem precisa fazer RLock().
- dei uma "enxugada" em uma das atualizações:
Código: Selecionar todos
do while .not. eof()
select forbas
// go top desnecessário
If DbSeek( padl(strtran(strtran(strtran(fornec->cgc,"."),"-"),"/"),15," ") )
@ 12,02 say "Atualizando.:FORBAS->"+" "+rtrim(fornec->fornecedor) color "gr+/b"
// seria o local para fazer RLock() mas não precisa pois voce abriu EXCLUSIVE
else
@ 12,02 say "Incluindo...:FORBAS->"+" "+rtrim(fornec->fornecedor) color "gr+/b"
append blank
IF NetErr()
// tratamento
ENDIF
endif
forbas->nr_cgcpf:= strtran(strtran(strtran(fornec->cgc,"."),"-"),"/")
forbas->nr_doc:= strtran(strtran(strtran(fornec->ie,"."),"-"),"/")
forbas->ds_razsc:= fornec->fornecedor
forbas->ds_fanta:= fornec->fantasia
forbas->ds_end:= fornec->endereco
forbas->nr_cep:= strtran(strtran(fornec->cep,"-"),"/")
forbas->ds_munic:= fornec->cidade
forbas->id_ufemis:= fornec->estado
forbas->cd_uf:= fornec->estado
forbas->nr_fone:= fornec->telefone
forbas->nr_fax:= fornec->fax
forbas->cd_for:= str(fornec->codigo)
forbas->ds_email:= fornec->e_mail
forbas->ds_site:= fornec->homepage
forbas->ds_bair:= fornec->bairro
// unlock Desnecessário
select fornec
skip
enddo
Sucesso!