PDA

Ver la Versión Completa : Progreso mientras carga datos...


jarlos
25-06-2007, 19:37:34
Hola a todos...

Alguien sabe cómo manipular el progreso de una consulta mientras se está ejecutando?.

Tengo el siguiente problema: tengo dos clientdataset (el maestro y el detalle) y cuando cargo data con muchos detalles, la aplicación se paraliza, por lo que le he puesto una ventana que me muestre algún tipo de progreso. Le he puesto a la ventana de progreso un control para mostrar un avi. Todo funciona bien. Pero necesito usar otro control X y si le quito el que muestra el avi, la ventana no refresca, se queda paralizada. Alguien sabe cómo ejecutar alguna acción (puede ser Application.ProcessMessage) cuando el clientdataset de detalle recibe un registro y poder actualizar el control de progreso?. Existe ese método para los clientdataset? Algun otra sugerencia?

casacham
26-06-2007, 01:11:18
HOLA
Para lo que necesitas es utilizar uno de estos objetos TProgressBar o un TGauge para enseñar el progreso de las operaciones mientras se procesan los datos. Tenes que calcular antes el numero de procesos que vas a realizar. Esto se hace la propiedad Count, por ejemplo ADOTable1.RecordCount. El valor arrojado lo tenes que poner en esta propiedad:

Gauge1.MaxValue:=ADOTable1.RecordCount;
ProgressBar1.Max:=ADOTable1.RecordCount;

Si el bucle de analisis hace dos pasadas, entonces tendras que multiplicar ADOTable1.RecordCount por 2 o por el numero de veces que analises los datos de tu tabla.

Luego dentro del bucle utiliza una variable Integer como contador y asignala dentro del bucle a una de estas propiedades y listo. Tienes una hermosa barra mostrandote el progreso de tus operaciones en tiempo real

Var I: Integer;
begin
I:=0;
'Bucle . . . . .' begin
{ Bloque que analiza tus datos
...........................
...........................
...........................
........................... }

ProgressBar1.Position:= I;
Gauge1.Progress:= I;
I:=I+1;
ADOTable1.Next;
end; // Fin del bucle;

jarlos
26-06-2007, 14:39:24
Hola casacham...

Agradezco mucho tu propuesta, pero ya la he probado, e inclusive para mostrar el formulario del progreso ya he probado creándolo desde un objeto TThread. También le puse un Timer al form y en el evento OnTimer le puse una instrucción Application.ProcessMessage, pero nada.

Otra cosa, no esto de acuerdo en utilizar la instrucción RecordCount, mucho menos en controles ADO (estoy usando controles dbexpress).

De todas formas, creo que me quedaré con el AVI, por cierto, alguien sabe dónde conseguir un AVI con una animación parecida a la barra de progreso que muestra el Windows Live Hotmail cuando está cargando, o como el del Microsoft SQL Server 2005 ?

cHackAll
29-06-2007, 23:04:55
...cuando cargo data con muchos detalles, la aplicación se paraliza...

Bueno amigo jarlos... lo que sucede es bastante simple, y te lo explico; la librería que está dando soporte al .AVI (el que te permite verlo) es la winmm.dll mediante la unidad MMSystem del Delphi (si estas utilizando DirectShow es prácticamente el mismo caso)… éstas librerías son solo una interfaz que permiten al codex adecuado (como su nombre lo dice), poder decodificar el formato del .AVI y así producir los frames (cuadros de imágenes consecutivos), de video y sonido. Para realizar dichas operaciones; éstas librerías crean un grupo de hilos en el proceso que así lo solicita indirectamente. Lo que significa que tu hilo principal (el que maneja tu ventana), mientras anda ocupado comunicándose vía OLE al motor de la BD (y que en dicha acción ni si quiera le permite procesar los mensajes para refrescar la ventana), los hilos creados por el sistema multimedia se encargan de permitir al usuario visualizar el video como si estuviese “separado” del proceso afectado.

Y bueno, sin intentar dar mas vueltas en la causa, te adjunto la solución que está basada en la creación de un hilo, el cual a su ves crea una ventana del cual los mensajes son procesados en el mismo. Lo que responde exactamente a aquellos problemas causados por un hilo principal “ocupado”. El modo de empleo es simple;


var Rect: TRect;
begin
Rect := BoundsRect;
BusyStatus('Sistema ocupado, por favor espere...', @Rect);
...


Procura que la función BusyStatus sea llamada justo antes del inicio del problema, el la misma unidad "detectará" cuando debe "ocultarce", y si quieres utilizar la unidad en otros momentos te sugiero que lo utilices (por ejemplo) al momento en que esta en plena creación tu aplicación:


BusyStatus('Inicializando el sistema...');
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TForm3, Form3);
Application.CreateForm(TForm4, Form4);
Application.CreateForm(TForm5, Form5);
Application.CreateForm(TForm6, Form6);

Continue;
Application.Run;


"Función Continue, creada para aquellas aplicaciones que no utilizan GUI o cuando no funciona por no tener controles, o simplemente para asegurar un funcionamiento adecuado"

De seguro será de utilidad y una base para solucionar otro tipo de problemáticas de la misma índole.

Saludos!

courtois
30-06-2007, 10:15:24
En el evento OnFetchProgress de los componentes ADO te da Progress y MaxProgress que corresponden a "donde va" y "hasta donde llega", respectivamente

maro
30-06-2007, 11:38:55
Hola,

Si estás tarbajando en 3 capas con Capas sql y capas clientes usando TClientdataset para la consulta de datos es normal que te suceda esto.

Si tu consulta retorna un número considerable de registros, es lógico que durante un cierto tiempo, la capa cliente se quede esperando una respuesta de la capa SQL.

Para estos casos te recomiendo implementar un procedimiento auxiliar que "obtenga" los datos por bloques de registros y los valla adjuntando a un tClientDataset final.

El resultado final es más lento, pero el usuario no tiene la sensación de que su aplicación se ha colgado, además de que puedes poner un gauge indicando el progreso de la operación. Una vez finalizado el proceso podrás manipular como siempre el tClientdataset final.

Ten en cuenta que cuando ejecutas una consulta de datos con un tClientDataset, éste no conoce el número de registro que se le retornará de la capa SQL y no te puede dar información sobre esto.

Igualmente, cuando un tClientadataset recibe un conjunto de registro, no los va recibimiento de uno en uno, ni de "x" en "x" registros, sino, que recibe un "paquete" que contiene la respuesta de la capa SQL, incluyendo estructura de la tabla, restricciones, formato de campos, etc... y por último los registros solicitados.

Un Saludo.

juniorSoft
16-10-2007, 19:54:22
Hola a todos, he encotrado esta conversacion y quisiera ver un pequeño ejemplo de como se haria lo mensionado en tres capas :confused:. gracias ante todo

capo979
18-10-2007, 16:39:45
este mensaje va para [cHackAll] (http://www.clubdelphi.com/foros/member.php?u=13492)

Probe _Busy y lo uso antes de hacer una consulta que me tarda el tema es que lo unico que hace es mostrar el cartel y lo que indica que esta haciendo algo que esta de verde no mueve, tenes alguna idea de que puede ser

saludos