× Linguagem de Programação ADVPL

Perguntas Desafio - Cancelar Query e Controlar Barras de Progressão corretamente

Mais
9 anos 9 meses atrás #27105 por filipe.nanclarez
Pessoal, boa tarde.

Estou aqui com um desafio, que não consigo implementar. E gostaria de compartilhar com todos, pois pode gerar uma solução muito útil.

Eu desenvolvo relatórios já a bastante tempo. E sempre na mesma pegada. E falando de relatórios não personalizáveis, temos sempre aquele processo comum, onde há uma barra de progresso e um botão cancelar. Podemos fazer isso com vários componentes, entre eles o Processa e o MsNewProcess.

Os dois possuem a opção de usar o botão cancelar, mas convenhamos, ele não funciona como deveria. É necessário pressionar compulsivamente para que ele cumpra ao que se propõe. Além disso, o código verifica a variável atribuída no botão, e se ela for verdadeira, podemos cancelar nossa execução.

Entretanto, isso só funciona quando o tempo que o sistema demora para gerar o relatório está relacionado com a renderização dele, não com a busca dos dados.

Então temos dois problemas:

1 - Como fazer o botão cancelar, funcionar corretamente, sem termos que ficar clicando nele loucamente?

2 - Como fazer para cancelar uma consulta enviada ao banco, quando ele demora muito para responder, seja por BeginSql, ou TcGenQry?

Acreditem, já testei muitas variações das implementações desses controles. A maioria não funciona.

Pensei em algo mais elaborado, como executar a rotina, em um processo separado, em outra Thread ou através de um job, e com isso, teríamos controle sobre o processo para poder cancela-lo, mesmo que ele estivesse esperando retorno do banco de dados. Mas não estou conseguindo implementar essa ideia.

Se alguém souber o caminho das pedras e quiser contribuir, tenho certeza que será de ajuda para muitos, e melhorará a qualidade da interação com o usuário ao lidar com relatórios grandes...

At.
Filipe Nanclarez
Analista ADVPL

Por favor Acessar ou Registrar para participar da conversa.

Mais
9 anos 9 meses atrás #27111 por filipe.nanclarez
Pessoal ...

Aparentemente consegui resolver os dois problemas.

A idéia é assim:

Ao iniciar o relatorio, chamo um JOB. Nesse job, executo a SQL, inserindo o resultado em uma tabela temporaria do proprio SQL.
Enquanto isso, fico dentro de um loop na rotina original, verificando se o job já terminou ou náo. Nesse loop, uso um comando para manter o botao cancelar disponivel para o usuario sem a impressáo de que está travado.
Se o usuario cancelar, eu volto para o siga, e libero a tela. O JOB continua em segundo plano, mas o usuario náo percebe, e continua trabalhando. Quando o JOB termina, ele encerra sozinho.

Estou comentando o código, e em breve posto completo aqui. Tive que usar variaveis globais, e uns macetes pra dar certo, mas nada monstruoso.

Se souberem de uma forma mais elegante e sofisticada, compartilhem ...

Obrigado a todos que colaboraram no particular para dar certo ...

At.
Filipe Nanclarez
Analista ADVPL

Por favor Acessar ou Registrar para participar da conversa.

Tempo para a criação da página:0.116 segundos
Joomla templates by a4joomla