PDA

Ver la Versión Completa : Barra de progreso dentro de un TpFIBQuery


Gregorio Cíber
23-12-2015, 19:40:44
Hola amigos.
Hay alguna manera de poner una barra de progreso dentro de query que borra registros de una tabla. El query sería algo así:
with qry_BorrarHastaFecha do
begin
Close;
sql.Clear;
sql.Add('DELETE FROM TABLA');
sql.Add('WHERE (FECHA <= :HASTA_FECHA);');
ParamByName('HASTA_FECHA').AsDate := edt_HastaFecha.Date;
ExecQuery;
end;

El texto SQL iría dentro del componente. Lo pongo así para que se pueda ver lo que hace.
La idea es que aparezca una barra de progreso mientras se están borrando los registros, si es que eso es posible.

Gracias de antemano y Felices Fiestas a todos.

AgustinOrtu
23-12-2015, 21:15:57
Pon el query a trabajar en un hilo en segundo plano y crea un cuadro de diálogo modal con un progress bar

Hay ejemplos de hilos (threads) en el foro, usa la función buscar

Delphius
23-12-2015, 23:49:41
Dos cuestiones:
1. ¿Cuando sabe la barra de progreso cuando detenerse sin saber la cantidad de registros a borrar? O dicho de otro modo: como saber cuando debe estar al 50% de la tarea si ese SQL no indica cuantos registros son afectados?
2. ¿No te parece un pelin fuera de lugar y medio absurdo que un componente que no es visual (el query) disponga internamente de otro que si lo es? Un query es un query, y un progressbar es un progressbar.

Por 1 y 2, tienes un error de concepto, de diseño y de lógica.

En todo caso puedes 1ro lanzar una consulta SQL para saber la cantidad y que registros se van a eliminar. Y luego mediante un ciclo for u otro lanzar una instruccion SQL DELETE para ir borrando el registro i-ésimo. Naturalmente en cada iteración procedes a incrementar la posición del progressbar.

Obviamente, toda esta operatoria debería estar protegida por una transacción.

Saludos,

AgustinOrtu
24-12-2015, 00:26:51
En realidad es mejor poner una marquesia adelante de todo como para decir "estoy procesando"

Me acuerdo que diseñe una clase que reportaba progreso mediante eventos (de hecho, hablaba con vos de este tema en DA, el famoso THacerAlgo (http://delphiaccess.com/foros/index.php/topic/11727-mostrar-formulario-que-haga-algo-y-luego-se-cierre/))

El gran problema es que para grandes procesos, el actualizar tanto, lo hace muy lento; yo pase de ponele 1 minuto procesando a 15, y si sacaba el refresco de la GUI el cuello de botella se iba

Lo que termine haciendo es refrescar cada x items (un delta, vamos) y no en cada uno, y anduvo mucho mejor

Pero sigo pensando que lo mas efectivo es, olvidarse de todo eso de decir: va el elemento x/150 - 30% completado y simplemente poner una marquesina y listo

Delphius
24-12-2015, 01:05:04
Asi es Agustín como debiera hacerse, ir por lo simple. Un cartel de que estoy trabajando y listo. Al finalIzar lo ocultamos.
Recuerdo el hilo que comentas, y esas soluciones bien sos viables para casos que lo ameriten.

En esta ocasión di la respuesta más simple que puede darse. Para que se haga una idea y estudie realmente lo que pretende.
Convengamos que derrapa mucho mezclar un dataset con un progressbar, algo no cuadra... o no tiene en cuenta lo que en verdad significa la abstracción que implica cualquier dataset, o no se hace la idea de lo que hace a la separación de intereses de los componentes... va que digo... hasta del principio básico del paradigma OO.

saludos,

Gregorio Cíber
24-12-2015, 08:47:04
Gracias a todos por responder. Iré mirando lo que me habéis indicado.
Saludos.

Gregorio Cíber
24-12-2015, 09:07:42
Dos cuestiones:
1. ¿Cuando sabe la barra de progreso cuando detenerse sin saber la cantidad de registros a borrar? O dicho de otro modo: como saber cuando debe estar al 50% de la tarea si ese SQL no indica cuantos registros son afectados?
2. ¿No te parece un pelin fuera de lugar y medio absurdo que un componente que no es visual (el query) disponga internamente de otro que si lo es? Un query es un query, y un progressbar es un progressbar.

Por 1 y 2, tienes un error de concepto, de diseño y de lógica.

En todo caso puedes 1ro lanzar una consulta SQL para saber la cantidad y que registros se van a eliminar. Y luego mediante un ciclo for u otro lanzar una instruccion SQL DELETE para ir borrando el registro i-ésimo. Naturalmente en cada iteración procedes a incrementar la posición del progressbar.

Obviamente, toda esta operatoria debería estar protegida por una transacción.

Saludos,

Todo lo que me indicas tienes razón. Lo que ocurre es que he puesto el mínimo código posible para que os hicierais una idea de lo que quería. El número de registros lo calculo antes. De todas formas gracias por tu comentario.

Gregorio Cíber
24-12-2015, 09:11:32
Asi es Agustín como debiera hacerse, ir por lo simple. Un cartel de que estoy trabajando y listo. Al finalIzar lo ocultamos.
Recuerdo el hilo que comentas, y esas soluciones bien sos viables para casos que lo ameriten.

En esta ocasión di la respuesta más simple que puede darse. Para que se haga una idea y estudie realmente lo que pretende.
Convengamos que derrapa mucho mezclar un dataset con un progressbar, algo no cuadra... o no tiene en cuenta lo que en verdad significa la abstracción que implica cualquier dataset, o no se hace la idea de lo que hace a la separación de intereses de los componentes... va que digo... hasta del principio básico del paradigma OO.

saludos,
Todo esto está contemplado, sólo que qería saber si se podía hacer de forma sencilla. No obstante, me parece que pondré un 'cartelito', y listo.
Gracias por el comentario.