Clipper On Line • Ver Tópico - Preencher rapidamente um array com todos os dados do Alias

Preencher rapidamente um array com todos os dados do Alias

Discussão sobre outras linguagens de programação.

Moderador: Moderadores

 

Preencher rapidamente um array com todos os dados do Alias

Mensagempor joaorenes » 17 Jul 2018 11:25

Bom dia, Pessoal.

Estou passando por algumas dificuldades no uso da linguagem ADVPL em relação ao preenchimento de um array com informações de um determinado alias. O problema está na lentidão da operação. Usando o alias diretamente, eu consigo listar mais de 100000 registros de forma instântanea, mas quando tento enviá-los para um array aparece a lentidão (mais de 2 min). Como a linguagem advpl, até onde eu sei, deriva do clipper, gostaria de um apoio.

Abaixo está a estrutura que uso para preencher o array:
Local aMeuArray := {}

meuAlias->(DbGotop())

While !meuAlias->(EOF())
aadd(aMeuArray ,{meuAlias->campo1,meuAlias->campo2, .F.})
meuAlias->(DbSkip())
Enddo

Dúvida: há alguma outra forma de fazer o preenchimento do array com as informações vindas do alias?

Obrigado.
joaorenes
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 4
Data de registro: 17 Jul 2018 11:12
Cidade/Estado: Goiânia/GO
Curtiu: 2 vezes
Mens.Curtidas: 0 vez

Preencher rapidamente um array com todos os dados do Alias

Mensagempor Eric.Developer » 17 Jul 2018 15:06

olá,
é assim que se constrói um array dinâmico, independe da origem das informações.

Você informou que é instantâneo, incluindo a movimentação sequencial? ou seja, comentando a linha AADD..., é instantâneo?

1) Eu ia te sugerir que na abertura da tabela/alias, definir uma instrução SQL, filtrando e apenas com os campos necessários.
2) Outra sugestão é ver no ADVPL como executar uma instrução SQL que retorne em array e depois você complementa, exemplo:
aMeuArray:=TQuery():new():execute('SELECT CAMPO1, CAMPO2 FROM ESTOQUE WHERE STATUS='A'') // classe fictícia
AEVAL(aMeuArray, {|a, n|aMeuArray[n]:={a[1], a[2], .F.}}) // adicionando o 3º valor.


Desenvolvendo queries no Protheus
Tente também o fórum ADVPL

neste caso é mais importante pensar nos recursos próprios do ADVPL do que as minúsculas semelhanças com o Clipper.

joaorenes escreveu:Usando o alias diretamente, eu consigo listar mais de 100000 registros de forma instântanea, mas quando tento enviá-los para um array aparece a lentidão (mais de 2 min). Como a linguagem advpl, até onde eu sei, deriva do clipper, gostaria de um apoio.

Abaixo está a estrutura que uso para preencher o array:
Local aMeuArray := {}

meuAlias->(DbGotop())

While !meuAlias->(EOF())
aadd(aMeuArray ,{meuAlias->campo1,meuAlias->campo2, .F.})
meuAlias->(DbSkip())
Enddo

Dúvida: há alguma outra forma de fazer o preenchimento do array com as informações vindas do alias?
Delphi, SQL, FastReport | Xailer VxH Fivewin Minigui Hwgui [x]Harbour
Contate-me: Desenvolvimentos em geral | Treinamentos
Overview/Download: Xailer / Harbour Ferramenta profissional e mais completa.
Avatar de usuário

Eric.Developer
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 161
Data de registro: 31 Ago 2010 22:16
Curtiu: 0 vez
Mens.Curtidas: 8 vezes

Preencher rapidamente um array com todos os dados do Alias

Mensagempor joaorenes » 17 Jul 2018 15:51

Obrigado pela Resposta.

Ao escrever "instantâneo", eu quis dizer que ao passar o Alias da tabela diretamente para um determinado componente do tipo browse (usei o TCBrowse), ele mostra todos os registros' da tabela imediatamente.

Sobre a minha "rotina", qualquer operação que faço para percorrer todos os registros acaba sendo lenta. Ex: o While que preenche o array.

A minha dúvida é: tem como evitar o loop e já carregar o array com os dados da tabela ?

Obs: eu entendo que existem limitações (principalmente usando o AADD, o DBeval, etc.), mas quero tentar todas as possibilidades.
joaorenes
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 4
Data de registro: 17 Jul 2018 11:12
Cidade/Estado: Goiânia/GO
Curtiu: 2 vezes
Mens.Curtidas: 0 vez

Preencher rapidamente um array com todos os dados do Alias

Mensagempor JoséQuintas » 17 Jul 2018 18:55

joaorenes escreveu: ao passar o Alias da tabela diretamente para um determinado componente do tipo browse (usei o TCBrowse), ele mostra todos os registros' da tabela imediatamente.


Muito errado pensar isso.
Qual o tamanho da tela? 30 linhas? o browse vai ler no máximo 32 registros pra preencher a tela.
Já em array.... vai ter que ler o arquivo inteiro antes de apresentar alguma coisa.
Se for arquivo gigante...

qualquer operação que faço para percorrer todos os registros acaba sendo lenta


Imagino que talvez o browse seja lento, apesar de mostrar instantâneo, e por isso quer agilizar.
Pois é... a lentidão é pra ler registros.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Preencher rapidamente um array com todos os dados do Alias

Mensagempor joaorenes » 18 Jul 2018 08:23

Bom dia, JoséQuintas.

Obrigado pela resposta.

Faz sentido o que você acabou de expor. O problema é que os usuários estão acostumados com esse comportamento "instantâneo" e um dos requisitos que tenho que seguir é a "velocidade de execução".

Vou explicar melhor o fluxo da minha aplicação para que vocês possam ter uma ideia mais próxima da minha realidade.

1. Inicialmente, tenho que ir em uma determinada tabela do banco e buscar os registros de acordo com a filial desejada e com os níveis de acesso do usuário que está executando. Se ele tem acesso e optar por ver todos os registros, ele deve ver todos os registros.

2. Depois de selecionado um intervalo, os registros serão carregados em 1 browse que tenha a opção de selecionar os itens.

3. Ao selecionar um ou mais registros, o usuário pode enviar a seleção para outro browse e continuar buscando outros registros de outras filiais (na parte superior da tela, há filtros para isso).

Nos dois browses, mencionados nos itens 2 e 3, estou usando arrays (por ser mais rápido). Eu consigo marcar/desmarcar e "mover" os registros de um browse para outro rapidamente.

PROBLEMA: a lentidão está no item 1, quando tenho que preencher o primeiro array (que será mostrado no item 2). Faço um DbSelectArea() na minha tabela e filtro com o SET FILTER TO. O problema está na lógica abaixo, que - conforme mencionei anteriormente - preenche o primeiro array:

meuAlias->(DbGotop())

While !meuAlias->(EOF())
aadd(aMeuArray ,{meuAlias->campo1,meuAlias->campo2, .F.})
meuAlias->(DbSkip())
Enddo
joaorenes
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 4
Data de registro: 17 Jul 2018 11:12
Cidade/Estado: Goiânia/GO
Curtiu: 2 vezes
Mens.Curtidas: 0 vez

Preencher rapidamente um array com todos os dados do Alias

Mensagempor joaorenes » 18 Jul 2018 08:30

Já em array.... vai ter que ler o arquivo inteiro antes de apresentar alguma coisa.
Se for arquivo gigante...


Eu tentei outras opções, como criar um arquivo/tabela temporária, mas não tive progressos. Em algum momento, seja no preenchimento do browse ou durante a execução do método "marcartudo", a lentidão volta. Até criei um campo de marcação na tabela, mas essa abordagem não funcionou como esperado.

Enfim... Estou tentando :%
joaorenes
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 4
Data de registro: 17 Jul 2018 11:12
Cidade/Estado: Goiânia/GO
Curtiu: 2 vezes
Mens.Curtidas: 0 vez

Preencher rapidamente um array com todos os dados do Alias

Mensagempor rochinha » 24 Jul 2018 00:05

Amiguinhos,

joaorenes
O seu exemplo me pareceu estar acessando uma tabela .DBF. Portanto a seguinte postagem tem os subsídios necessários para a sua filtragem.

Relatório Demorado
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para fivolution@hotmail.com. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar de usuário

rochinha
Membro Master

Membro Master
 
Mensagens: 4538
Data de registro: 18 Ago 2003 20:43
Cidade/Estado: São Paulo - Brasil
Curtiu: 800 vezes
Mens.Curtidas: 242 vezes

Preencher rapidamente um array com todos os dados do Alias

Mensagempor asimoes » 24 Jul 2018 11:50

PROBLEMA: a lentidão está no item 1, quando tenho que preencher o primeiro array (que será mostrado no item 2). Faço um DbSelectArea() na minha tabela e filtro com o SET FILTER TO. O problema está na lógica abaixo, que - conforme mencionei anteriormente - preenche o primeiro array:


SET FILTER vai deixar mais lento mesmo, eu trocaria por OrdScope ou indice temporário para filtrar.

Exemplo essa tabela tem um campo UTI que recebe S ou N

ADMSAUDE->(OrdSetFocus("admsau-0"))
ADMSAUDE->(OrdScope(0, 'S'))
ADMSAUDE->(OrdScope(1, 'S'))
ADMSAUDE->(DbGoTop())

Ou criar um indice temporário para filtrar

INDEX ON UTI TAG UTI FOR UTI = 'S' .AND. ! Deleted() TEMPORARY ADDITIVE

ADMSAUDE->(DbGoTop())
â–ºHarbour 3.x | Minigui xx-x | HwGuiâ—„
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes




Retornar para Outras linguagens de programação

Quem está online

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