Página 1 de 3
Migração de dados entre Arrays e BDs
Enviado: 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:
Código: Selecionar todos
\\ 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
Enviado: 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
Enviado: 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
Enviado: 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
Enviado: 17 Abr 2012 23:41
por JoséQuintas
o mais difícil é entender o que precisa.
No bd pode gravar usando macro.
Código: Selecionar todos
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
Enviado: 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
Enviado: 20 Abr 2012 21:33
por rochinha
Amiguinho,
Baseado no trecho de codigo que voce apresentou:
Código: Selecionar todos
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:
Código: Selecionar todos
...
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
Enviado: 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
Enviado: 22 Abr 2012 11:42
por alxsts
Olá!
O executável ficaria menor e mais rápido se eliminar o uso do operador macro (&):
Código: Selecionar todos
...
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
Enviado: 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:
Código: Selecionar todos
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
Enviado: 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 :
Código: Selecionar todos
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
Enviado: 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
Enviado: 09 Mai 2012 05:52
por rochinha
Amiguinho,
Voce precisa ter certeza que o nome do campo esta sendo criado corretamente.
Código: Selecionar todos
...
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:
Código: Selecionar todos
...
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().
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:
Código: Selecionar todos
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
Enviado: 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
Enviado: 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.
Código: Selecionar todos
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