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!