Preencher rapidamente um array com todos os dados do Alias

Fórum sobre outras linguagens de programação.

Moderador: Moderadores

joaorenes
Usuário Nível 1
Usuário Nível 1
Mensagens: 4
Registrado em: 17 Jul 2018 11:12
Localização: Goiânia/GO

Preencher rapidamente um array com todos os dados do Alias

Mensagem por joaorenes »

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
Registrado em: 17 Jul 2018 11:12
Localização: Goiânia/GO

Preencher rapidamente um array com todos os dados do Alias

Mensagem por joaorenes »

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.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Preencher rapidamente um array com todos os dados do Alias

Mensagem por JoséQuintas »

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 mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
joaorenes
Usuário Nível 1
Usuário Nível 1
Mensagens: 4
Registrado em: 17 Jul 2018 11:12
Localização: Goiânia/GO

Preencher rapidamente um array com todos os dados do Alias

Mensagem por joaorenes »

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
Registrado em: 17 Jul 2018 11:12
Localização: Goiânia/GO

Preencher rapidamente um array com todos os dados do Alias

Mensagem por joaorenes »

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 :%
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Preencher rapidamente um array com todos os dados do Alias

Mensagem por rochinha »

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 [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Preencher rapidamente um array com todos os dados do Alias

Mensagem por asimoes »

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)
Responder