Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Problema con GotoBookmark (https://www.clubdelphi.com/foros/showthread.php?t=76024)

glopez 04-10-2011 19:28:10

Problema con GotoBookmark
 
Tengo un problema al recorrer los registros de un Grid que no consigo solucionar.
Lo que tengo es un listado de facturas y quiero recorrer los registros que selecciono y mostrar en un label la suma de los registros seleccionados.
con este codigo funciona bien pero lo que ocurre es que el grid se va moviendo cuando selecciono los registros que están muy abajo y me gustaría que el grid se quedara exactamente en la misma posición.
Código Delphi [-]
    begin
      Temp:=0;
      PBookmark:=Q.GetBookmark;
      Q.DisableControls;
      for i:=0 to DBG1.SelectedRows.Count-1 do
      begin
        Q.GotoBookmark(pointer(DBG1.SelectedRows.Items[i]));
        Temp:=Temp+Q.fieldbyName('total').AsFloat;
      end;
      ResultadoParcial.Caption:='  : '+FormatFloat('#,##0.00 €',Temp)+'      Reg: '+IntToStr(DBG1.SelectedRows.Count);
      Q.GotoBookmark(PBookmark);
      Q.FreeBookmark(PBookmark);
    end;

Probé con este otro código pero al recorrer los registros cuando estaban ordenados por fecha descendentemente no se recorrian correctamente (se posiciobnaba en otro registro y no se porqué)
Código Delphi [-]
    begin
      Temp:=0;
      Q2.Close;
      Q2.SQL.Assign(Q.SQL);
      Q2.Open;
      for i:=0 to DBG1.SelectedRows.Count-1 do
      begin
        Q2.GotoBookmark(pointer(DBG1.SelectedRows.Items[i]));
        Temp:=Temp+Q2.fieldbyName('total').AsFloat;
      end;
      ResultadoParcial.Caption:='  : '+FormatFloat('#,##0.00 €',Temp)+'      Reg: '+IntToStr(DBG1.SelectedRows.Count);
    end;

Gracias.

Casimiro Noteví 04-10-2011 19:41:47

Si los registros del grid lo has obtenido con un select, entonce sólo añade el sum(campo) al select y el resultado lo asocias a un dbedit.
En cuanto a usar un TBookMark, como lo estás haciendo, me parece que estás asignando el bookmark en el bucle, a cada registro, quita esa línea.

oscarac 04-10-2011 19:46:29

Casimiro
me parece que el amigo quiere sumar solo los que estan marcados

Casimiro Noteví 04-10-2011 20:04:53

Vaya, entonces no he entendido bien la pregunta al decir: "pero lo que ocurre es que el grid se va moviendo cuando selecciono los registros que están muy abajo".
Se tendrá que mover el dbgrid para marcarlos, digo yo.

O no acabo de entender la pregunta :confused:

Si es sólo sumar los marcados entonces lo que he dicho antes está bien, creo, ya que sólo hace falta recorrer y comprobar si está seleccionado, pero no asignarle un bookmark a cada uno, como hace en el bucle.

Chris 04-10-2011 20:06:39

Una cosa que veo en el primer código, es que no estás haciendo una llamada a EnableControls. Por otro lado, no me queda claro el problema que estás teniendo con el primer código.

Saludos,
Chris

Casimiro Noteví 04-10-2011 21:33:42

Pues ahora que lo veo más tranquilo, aparte de lo que dice Chris, no veo que esté mal.
Habrá que esperar que aclare glopez exactamente el problema.

cloayza 05-10-2011 02:34:45

Cita:

Empezado por Chris (Mensaje 414533)
Una cosa que veo en el primer código, es que no estás haciendo una llamada a EnableControls. Por otro lado, no me queda claro el problema que estás teniendo con el primer código.

Saludos,
Chris

Como dice el compañero Chris, creo que falta el EnableControls después de volverlo al registro que estaba antes de realizar la suma...

Código Delphi [-]
 begin
      Temp:=0;
      PBookmark:=Q.GetBookmark;
      Q.DisableControls;
      for i:=0 to DBG1.SelectedRows.Count-1 do
      begin
        Q.GotoBookmark(pointer(DBG1.SelectedRows.Items[i]));
        Temp:=Temp+Q.fieldbyName('total').AsFloat;
      end;
      ResultadoParcial.Caption:='  : '+FormatFloat('#,##0.00 €',Temp)+'      Reg: '+IntToStr(DBG1.SelectedRows.Count);
      Q.GotoBookmark(PBookmark);
      Q.EnableControls;
      Q.FreeBookmark(PBookmark);
    end;

A ver que pasa ahora...

glopez 05-10-2011 09:54:28

Es cierto que me falta
Q.EnableControls;
al copiar el codigo me salte esa linea
El problema exacto con el primer código es el siguiente:
Imaginemos que tengo un grid con las siguientes lineas visibles
Nº Frac nombre total
1 Pepe 5
2 Juan 7.5
3 Pedro 8
.
.
.
30 Antonio 475

Entonces después de seleccionar varios registros y ejecutarse el código anterior para recorrer los registros seleccionados y sumarlos (sólo los seleccionados). Puede que el primer registro que tenga visible ahora no sea la Factura 1 si no la 3 y la última la 33. Es decir los registros se han desplazado un poco hacia arriba. Espero haberme explicado bien. Gracias.

ecfisa 05-10-2011 20:40:19

Cita:

Empezado por glopez (Mensaje 414605)
Entonces después de seleccionar varios registros y ejecutarse el código anterior para recorrer los registros seleccionados y sumarlos (sólo los seleccionados). Puede que el primer registro que tenga visible ahora no sea la Factura 1 si no la 3 y la última la 33. Es decir los registros se han desplazado un poco hacia arriba. Espero haberme explicado bien. Gracias.

Hola glopez.

Humm, sigo con la duda de haber entendido bién lo que buscas. Según entiendo deseas que cuando termines de seleccionar varios registros desde el DBGrid, haya hecho los scrolls que fueran, vuelva a posicionarse en el primero de la seleccion.

Si es así, creo que tendrías que hacer algo como:
Código Delphi [-]
...
var
  i: Integer;
  BM: TBookmark;
  Total: Double;
begin
  if DBGrid1.SelectedRows.Count > 0 then
  begin
    Total:= 0;
    BM:= DataSet.GetBookmark;
    try
      for i:= 0 to DBGrid1.SelectedRows.Count-1 do
      begin
        DataSet.GotoBookmark(Pointer(DBGrid1.SelectedRows[i]));
        Total:= Total + DataSet.FieldByName('FLOTANTE').AsFloat;
      end;
    finally
      DataSet.GotoBookmark(Pointer(DBGrid1.SelectedRows[0]));
      DataSet.FreeBookmark(BM);
    end;
    Label1.Caption:= FloatToStr(Total);
  end;
end;

Un saludo.

glopez 06-10-2011 10:27:47

Intentare explicarme un poco mejor. Lo que quiero hacer es lo siguiente:
Tengo una tabla con 1000 lineas pero en el grid tengo visible sólo 10 lineas.
1
2
3
...
10
y selecciono las lineas 2 y 8 haciendo click con el ratón. Quiero que después de recorrer las lineas seleccionas con GotoBookmark siga viendo los registros del 1 al 10 y no otros.

ecfisa 06-10-2011 12:54:33

Hola glopez.

Soy medio duro de mollera pero ahora creo que te entendí... :p:)

Una solución que se me ocurre es crearte al vuelo una consulta apuntando a la misma tabla y obtener el dato de ella utilizando el BookmarkList del DBGrid:
(asumo que la tabla involucrada se llama: TU_TABLA)
Código Delphi [-]
procedure TForm1.btnTotalClick(Sender: TObject);
var
  BM: TBookMark;
  i: Integer;
  Tot: Double;
begin
  with TIBQuery.Create(nil) do   // Crear consulta 
  try
    Database:= IBDatabase1;    // Asignar Database 
    Close;
    SQL.Text:= 'SELECT TOTAL FROM TU_TABLA'; // Seleccionar sólo campo a sumar
    Open;
    Tot:= 0;
    for i:= 0 to DBGrid1.SelectedRows.Count-1 do
    begin
      GotoBookmark(Pointer(DBGrid1.SelectedRows[i])); // Posicionarse
      Tot:= Tot + FieldByName('TOTAL').AsFloat;       // acumular
    end;
  finally
    Free;
  end;
  Caption:= FloatToStr(Tot);  // mostrar acumulador
end;
Al no realizarse posicionamiento sobre la consulta relacionada al TDBGrid, este permanecerá inamovible.


Como no especificaste con que motor de BD ni componentes estas trabajando hice el ejemplo con Firebird/IBX, reemplazá por los componentes que utilices.

Un saludo.

glopez 06-10-2011 16:45:18

Co la mollera mala estamos más de uno, pero ahora si me has entendido bien. Pero si te fijas en el segundo código que puse al principio yo hacia lo mismo que me explicas ahí.
Pero no entiendo porque a veces no se posiciona en los registros correctamente. Me pasa que algunas veces en vez de irse a unos de los registros que tengo seleccionado se me queda en el anterior. Utilizo Firebird y IBX pero he probado con FibPlus y tambien falla ya estoy pensando que puede que sea el Grid (ExDBGrid). Pero lo que no comprendo es que cuando recorro la consulta (Q) que esta directamente asociada al Grid no falla.
Sólo pasa a veces y casi siempre cuando ordeno el listado por fecha descendentemente. Gracias.

ecfisa 06-10-2011 22:28:50

Hola glopez.
Cita:

Pero si te fijas en el segundo código que puse al principio yo hacia lo mismo que me explicas ahí.
Es que el endurecimiento de mollera me está afectando la vista tambien... :o:)

Seguramente no lo he probado tán a fondo como vos, y por eso no he detectado el fallo. Voy a revisar con cuidado y cualquier novedad que encuentre te comento.

Un saludo.

ecfisa 06-10-2011 22:47:33

Hola de nuevo.
Cita:

Sólo pasa a veces y casi siempre cuando ordeno el listado por fecha descendentemente
Despues de leer ese comentario, hice unas pruebas y solo logré reproducir un comportamiento extraño si en la consulta asociada al DBGrid tengo:
Código SQL [-]
SELECT * FROM TABLA ORDER BY FECHA DESC

Y en la consulta secundaria:
Código SQL [-]
SELECT TOTAL FROM TABLA
Lo cuál es lógico por que en la consulta relacionada al DBGrid se ha alterado el órden mediante 'ORDER BY FECHA DESC'.

Se solucionó immediatamente con:
Código SQL [-]
SELECT TOTAL FROM TABLA ORDER BY FECHA DESC

Un saludo.

glopez 07-10-2011 09:55:35

Hola ecfisa, si te fijas bien en el 2 codigo que pongo a Q2 le asigno exactamente la misma sentencia que tiene la consulta asociada al Grid Q.
Q2.SQL.Assign(Q.SQL);
Es decir ambas son identicas.
Lo único que hago y que no puse en el código para no liar más es después de asignar: Q2.SQL<-Q.SQL.

es sustituir la linea de:
select numero, nombre, fecha,...
por
select *
que lo hago así
Q2.SQL[0]:='select *'
y en la primera linea del SQL sólo hay eso.

Ej:
select numero, nombre, fecha,...
from facturas
where ...
order by fecha desc

ecfisa 07-10-2011 10:13:24

Hola glopez.

Entonces realmente no se que decirte ya que hice muchas pruebas con el código del mensaje #11 y se comportó correctamente.
Quizá, como comentás en un mensaje anterior, el problema lo provoque el componente ExDBGrid...

Un saludo.

glopez 07-10-2011 10:31:35

Muchas gracias de todas formas. Estoy pensando en cambiar el Grid pero me supone muchos cambios y lo estoy dejando un poco. cuando lo haga ya te comentaré.

Un Saludo.


La franja horaria es GMT +2. Ahora son las 22:15:53.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi