Clipper On Line • Ver Tópico - Migração de dados entre Arrays e BDs

Migração de dados entre Arrays e BDs

Discussão sobre Banco de Dados e RDDs para Clipper/[x]Harbour.

Moderador: Moderadores

 

Migração de dados entre Arrays e BDs

Mensagempor alxsts » 12 Out 2014 12:36

Olá!

Eu havia entendido a questão desde o início e creio que o meu exemplo atende, com um código pequeno e enxuto. Por falar em desenhar:

Esquema1.PNG


Para exemplo da função AEval(), consulte o Norton Guides
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Migração de dados entre Arrays e BDs

Mensagempor Jairo Maia » 12 Out 2014 19:39

Olá Alexandre,

Sem dúvida seu código é mais sucinto, mas procurei no meu exemplo usar um layout mais clássico. Mas ele pode se desejar usar seu exemplo, porém não na forma que está. Precisa alguns ajustes. Veja:
FUNCTION Teste()

   LOCAL aRecord, nVal, nPos

   use bdclass shared new
   use bdmatriz shared new
   
   bdmatriz->( dbGoTop() )
   
   WHILE bdmatriz->( ! Eof() )
   
      aRecord := AFill( Array( 100 ), 0 )
     
      FOR nPos := 1 TO 16
         If nPos = 1
          aRecord[ 1 ] := FieldGet( nPos )
         Else
          nVal := bdmatriz->( FieldGet( nPos ) )
          aRecord[ nVal ] := nVal
         EndIf
      NEXT
     
      bdclass->( dbAppend() )
     
      AEval( aRecord, { | nVal, nPosition| bdclass->( FieldPut( If( nPosition > 1, nPosition+1, nPosition ), nVal ) ) } )
     
      bdmatriz->( dbSkip() )
   ENDDO
   
   dbCloseAll()

RETURN NIL
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar de usuário

Jairo Maia
Colaborador

Colaborador
 
Mensagens: 2733
Data de registro: 16 Ago 2010 13:46
Cidade/Estado: Campinas-SP
Curtiu: 371 vezes
Mens.Curtidas: 305 vezes

Migração de dados entre Arrays e BDs

Mensagempor Francisco Diniz » 13 Out 2014 07:23

Bom dia

Jairo

A variável nPosition agora ficou mais clara, visto que da forma que estava exemplificada pelo colega Alexandre ela não variava ( coisa que estava me pegando para entender). Porém eu pergunto, esta variável deve ser também definida no inicio da função como local ou não é necessário ?, as variáveis antes de serem utilizadas eu tenho por hábito iguala-las a zero ( quando núméricas).
Francisco Diniz
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 22
Data de registro: 13 Fev 2012 22:05
Cidade/Estado: Marília/ SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Migração de dados entre Arrays e BDs

Mensagempor Jairo Maia » 13 Out 2014 10:08

Olá Francisco,

Não precisa. Não tem sentido, e veja que curioso:

- Variáveis usadas entre os pipes num Code Block, não precisam ser previamente declaradas.

- Se entre os pipes você usar nomes de variáveis existente na função, quando o Code Block for concluído, as variáveis existentes não terão sido alteradas pela ação do Code Block.

- Variáveis previamente não declaradas, ou seja, que não existem em sua função, e você usar entre os pipes, não tem como usá-las depois do processo, isso provocaria um RTE (Run Time Error) de variável não existente, pois ela não soma na lista de variáveis.

Portanto, a rigor melhor mesmo não declará-las se forem usadas somente entre os pipes no Code Block. No caso do exemplo do Alexandre, coincidiu que ele usou a variável nVal no Code Block, mas ela foi declarada como local porque foi usada no laço FOR/NEXT mais acima.

====================
Editado:

Francisco, somente agora ao responder vi que há um ERRO nos ajustes que fiz na função do Alexandre, veja que no exemplo anterior se o valor de algum campo do arquivo matriz for 1, no Laço FOR/NEXT tomará a posição do ID e desconfigura tudo. Está errado. Use o exemplo abaixo que ele está correto. Os ajustes foram somente no tamanho das Matrizes e no laço FOR/NEXT. Veja:
FUNCTION Teste()

   LOCAL aRecord, nVal, nPos

   use bdclass shared new
   use bdmatriz shared new
   
   bdmatriz->( dbGoTop() )
   
   WHILE bdmatriz->( ! Eof() )
   
      aRecord := AFill( Array( 100 ), 0 )
     
      FOR nPos := 1 TO 16
         If nPos = 1
          aRecord[ 1 ] := FieldGet( nPos )
         Else
          nVal := bdmatriz->( FieldGet( nPos ) )
          aRecord[ nVal + 1 ] := nVal  // posiciona o valor no campo correto...
         EndIf
      NEXT
     
      bdclass->( dbAppend() )
     
      AEval( aRecord, { | nVal, nPosition| bdclass->( FieldPut( nPosition, nVal ) ) } )
     
      bdmatriz->( dbSkip() )
   ENDDO
   
   dbCloseAll()

RETURN NIL
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar de usuário

Jairo Maia
Colaborador

Colaborador
 
Mensagens: 2733
Data de registro: 16 Ago 2010 13:46
Cidade/Estado: Campinas-SP
Curtiu: 371 vezes
Mens.Curtidas: 305 vezes

Migração de dados entre Arrays e BDs

Mensagempor Francisco Diniz » 13 Out 2014 19:45

Boa noite

Jairo

interessante sua explanação. Eu na verdade não sou nenhum catedrático em clipper, porém gosto muito de programar com ele, baixei o Harbor, Dizem que é melhor e mais rápido, sei lá, vou esperimentar e estudá-lo.
Agora de volta ao meu prg, não entendi bem sua passagem :

FOR nPos := 1 TO 16 // <<< 16 ??
15 If nPos = 1 // <<< ??
16 aRecord[ 1 ] := FieldGet( nPos ) // <<< fieldget(npos) já não assume e aloca nos campos 1- 2- 3- 4- 5 ,,, 15 ?
17 Else
18 nVal := bdmatriz->( FieldGet( nPos ) )
19 aRecord[ nVal + 1 ] := nVal // posiciona o valor no campo correto...
20 EndIf
21 NEXT

Bom ... vou bater um pouco de cabeça

Abraços
Francisco Diniz
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 22
Data de registro: 13 Fev 2012 22:05
Cidade/Estado: Marília/ SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Migração de dados entre Arrays e BDs

Mensagempor Jairo Maia » 14 Out 2014 04:43

Sim. Mas conforme você informou, seu arquivo BPTEC (alias bp), tem 16 campos:
conbp = Id do registro + bpa1 até bpa15 => totalizando 16 campos.

Seu arquivo BPCL (alias bcl) tem 100 campos:
conbc = Id do registro + bcp1 até bcp99 => totalizando 100 campos.
FOR nPos := 1 TO 16
  If nPos = 1
    aRecord[ 1 ] := FieldGet( nPos )
  Else
    nVal := bdmatriz->( FieldGet( nPos ) )
    aRecord[ nVal + 1 ] := nVal // posiciona o valor no campo correto...
  EndIf
NEXT

Linha 1: FOR nPos := 1 TO 16 // Faz a leitura dos 16 campos
Linha 2: If nPos = 1 // Se o campo for 1, então é o Id do registro. Se é o Id, pode ser qualquer numero entre 1 e o último registro. Como informado, hoje pode ser 1 a 6756.
Linha 3: aRecord[ 1 ] := FieldGet( nPos ) // trata separado, pois se o Id for 101 já é maior que a matriz que tem 100. Nada muda se alterar esta linha para: aRecord[ 1 ] := FieldGet( 1 ), pois nPos aqui sempre será 1.
Linha 4: Else
Linha 5: nVal := bdmatriz->( FieldGet( nPos ) ) // a partir de nPos 2, coloca em nVal o valor do campo, que pode ser 1 a 99
Linha 6: aRecord[ nVal + 1 ] := nVal // como o campo 1 é o ID, a posição na matriz sempre será uma a frente. Por exemplo: Se o valor do campo bpa[x] for 1, nVal será 1, mas para que seja gravado no campo bcp1, tem que ser a posição nVal+1. Se não fizer isso, irá gravar no campo 1 que é o ID. Como os números não se repetem, fica correto.
Linha 7: EndIf
Linha 8: NEXT
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar de usuário

Jairo Maia
Colaborador

Colaborador
 
Mensagens: 2733
Data de registro: 16 Ago 2010 13:46
Cidade/Estado: Campinas-SP
Curtiu: 371 vezes
Mens.Curtidas: 305 vezes

Migração de dados entre Arrays e BDs

Mensagempor Francisco Diniz » 14 Out 2014 07:25

Bom dia

Claríssimo ! Já havia perdido o jeito de pensar como computador em que tudo tem que ser extremamente lógico e sem deduções. A coisa é de muita sensibilidade.
Vou partir para refazer uma série de trechos de meus programas com estas informações que vieram a ajudar, tão logo eu tenha um resultado, postarei as linhas de como efetuei as alterações.
Só uma informação, eu tenho muitas literaturas de Clipper, porém são muito pobres em exemplos esclarecedores de uso de macros e funções. Vc tem alguma sugestão literária que seja rica no uso destas ?
Outra coisa, eu uso programar com "C++" códigos de procedimentos para micro controladores ( CHIPs eletrônico controlados). O Clipper é uma semelhança grande com "C", talvez pelo fato de ter sido originado a partir deste, por acaso voce já ouviu falar de se programar micro controladores com Clipper ?. Pergunto isto porque há algum tempo atrás eu tinha uma literatura de um autor Carlos Augusto Gomes cuja sua obra " Clipper com C" interagia as duas linguagens. Por ter me mudado de Sampa para Tauba e desta para Marília, esta obra se perderam ( voce conhece mulher fazendo mudança né ?. As coisas delas são inseparáveis, as do marido ... lixo ).
Fico agradecido e fique na paz
Francisco
Francisco Diniz
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 22
Data de registro: 13 Fev 2012 22:05
Cidade/Estado: Marília/ SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Migração de dados entre Arrays e BDs

Mensagempor Jairo Maia » 14 Out 2014 15:39

Olá Francisco,

Francisco Diniz escreveu:Vc tem alguma sugestão literária que seja rica no uso destas ?
Hoje em dia acho que a melhor documentação em Clipper está aqui: http://www.ousob.com/ng/clguide/.

Francisco Diniz escreveu:já ouviu falar de se programar micro controladores com Clipper ?
Nunca. Primeira vez...

Francisco Diniz escreveu:Pergunto isto porque há algum tempo atrás eu tinha uma literatura de um autor Carlos Augusto Gomes cuja sua obra " Clipper com C" interagia as duas linguagens
Ele tem várias obras sobre isso. Inclusive para o Clipper 5.2 e integração com C. Como sei disso? Acabei de acessar http://www.livronauta.com.br e na busca digitei: Clipper com C.

Procure deixar o tópico sempre aberto à participação de outros membros. Ao direcionar uma pergunta a um membro mas que poderia ser ampla, inibe a participação de outros membros...

Ademais, Sucesso na remodelação de sua função...
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar de usuário

Jairo Maia
Colaborador

Colaborador
 
Mensagens: 2733
Data de registro: 16 Ago 2010 13:46
Cidade/Estado: Campinas-SP
Curtiu: 371 vezes
Mens.Curtidas: 305 vezes

Migração de dados entre Arrays e BDs

Mensagempor Francisco Diniz » 22 Out 2014 21:12

Oi pessoal.
Boa Noite a todos.

De volta as vacas magras, estou passando aqui o trecho de meu prg que está travado na rotina AEVAL().
Como disse, por inexperiência ainda não consegui visualizar e entender bem esta rotina de bloco. Mas Vamos lá >> Para ficar facilitar, diminui meu banco principal para 25 campos ao invés de 100, as demais informações que não estão envolvidas são cópias de rotinas que não fazem diferença para o tópico principal que é a de mover dados de um bd para outro sem o uso dos " IF ENDIF " e " FOR NEXT " que fazem que os prgs fiquem extensos demais.

Eis minha digitação>>
/*         
                   FRANCISCO DINIZ
  ---------------------------------------------------------
       ***         C L A S S I F I C A Ç Ã O                ***
  ---------------------------------------------------------
*/
#define b_single 1
#define b_double 2
function main()
// --- definição das variáveis -------------------------

local opt,i,nVal,nPos,dados[26],vtr[26],getlist:={}
local Soma113,Soma1425
soma113:=soma1425:=0
opt:="S"
afill(dados,0)
afill(vtr,0)

// ===============  Abertura dos Bancos de Dados  ==============
select 1
use BD_PR alias bp shared new
if neterr()
   setcolor("w+/r")
   @16,5 say " BANCO PRINCIPAL ESTA INDISPONIVEL"
   inkey(0)
   quit
endif
select 2
use BCl_El alias bcl shared new
if neterr()
  setcolor("w+/r")
  @16,5 say "O BANCO DOS BCL ESTA INDISPONIVEL "
  inkey(0)
  dbcloseall()
  scroll()
  quit
endif

select 3
use BCl_EX alias bcx shared new
if neterr()
   setcolor("w+/r")
   @16,5 say "BANCO DOS BCX ESTA INDIPONIVEL"
   inkey(0)
   dbcloseall()
   scroll()
   quit
endif

// ################## Montagem Total dos Bancos BCL e BCX ################
close all
setcolor("g+/n")
@16,5 say "ATENÇÃO >> ESTA ROTINA REFAZ POR COMPLETO OS BANCOS CLASSIFICADOS"
@18,29 say "Podemos proceguir ? S/N"
@18,49 get opt picture "!"
read

if lastkey()=27.or.opt<>"S"
   dbcloseall()
   return nil
endif
use BCP_PQ alias bpq exclusive new
if !neterr()
  zap
   close
  else
   use BCP_PQ alias bpq shared new
   setcolor("w+/r")
   @16,5 say "BANCO PESQ INDISPONIVEL PARA USO"
   inkey(0)
   dbcloseall()
   return nil
endif

//   Nova formacao de BCL_EL e BCL_EX
use BCL_EL exclusive new
   zap                       //  zeramento dos bancos bcl e bcx
   close
use BCL_EX exclusive new
   zap
   close
use bd_pr alias bp shared new
   bp->(dbgotop())

//   ~~~~~~~~~~ proc sugeridas pelos colegas do Forum PCTOLEDO ~~~~~~~~~~~

use BCL_EL alias bcl shared new
use BCL_EX alias bcx shared new
use BCP_PQ alias bcp shared new

while bp->(!eof())
   vtr:=afill(array(26),0)      
   for nPos:= 1 to 16
     nVal:=bp->(fieldget(nPos))
     vtr[nPos]:=nVal        // Posiciona o valor no campo correto
   next

// A rotina acima executa perfeitamente o dscrito > São transferidos para vtr[] os valores do bp linha pós linha.

   bcl->(dbappend())
   aeval(vTr,{|nVal,nPosi|bcl->(fieldput(nPosi,nVal))})  // travou aqui.  Que tipo de dado esta errado ?
   bp->(dbskip())
enddo
dbcloseall()   
return nil

Quando eu rodo este prg apresenta a mensagem:
Error DBFNTX/1020 Data type error
...
Called from AEVAL(0)


<<< Ou Seja ... Não consegui esclarecer o erro e portanto resolve-lo . Alguém de vcs tem como clarear esta dúvida ?

Abraços
Francisco
Nota de Moderação:
Toledo: Mensagem editada para colocar a tag [ code ]
Veja como utilizar esta tag: Clique aqui
Francisco Diniz
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 22
Data de registro: 13 Fev 2012 22:05
Cidade/Estado: Marília/ SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Migração de dados entre Arrays e BDs

Mensagempor Jairo Maia » 24 Out 2014 10:33

Olá Francisco,

Este erro está ocorrendo porque você está tentando gravar um dado com tipo diferente do campo. Para saber onde está ocorrendo o erro, altere a sua linha do bloco AEval() por esta:
aeval(vTr,{|nVal,nPosi|SalvaDados(nPosi,nVal)})
Coloque esta função em seu .PRG:
Func SalvaDados( nCampo, xVal )

zy_nCampo := bcl->( Field( nCampo ) )

If ValType( bcl->&zy_nCampo. ) != ValType( xVal )
 
  Clear Screen
 
  @ 03, 02 Say "Aqui está dando erro:"

  @ 05, 02 Say "Número do campo: " + LTrim( Hb_ValToStr( nCampo ) )
  @ 06, 02 Say "Nome do campo  : " + bcl->( Field( nCampo ) )
  @ 07, 02 Say "Tipo do Campo  : " + ValType( bcl->&zy_nCampo. )

  @ 09, 02 Say "Dado a gravar  : " + LTrim( Hb_ValToStr( xVal ) )
  @ 10, 02 Say "Tipo do Dado   : " + ValType( xVal )
 
  SetPos( 12, 2 )
  InKey( 0 )
 
EndIf

bcl->( FieldPut( nCampo, xVal ) )

Return Nil
Quando ocorrer o erro você verá na tela os dados que estão provocando o erro.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar de usuário

Jairo Maia
Colaborador

Colaborador
 
Mensagens: 2733
Data de registro: 16 Ago 2010 13:46
Cidade/Estado: Campinas-SP
Curtiu: 371 vezes
Mens.Curtidas: 305 vezes

Migração de dados entre Arrays e BDs

Mensagempor Francisco Diniz » 04 Nov 2014 21:49

Boa Noite Pessoal.
Ó eu aqui de volta. Bom, conforme prometi, estou passando o código do meu prg que executa a passagem de valores numéricos e desordenados de uma "string" para um banco de dados de forma classificada. Ficou super legal.
Mas me desculpem minha ignorância, >>> a função Aeval() não funcionou " M E S M O " - Desisti dela, porém se algum aventureiro desejar insistir em fazer seu uso, que tenha mais sorte que eu.
O Prg ficou curtinho e atendeu minha expectativa satisfatoriamente, vejam como ficou:
( OBS: algumas informações contidas nada tem a ver com a rotina, pertencem a outra proc, o mais importante é o comando " while " para frente).

#define b_single 1
#define b_double 2

function main()
// --- definição das variáveis -------------------------
local opt,i,nTr,nVal,nPos,nCol,vtr[26],aRecord[26],getlist:={}
local Soma113,Soma1425
private iNdc
iNdc:=0 // para o uso de macro a variável precisa ser ""PRIVATE""
i:=nTr:=nVal:=nPos:=nCol:=0
soma113:=soma1425:=0
opt:="S"
afill(vtr,0)
afill(aRecord,0)
// =============== Abertura dos Bancos de Dados ==============
select 1
use BD_PR alias bp shared new
if neterr()
setcolor("w+/r")
@16,5 say " BANCO PRINCIPAL ESTA INDISPONIVEL"
inkey(0)
quit
endif
select 2
use BCl_El alias bcl shared new
if neterr()
setcolor("w+/r")
@16,5 say "O BANCO DOS BCL ESTA INDISPONIVEL "
inkey(0)
dbcloseall()
scroll()
quit
endif
// ################## Montagem Total dos Bancos BCL e BCX ################
close all
setcolor("g+/n")
@6,5 say "ATENÇÃO >> ESTA ROTINA REFAZ POR COMPLETO OS BANCOS CLASSIFICADOS"
@8,29 say "Podemos proceguir ? S/N"
@8,49 get opt picture "!"
read
if lastkey()=27.or.opt<>"S"
dbcloseall()
return nil
endif
// Nova formacao de BCL_EL e BCL_EX
use BCL_EL exclusive new
zap // zeramento dos bancos bcl e bcx
close
select 1
use bd_pr alias bp shared new
bp->(dbgotop())
select 2
use BCL_EL alias bcl shared new

while .T.
npos:=nCol:=nTr:=nVal:=0
afill(vtr,0) // afill zera vtr[]
nval:=bp->(fieldget(1))
bcl->(dbappend())
bcl->concl:=nval // aqui a coluna1 (concl) assume seu indicador que vai de 1 a n
for nPos:= 2 to 16
nVal:=bp->(fieldget(nPos)) // fieldget() toma as 15 posições do BP
vtr[nVal]:=nVal // aqui vtr > coluna a ser passada assume seu próprio valor
next
For nCol:= 1 to 25
iNdc:=alltrim(str(nCol)) // iNdc torna-se string para passagem na macro
nTr:=(vtr[ncol]) // passagem direta do vetor para o bcl+macro
bcl->BCE&iNdc:=nTr
next
bp->(dbskip())
if bp->concbp=0 // caso seja colocada a função ""if eof()", o ultimo reg
eof() // considerado como "end of file" é o imediatamente após o ultimo reg preenchido
dbcloseall() // válido existente no BD, ou seja Zeros ou Brancos
return nil
endif
enddo
return nil

Fico agradecido a atenção dos senhores colaboradores na ajuda, foi bem válida as informações prestadas.
Abraços e quem desejar usar esta rotina, se dará bem pois ficou muito boa.
Fiquem na Paz..
Francisco Diniz
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 22
Data de registro: 13 Fev 2012 22:05
Cidade/Estado: Marília/ SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Anterior



Retornar para Banco de Dados

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 15 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