Clipper On Line • Ver Tópico - Migração de dados entre Arrays e BDs
Página 1 de 3

Migração de dados entre Arrays e BDs

MensagemEnviado: 16 Abr 2012 20:57
por Francisco Diniz
Tenho por vezes trabalhado com estatísticas, e quando vou colocar os dados em um DBF é a maior trabalheira. Até que consigo, porém o programa fica demais grande.
É mais ou menos assim o meu problema: Tenho de 1 a 10 grupos para estudar. Eu escolho quantos grupos eu vou estudar, após eu informo o local de cada faixa deste grupo ( vai de 1 a 879), então fica por exemplo assim:
número de grupo escolhido : 5
local da faixa de cada grupo: gr 1>> 875, gr 2 >> 645, gr3 >> 315 ... gr 5 >> 157
Após isto, são formadas 5 arrays compostas de 25 campos ( private soma[25] ,soma2[25], soma3[25] ...soma5[25]).
Pois bem, ai esta o problema. Eu sempre tento usar o argumento FOR NEXT para a montagem do BD com estas arrays e não consigo. Tento assim:

\\   qtd é o no. de grupo
sele bde
dbappend()
local j:=i:=0            \\ definido no inicio do prg
for i:= 1 to qtd
     if i=1
         for j:= 1 to 25
             bp->n J := soma[j]      \\  << Aqui está meu problema. Esta rotina não roda. Não é aceito o indice j
         next
next

repete a rotina ...
Já estudei várias formas e ainda não vi nada que me esclarecece uma forma de montar o BD a partir de um for next com arrays.
Agradeço a ajuda.
Francisco Diniz

Migração de dados entre Arrays e BDs

MensagemEnviado: 16 Abr 2012 21:32
por Pablo César
Bem vindo ao fórum Francisco !

Eu não entendi direito a sua explicação. Você tem uma array com informações e quer passar para o dbf ?(1) Ou você tem os dados no dbf e quer compor uma array ?(2) A array é multidimensional ou unidimensional ?(3)

eu informo o local de cada faixa deste grupo ( vai de 1 a 879), então fica por exemplo assim:
número de grupo escolhido : 5
Você escolhe a quantidade de grupos e isso como você faz ? Posiciona-se nos 5 registros ou como estão localizados ?(4)

Você poderia listar a estrutura do seu bd ?(5) -> quiser utilizar este aplicativo: para listar estrutura seria melhor
Não entendi, por quê você usa dbappend() e por quê utiliza if i=1 (na linha 6 do seu código) ?(6)
Na linha 4 você diz: j:=i:=0 igual a zero ?(7) Pois todo inicio de array começa com 1 ao menos em Clipper (na linguagem C começa com zero)

Após isto, são formadas 5 arrays compostas de 25 campos ( private soma[25] ,soma2[25], soma3[25] ...soma5[25])
Estou vendo que você utiliza 5 arrays unidimensionais. Isto responderia minha pergunta numero 2,, certo ?(8) Na minha opinião, você facilitaria se fosse multidimensional (apenas um nome, formando 5 linhas por 25 colunas), daí não precisaria repetir 5 vezes o código. Apenas mudar o ponteiro de cada array.

Se você responder as minhas 8 interrogações, terei como compor o código que precisa, mas preciso entender o seu caso.

Migração de dados entre Arrays e BDs

MensagemEnviado: 17 Abr 2012 21:49
por Francisco Diniz
Boa noite Pablo. De antemão agradeço à sua atenção.
Eu desejo passar os valores da arrays soma[] para o banco de dados (bde) alias bp.
Este banco de dados possui os campos n1, n2,n3 ....n25 com tres dígitos numéricos
São dez (número máximo) de arrays unidimensional compostas de 25 campos: soma1[],soma2[],soma3[] . . . soma10[]. Digamos que é escolhida a quantidade 5 faixas para estudo, então o programa monta 5 arrays soma1[], soma2[]...soma5[] contendo 25 campos com resultados de cálculos.
De posse destas 5 arrays que preenchidas nos seus 25 campos, passo agora para a montagem do BDE alias bp, esta ai o problema, através de um for next eu não consigo colocar os dados das arrays no mesmo.

Para entender melhor, Imagine que vc tem 879 objetos semelhantes saidos de uma linha deprodução (porcas de parafusos por exemplo), sabidamente, cada porca mesmo saindo do mesmo torno é diferente da anterior gerada.
Então por amostragem aleatória eu escolho até de 1 até no max. 10 peças deste total de 879 peças. No caso do meu exemplo: gr1>> 875, gr 2 >> 645, gr3 >> 315 ... gr 5 >> 157. O que é feito ? Uma análise contendo 25 resultados e que são as minhas arrays denominadas soma 1 a n {1,2, 3 ,...., 25] (n = amostragem), pois bem, agora é a minha treta, por um simples for next, seria resultado mil se eu conseguisse colocar os resultados das arrays no bd, porém ele não aceita a variável de FOR até qtd ( qtd é a amostragem) como referência na inclusão no bd. Ou seja
for i:= 1 to qtd // valor de n
06 if i=1 // aqui eu vario "i" para limitar a qtd de arrays, uma arrays com valor zero dana meus cálculos
07 for j:= 1 to 25 // é a qtd de campos existente na array
08 bp->n J:= soma[j] \\ << Aqui está meu problema. Tento atribuir nos campos do BDE (bp) os valores de soma[j] para n1,n2 ,n3,n4...n25 que compoem o BDE. Então veja, o índice j em " nj " o programa não entende que j assume a cada looping outro valor :- j:=1, j:=2,...,j:=25. Isto ocorre também com a array soma[]

09 endif
10 next
Espero que tenha sido claro.
A questão básica é isto, porém coloquei de forma resumida de uma mega operação. A dificuldade é: " Como colocar valores de arrays através de um for next a um banco de dados .dbf". Claro que for next é uma alternativa, podendo ser também com do while, ou uma função () já existente e que desconheço.
Abraços colega.

Já li uma paulada de literaturas sobre montagens de BDs e nada sobre isto.

Migração de dados entre Arrays e BDs

MensagemEnviado: 17 Abr 2012 22:16
por Francisco Diniz
Um detalhe a mais:
a) " For i " ao atingir o valor da amostragem escolhida, as demais arrays postereriores a "i" serão descartadas, evitando -se assim que elas entrem no cálculo final
b) eu atribuo valores zeros no inicio do prg as arrays através de afill (soma1,0) . . .
c) quando vou colocar os dados nos DBFs eu sempre abro a cada select o bd, pois como manipulo muitos dbfs, a cada abertura de um deles, o outro é fechado automaticamente, assim eu confio no dbappend() a cada chamada para inclusão de dados ao invés de append.
d)Não posso utilizar array mutidimencional pois a formação de cada uma delas é feito através de manipulação de cálculo. Sendo elas independentes, fica mais fácil de se entender uma depuração do prg. Coisa que não aconteceria se ela fosse uma matriz i,j.

Migração de dados entre Arrays e BDs

MensagemEnviado: 17 Abr 2012 23:41
por JoséQuintas
o mais difícil é entender o que precisa.

No bd pode gravar usando macro.
for nCont = 1 to 25
   cCont = ltrim(str(nCont))
   replace banco->n&cCont with array[nCont]
next


ou gravar cada elemento do array no bd:
analise, N, 10
array1, N, 10
array2, n, 10
valor, n, 10

Migração de dados entre Arrays e BDs

MensagemEnviado: 20 Abr 2012 21:17
por Francisco Diniz
Vou tentar usar sua sugestão de uso de macros, coisa que não havia pensado. A gente foca em um caso e acaba esquecendo de outro. Assim que obtiver o resultado, comunico a vcx. Abraços

Migração de dados entre Arrays e BDs

MensagemEnviado: 20 Abr 2012 21:33
por rochinha
Amiguinho,

Baseado no trecho de codigo que voce apresentou:

cDBFVetor := "vetores"
if !file( cDBFVetor+".dbf" )
   aStru := {}
   for i = 1 to 25 // é a qtd de campos existente na array
       aadd( aStru, { "GR"+strZero(i,2), "N", 10, 0 } ) // Cria o nome do campo como sequencia GR01, GR02, ..., GR25
   next
   DBCREATE( cDBFVetor, aStru )
endif
USE ( cDBFVetor ) NEW SHARED
for i:= 1 to qtd // valor de n
    if i=1 // aqui eu vario "i" para limitar a qtd de arrays, uma arrays com valor zero dana meus cálculos
       dbAppend() // Produzira os appends de campos novos baseados em "qtd"
       for j := 1 to 25 // é a qtd de campos existente na array
           field_name := LOWER("GR"+strZero(j,2)) // Pega a nome do campo GR01, GR02, ..., GR25
           _FIELD->&field_name := soma[j] // Repassa o campo com o conteudo de soma[j]
       next
    endif
next


O trecho de repasse ficaria parecido com este com o uso de vetor bidimensional:
...
for i:= 1 to qtd // valor de n
    //if i=1 // aqui eu vario "i" para limitar a qtd de arrays, uma arrays com valor zero dana meus cálculos
       dbAppend() // Produzira os appends de campos novos baseados em "qtd"
       for j := 1 to 25 // é a qtd de campos existente na array
           field_name := LOWER("GR"+strZero(j,2)) // Pega a nome do campo GR01, GR02, ..., GR25
           _FIELD->&field_name := soma[i,j] // Repassa o campo com o conteudo de soma[i,j]
       next
    //endif
next


Visto que o problema não esteja na criação do vetor e sim na manipulação para se imputar na tabela.

Eu talvez nem usasse tabela, a não ser que quizesse salvar por mais tempo o resultado, continuaria trabalhando somente sobre os vetores.

Mas no caso da tabela depois de criada, possibilitaria outras manipulações ou visões como filtragem dos ranges das amostragens ou escolhas de sequencias para comparações e os vetores resultantes podendo ser visualizados em gráficos.

Tive um desafio assim quando precisei montar um gráfico em meu sistema que apresentava simultaneamente a relação de valores do momento comercial de ponto de equilibrio.

Levando-se em consideração que a lógica acima foi didáticamente digitada e não testada pelo ISO ou IMMETRO.

Migração de dados entre Arrays e BDs

MensagemEnviado: 22 Abr 2012 10:35
por Francisco Diniz
Tá ai, vc matou a charada, fiz uso da macro, funcionou, e diminuiu bem o meu prg. O uso de vetor bidimensional, foi providencial. Ficou um programa mais limpo e eficaz na redução de tempo de processamento.
Valeu, as dicas forma ótima.
Agradeço pela ajuda.

Migração de dados entre Arrays e BDs

MensagemEnviado: 22 Abr 2012 11:42
por alxsts
Olá!

O executável ficaria menor e mais rápido se eliminar o uso do operador macro (&):
...
for i:= 1 to qtd // valor de n
    //if i=1 // aqui eu vario "i" para limitar a qtd de arrays, uma arrays com valor zero dana meus cálculos
       dbAppend() // Produzira os appends de campos novos baseados em "qtd"
       for j := 1 to 25 // é a qtd de campos existente na array
           //field_name := LOWER("GR"+strZero(j,2)) // Pega a nome do campo GR01, GR02, ..., GR25
           //_FIELD->&field_name := soma[i,j] // Repassa o campo com o conteudo de soma[i,j]
           FieldPut( j, soma[i,j] ) // Repassa o campo com o conteudo de soma[i,j]   
       next
    //endif
next

Migração de dados entre Arrays e BDs

MensagemEnviado: 23 Abr 2012 17:17
por rochinha
Amiguinhos,

Estas pequenas porções me fazem lembrar os velhos "Two Lines" em Basic.

Era uma série de pequenos aplicativos ou joguinhos feitos em duas linhas. Base esta que permitiu a muitos programadores aprender a enchertar comandos dentros de outros. Hoje isto é possivel usando-se xBase com o separador ";"

Neste caso o trecho acima(sem anotações) ficaria assim:
for i:= 1 to qtd ; dbAppend() ; for j := 1 to 25 ; FieldPut( j, soma[i,j] ) ; next ; next


Super simples. Mas a depuração...

Migração de dados entre Arrays e BDs

MensagemEnviado: 08 Mai 2012 22:41
por Francisco Diniz
Boa noite Gente.

Legal este papo, faz a gente aprender ou lembrar algumas rotinas de antigamente, mas vejam vcs, hoje estou desenvolvendo um programa que tem uma rotina semelhante a deste tópico, o que muda é a passagem de uma variavel de um FOR NEXT como referência aos campos do BD, Vejam como ficou o trecho do programa PRG :
if fx1<>0           
   k:=fx1-9                               // caso fx1 = 100 , então k assume 91
   for j:=k to fx1                        // FOR NEXT  variará de 91 a 100 (10 unidades)
       for r:= 1 to 15                    // Verifico o resultado de 15 análises
           vLr:="F" + trim(str(r))        // f1,f2,...,f15  nome dos campos do meu BP Banco principal
           select bp                      // seleciono o Bco Principal de dados BP
                                          // ( possui o valor numérico de 1 a 25 )
           go j                           // inicio a varredura pela primeira amostra ( 91 )
           for m:= 1 to 25                // 1 a 25 - Varro para localizar uma igualdade de resultados possíveis
               if bp->&vLr = trim(str(m)) // No caso de ter achado a igualdade BP->(macro)f1, f2, ... f15
                  bdN:="N" + trim(str(m)) // bdN assume  N1,N2,...,N25
                  select bde              // Seleciona o Banco depositário dos resultados
                  dbappend()

                  bde->&bdN:=1            // bde->(macro)bdN :=1     
                                          // se verdade :bde->n1:=1, bde-n2:=1, .... ,bde-n25:=1     
                                          // >>>  Esta é a linha que o erro é apontado  (linha xxxxx)
               endif
           next
       next
   next
endif

Esta rotina o clipper aceita e a lik edição é feita, porém no processamento gera o erro: Error Base/1449 Syntax error: & (macro)
linha XXXXX

Migração de dados entre Arrays e BDs

MensagemEnviado: 08 Mai 2012 22:58
por Francisco Diniz
Vejam a minha dúvida resumidamente. Desejo alocar 15 resultados obtidos na faixa de resultados 91 a 100, e posicionálos na coluna respectiva a cada campo do BDE sinalizando com o numeral 1 se verdadeiro.
BDE >> N1, N2, N3, ..., N25
BP >> F1, F2, F3, .....F25.

EXEMPLO PRÁTICO para o caso do inicio da faixa a ser varrida 91 (10 elementos):
BDE - N1 - N2 - N3 - N4 - N5 - N6- N7 - N8 - ....... N 21 - N22 - N23 - N24 - N25
BP - 1 - 0 - 1 1 1 - 0 - 1 - 1 1 0 0 1 1
BP é a amostragem dos resultados obtido na faixa 91, após será a faixa 92 e ate 100.
Espero ter sido claro.
Agradeço uma clareada neta questão.

Migração de dados entre Arrays e BDs

MensagemEnviado: 09 Mai 2012 05:52
por rochinha
Amiguinho,

Voce precisa ter certeza que o nome do campo esta sendo criado corretamente.
...
                          bdN:="N" + trim(str(m)) // bdN assume  N1,N2,...,N25
                     select bde              // Seleciona o Banco depositário dos resultados
                     dbappend()
   
                     bde->&bdN:=1            // bde->(macro)bdN :=1     
                                             // se verdade :bde->n1:=1, bde-n2:=1, .... ,bde-n25:=1     
                                             // >>>  Esta é a linha que o erro é apontado  (linha xxxxx)
...


Quando voce não define a largura em uma função str() ela pode assumir outra largura e o retorno não será o que voce deseja. Neste momento pode ser criado um nome de campo que não exista, exemplo N0003, N025, etc.

Portanto faça assim:

...
                          bdN:="N" + trim(str(m)) // bdN assume  N1,N2,...,N25
                     select bde              // Seleciona o Banco depositário dos resultados
                     dbappend()
? bdN // ******* PROVA DOS NOVE ******* //
                     bde->&bdN:=1            // bde->(macro)bdN :=1     
                                             // se verdade :bde->n1:=1, bde-n2:=1, .... ,bde-n25:=1     
                                             // >>>  Esta é a linha que o erro é apontado  (linha xxxxx)
...


Portanto apesar do alxsts ter proposto o uso de FieldPut(), esta função se sairia bem se realmente os campos forem criados na sequencia.

O uso de macro permite que o campo seja repassado mesmo que receba uma sequencia fora de ordem, exemplo: N1, N2, N15, N3, N18, N4, etc.

O uso de FieldPut() é certeiro, mas exige que a tabela esteja estruturada na sequencia. O uso de macro é demorado e sua precisão não depende da ordem dos campos. Mas exige verificação se o mesmo realmente esta sendo bem montado.

Dica: a função trim() é uma enganação. Use AllTrim() quando for fazer montagens, ou um rTrim() e lTrim().
                          bdN:="N" + alltrim(str(m)) // bdN assume  N1,N2,...,N25


Se voce padronizar os campos com um tamanho padrão ao invés de N1,N2,...,N11,N12 que visualmente mudam de tamanho, voce pode criá-los como N01,N02,...,N11,N12, onde todos os campos terão o mesmo tamanho no nome.

Neste caso voce passa a usar strZero() que preenche com zeros à esquerda conforme o tamanho que voce quizer:

                          bdN:="N" + alltrim(strZero( m, 2 )) // bdN assume  N1,N2,...,N25


Desta forma os numero de 1 a 9 aparecerão como 01, 02, ..., 09.

Migração de dados entre Arrays e BDs

MensagemEnviado: 09 Mai 2012 21:52
por Francisco Diniz
Boa noite.
Bastante sensata sua colocação, vou retificar minhas entradas e nomes de campos, passo a passo e verificarei as suas sugestões e informo o resultado. De pronto, agradeço sua gentileza.

Migração de dados entre Arrays e BDs

MensagemEnviado: 20 Mai 2012 07:55
por Francisco Diniz
Bom dia.
Pois então, seguindo sua sugestão consegui compor meu BD quase que satisfatotiamente. Digo quase , por um motivo que ainda não entendi.
if fx1<>0                    // esta rotina será executada se fx1 # 0 
   k:=fx1-9               // k assume 9 valores anterioress a fx1
   for j:=k to fx1     
        for r:= 1 to 15  // 15 valores possíveis existentes em BP
             vLr:="F" + alltrim(str(r))  // vLr assume bde >> f1 f2 ... f15
             select bp
             go j
             for m:= 1 to 25  // esta rotina localiza os correspondentes F1 com N1 F2 com N2 etc.
                  if bp->&vLr = m  // macro assume bp >> bp->f1,bp->f2 ...bp->f15
                     bdN:="N" + alltrim(str(m))  //bdN assume os campos de bde >> N1, N2, ...,N25
                     replace bde->&bdN with 1   // na existência do correspondente o campo N assume valor 1
                  endif
             next
        next
        select bde
        dbappend()
        select bp
   next
endif

Esta rotina executa satisfatóriamente com um unico agravante, "j" é um looping composto de 10 ciclos, porém quando verifico o BDE (BD que foi composto), existem 11 registros sendo que este 11 é totalmente zerado (???). Deveria ter apenas 10 e não 11. Não entendi.

Editada por Rochinha. Para conter o código dentro das tags CODE

Migração de dados entre Arrays e BDs

MensagemEnviado: 20 Mai 2012 10:47
por Jairo Maia
Olá Francisco,

Tente com a alteração abaixo: Passei as linhas 15, 16 e 17 do seu código para o inicio do laço "j". Veja se é isso.
if fx1<>0                    // esta rotina será executada se fx1 # 0 
  k:=fx1-9               // k assume 9 valores anterioress a fx1
  for j:=k to fx1     
    select bde
    dbappend()
    select bp
    for r:= 1 to 15  // 15 valores possíveis existentes em BP
      vLr:="F" + alltrim(str(r))  // vLr assume bde >> f1 f2 ... f15
      select bp
      go j
      for m:= 1 to 25  // esta rotina localiza os correspondentes F1 com N1 F2 com N2 etc.
        if bp->&vLr = m  // macro assume bp >> bp->f1,bp->f2 ...bp->f15
          bdN:="N" + alltrim(str(m))  //bdN assume os campos de bde >> N1, N2, ...,N25
          replace bde->&bdN with 1   // na existência do correspondente o campo N assume valor 1
        endif
      next
    next
  next
endif

Migração de dados entre Arrays e BDs

MensagemEnviado: 20 Mai 2012 10:52
por rochinha
Amiguinho,

Este registro zerado causa algum problema?

Senão deixe-o, mas o correto seria verificar passo-a-passo como são gerados os numeros que voce manipula nos ifs:

Além disto até que se encontre o problema coloque um escape como abaixo:
if fx1<>0                    // esta rotina será executada se fx1 # 0 
   k:=fx1-9               // k assume 9 valores anterioress a fx1
   for j:=k to fx1

        ? "for j:=k to fx1", j // ***** TRACANDO A ROTA *****
        if j > 10
           exit
        endif

        for r:= 1 to 15  // 15 valores possíveis existentes em BP

             ? "for r:= 1 to 15", r // ***** TRACANDO A ROTA *****

             vLr:="F" + alltrim(str(r))  // vLr assume bde >> f1 f2 ... f15
             select bp
             go j
             for m:= 1 to 25  // esta rotina localiza os correspondentes F1 com N1 F2 com N2 etc.
                  if bp->&vLr = m  // macro assume bp >> bp->f1,bp->f2 ...bp->f15
                     bdN:="N" + alltrim(str(m))  //bdN assume os campos de bde >> N1, N2, ...,N25
                     replace bde->&bdN with 1   // na existência do correspondente o campo N assume valor 1
                  endif
             next
        next
        select bde
        dbappend()
        select bp
   next
endif

Migração de dados entre Arrays e BDs

MensagemEnviado: 20 Mai 2012 11:04
por rochinha
Amiguinhos,

Esta galéra PC Toledo é muito ativa, Parabéns.

Migração de dados entre Arrays e BDs

MensagemEnviado: 20 Mai 2012 14:34
por Jairo Maia
Olá Rochinha,

Mas analisando seu post, percebi que nem a solução que propus, nem a sua irá resolver o problema. Veja que no código que ele postou, o aliás bde já chega com um AppenBlank() que ele cria antes da entrada nesta seção.

No caso da minha proposta, será gerado um registro em branco adicional, e no caso da sua proposta, o laço não passa por ela se for maior que 10. Vou propor uma outra solução usando a sua idéia, mas alterando a posição:
if fx1<>0                    // esta rotina será executada se fx1 # 0 
  k:=fx1-9               // k assume 9 valores anterioress a fx1
  for j:=k to fx1     
    for r:= 1 to 15  // 15 valores possíveis existentes em BP
      vLr:="F" + alltrim(str(r))  // vLr assume bde >> f1 f2 ... f15
      select bp
      go j
      for m:= 1 to 25  // esta rotina localiza os correspondentes F1 com N1 F2 com N2 etc.
        if bp->&vLr = m  // macro assume bp >> bp->f1,bp->f2 ...bp->f15
          bdN:="N" + alltrim(str(m))  //bdN assume os campos de bde >> N1, N2, ...,N25
          replace bde->&bdN with 1   // na existência do correspondente o campo N assume valor 1
        endif
      next
    next
   
    If j < 10  // aqui, se j = 10 mais nada a fazer, e sai no próximo loop...
      select bde
      dbappend()
      select bp
    Endi

  next
endif

Migração de dados entre Arrays e BDs

MensagemEnviado: 21 Mai 2012 01:54
por rochinha
Amiguinho,

Pelo menos são mais cabeças pensando, néh, as vezes a solução é uma pequena coisa, um nada na verdade, mas quando se trata de laços aninhados um simples erro em um causa um caos nos outros.

A gente chega lá.

Migração de dados entre Arrays e BDs

MensagemEnviado: 07 Out 2014 08:01
por Francisco Diniz
Bom dia Pessoal.

Estes dias estava com este mesmo problema para resolver já em um outro sistema que estou desenvolvendo. É uma situação parecida, só que de um Bd para outro, o que difere é que o Primeiro BD com 15 campos( bdMatriz) terá sua imagem passada para o 2o BD com 99 campos (bdClass) porém de forma classificada onde os números não indicados no bdMatriz serão preenchidos com zero no bdClass:

bdMatriz >> registro cole1 cole2 cole3 cole4 cole5 cole6 ... cole15
... 45 1 16 3 5 99 16
estes dados coletados deverão ser passados para o bdClass classificados em ordem crescente que devem ficar assim

bdClass >> registro cclas1 cclas2 cclas3 cclas4 cclas5 cclas6 ... cclas16 cclas17 ...cclas99
... 1 0 3 0 5 0 16 0 99

Qual o processo mais curto para se obter esta classificação ? Os senhores têm alguma sugestão?

Obrigado e fiquem na paz.

Francisco

Migração de dados entre Arrays e BDs

MensagemEnviado: 07 Out 2014 17:29
por Jairo Maia
Olá Francisco,

Tenho a impressão que não ficou claro o que você quer com os 2 arquivos. Me parece que você não está falando em consulta relacional, mas sim, sincronizar campos entre arquivos, e diferenciar informações se um não está contemplado no outro. Mas da minha parte confesso que não entendi o que você quer... Se não for uma dificuldade somente minha, você poderia tentar nos esclarecer melhor?

Migração de dados entre Arrays e BDs

MensagemEnviado: 07 Out 2014 23:44
por Francisco Diniz
Boa Noite Pessoal
Boa noite Jairo.

O que estou tentando fazer é simples, porém da maneira que estou fazendo o prg fica longo demais. É assim:
>. Tenho dois bancos de dados, um deles eu chamo de Bdmatriz e o outro de bdClass. O bdMatriz será copiado no bdClass.
O bdMatriz possue 15 campos numéricos em cada registro ( 1450 registros) e que de forma desarranjada podem conter valores de 1 a 99, ou seja, num universo de 99 números o bdClass possue 15 números deste universo e não repetidos por registro.
Já o bdClass possue a mesma quantidade de registro que o bdMatriz, porém com 99 campos. Os registros com os respectivos campos deste bancos serão preenchidos com os quinze números extraídos do bdMatriz, nos locais (campos) correspondentes a grandeza numérica existente nos campos do bdMatriz. Os campos que não tem correspondência com os campos do bdMatriz ficam com valor zero ( 0 ).
Isto na verdade é classificar os 15 números de cada registro do bdMatriz no bdCalss de forma ordenada e dentro dos campos correspondentes ao valor numérico existente nos campos do bdMatriz. (99 campos).

Migração de dados entre Arrays e BDs

MensagemEnviado: 08 Out 2014 02:44
por alxsts
Olá!

Não sei se entendi a questão mas, veja se o código abaixo atende. Não compilei nem testei.
FUNCTION Teste()

   LOCAL aRecord, nVal, nPos

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

RETURN NIL

Migração de dados entre Arrays e BDs

MensagemEnviado: 09 Out 2014 07:16
por Francisco Diniz
Bom dia.

Vou tentar esta sugestão, porém não entendi a passagem que vc menciona, talvez por nunca ter utilizado a função AEVALL(), pode me esclarecer ? :
O que faz esta barra vertical antes do nVal ?
AEval( aRecord, { | nVal, nPosition| bdclass->( FieldPut( nPosition, nVal ) ) } )

Abraços

Migração de dados entre Arrays e BDs

MensagemEnviado: 09 Out 2014 12:31
por alxsts
Olá!
Francisco Diniz escreveu:O que faz esta barra vertical antes do nVal ?
AEval( aRecord, { | nVal, nPosition| bdclass->( FieldPut( nPosition, nVal ) ) } )

A função AEval() executa um code block uma única vez para cada elemento de um array (ou os especificados pelos parâmetros nStart e/ou nCount e passa automaticamente para este code block o conteúdo e posição do elemento do array que está sendo tratado no momento. Na sintaxe de definição de um code block, os pipes ( | ) são obrigatórios e indicam o início e fim da área de parâmetros, parâmetros estes que podem ser opcionais.

Migração de dados entre Arrays e BDs

MensagemEnviado: 11 Out 2014 08:18
por Francisco Diniz
Mestre, Bom dia

Desculpe, mas fiquei travado nesta função aeval(). Já procurei na NET e não encontro exemplos desta função em clipper.
No seu exemplo:
>> AEval( aRecord, { | nVal, nPosition | bdclass->( FieldPut( nPosition, nVal ) ) } )
o nPosittion não ficou claro, veja como ficou meu descritivo do progama>>

// bp é o banco pricipal de dados formado com quinze campos ( bpa1, bpa2 ... bpa15) numéricos de 2 dígitos //podendo conter 0 a 99
// bcl é outro banco contendo 100 campos (bpc1, bpc2, bpl3 ... bpc100) que deverá conter para cada registro
// correspondente ao bp (banco principal) os valores deste banco no local campo correspondente
// se no registro 190 do bp houver o número 56, no reg 190 do bcl o número 56 será alocado no campo bpc56

do while bp->(!eof())
afill(coPs(25),0)
bp->(dbgotop())
for nPos:= 1 to 15
nVal:=bp->(fieldGet(nPos))
coPs[nVal] := nVal
next

bce->(dbapend())

// estou travado aqui >> ( nPosition ? >> não entendi))
AEval(coPs,{|nVal, nPosition|bce->(fieldput(nPosition,nVal))})

bp->(dbSkip())

enddo
dbcloseall()
return nil

Abraços e bom sábado

Migração de dados entre Arrays e BDs

MensagemEnviado: 11 Out 2014 10:00
por Jairo Maia
Olá Francisco,

Eu continuo com dificuldade em entender o que você precisa, e esse laço FOR/NEXT do seu exemplo me complicou mais ainda. Mas no caso do exemplo do Alexandre, nPosition é o número do campo a ser alterado/gravado. Exemplo:
bdclass->( FieldPut( NúmeroDoCampo, ValorASerGravado )
e que é retornado pela pesquisa executado pela AEval().

Migração de dados entre Arrays e BDs

MensagemEnviado: 12 Out 2014 08:38
por Francisco Diniz
Bom dia

Para esclarecer melhor, a coisa é assim:

Cinco departamentos técnico enviam mensalmente a coleta de dados para análise estatística na central de operação. Estes dados são coletados através de uma planilha excel que é convertida em um banco de dados utilizado por clipper, que recebe o nome de BPTEC e o alias Bp

O banco principal que eu chamo no alias de Bp é assim formado:

conbp......Bpa1...Bpa2....Bpa3....Bpa4........Bpa12...Bpa13....Bpa14.....Bpa15
145.........15...... 22......35........6...........89.......12.........1............65
146.........56.......12......9........78...........65.......71........16............34

Conbp >> é uma seqüência numérica que vai de 1 até a ocorrência mais recente ( 6756)
Bpa1 até Bpa15 são os campos que compõem o banco principal que tem valores compreendidos entre 1 a 99 e não se repetem em cada registro.

Eu necessito transportar estes dados para outro banco de dados com 99 campos denominado BPCL com seu alias bcl, que nada mais é que o espelho do Bp, porém com seus valores devidamente alocados nos campos correspondentes.

conbc......Bcp1........Bcp9........Bcp12.....Bcp13.......Bcp15........bcp65.........Bcp99
145..........1............0............12..........0............15............65.............0
146..........0............9............12..........0.............0.............65.............0

Conbc >> é espelho de conbp
Bcp1 até bcp99 são os campos que compõem o banco de dados BPCL

Eu obtenho isto através de loopings “ for - next “ , mas da forma que faço fica um prg muito grande. O que eu gostaria era de resumir este programa em uma forma mais simples.
Espero ter sido claro.

Bom domingo a todos e fiquem na paz

Migração de dados entre Arrays e BDs

MensagemEnviado: 12 Out 2014 11:57
por Jairo Maia
Olá Francisco,

Agora sim! Desenhando ficou fácil! :%

Não usei o exemplo do colega Alexandre Santos (que aliás já havia entendido antes), preferi fazer de um modo que acho que ficou mais fácil de você entender, e que tenho mais facilidade em usar Matrizes.

Veja se esse exemplo vai funcionar:
Function Main()

   Local x, aRecord, nVal, nPos
   
   /*
      Ajuste o tamanho dos campos do arquivo BCE.DBF.
      Usei 8 para conbc e 2 para os demais...
   */
   //If !File( "BCE.DBF" )
    aEstruDBF := {}
    AaDd( aEstruDBF, {"conbc"  ,"N", 8, 0} )
    For x=1 To 99
     AaDd( aEstruDBF, {"bcp"+Hb_NToS( x ),"N", 2, 0} )
    Next
    DBCreate( "BCE.DBF", aEstruDBF )
   //EndIf

   Use bp Shared New
   Use bce Shared New
   
   Select( "bp" )
   
   bp->( dbGoTop() )
   
   While bp->( !Eof() )
   
    aRecord := {}
    For x = 1 To 16
     Private cCampo := Field( x )  // pega o nome do campo
     AaDd( aRecord, &cCampo. )     // salva o conteudo do campo em aRecord
    Next
     
    bce->( dbAppend() )
    For x = 1 To 16
     If x = 1
      bce->( FieldPut( 1, aRecord[ 1 ] ) )  // salva o campo conbc
     ElseIf aRecord[ x ] > 0
      bce->( FieldPut( aRecord[ x ] + 1, aRecord[ x ] ) )
     EndIf
    Next
     
    bp->( dbSkip() )

   EndDo
   
   dbCloseAll()

Return Nil

Migração de dados entre Arrays e BDs

MensagemEnviado: 12 Out 2014 12:36
por alxsts
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

Migração de dados entre Arrays e BDs

MensagemEnviado: 12 Out 2014 19:39
por Jairo Maia
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

Migração de dados entre Arrays e BDs

MensagemEnviado: 13 Out 2014 07:23
por Francisco Diniz
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).

Migração de dados entre Arrays e BDs

MensagemEnviado: 13 Out 2014 10:08
por Jairo Maia
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

Migração de dados entre Arrays e BDs

MensagemEnviado: 13 Out 2014 19:45
por Francisco Diniz
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

Migração de dados entre Arrays e BDs

MensagemEnviado: 14 Out 2014 04:43
por Jairo Maia
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

Migração de dados entre Arrays e BDs

MensagemEnviado: 14 Out 2014 07:25
por Francisco Diniz
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

Migração de dados entre Arrays e BDs

MensagemEnviado: 14 Out 2014 15:39
por Jairo Maia
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...

Migração de dados entre Arrays e BDs

MensagemEnviado: 22 Out 2014 21:12
por Francisco Diniz
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

Migração de dados entre Arrays e BDs

MensagemEnviado: 24 Out 2014 10:33
por Jairo Maia
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.

Migração de dados entre Arrays e BDs

MensagemEnviado: 04 Nov 2014 21:49
por Francisco Diniz
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..