Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Poner columna de checkbox dentro de dbgrid para hacer multiseleccion (https://www.clubdelphi.com/foros/showthread.php?t=63360)

juscar 11-02-2009 09:38:42

Poner columna 'falsa' de checkbox dentro de dbgrid para hacer multiseleccion
 
Buenas, tengo un problema con un dbgrid, os explico. Tengo una tabla de la que extraigo X campos; mi idea es añadir una nueva columna de checkbox que permita al usuario seleccionar las filas que quiera, para recoger varios IDs y hacerles un tratamiento posterior.
He visto lo de pintar checkbox (http://delphi.about.com/od/usedbvcl/l/aa082003a.htm)
y me funciona creando un campo boleano que no existe en la tabla, pero no los puedo modificar.
Alguien me echa un cable, porque no encuentro nada en internet.
Saludos y gracias..

fjcg02 11-02-2009 16:02:05

Hola,
te cuento un poco lo que podrías hacer, pero no tengo delphi aquí para comprobarlo y darte mejores pistas.
En ocasiones, para seleccionar registros en un grid lo que hago es:
- crear un stringlist
- Cuando pulso espacio selecciono el registro. Cojo el id del registro y lo almaceno en el stringlist. Si está seleccionado lo borro del stringlist.
- Al pintar la fila, si el id está en la lista, pinto en negrita.

¿ Cómo encaja esto en tu pregunta ?
Sencillo, en lugar de pintar en negrita, añade un campo calculado que no dependa del dataset, y si el id del registro está en la lista, pintas checado el checkbox.
Después, si quieres hacer algo con los registros seleccionados, te coges el stringlist y procesas todos los ids que tenga.

Puedes mejorar la selección del registro obviamente utilizando el campo calculado del checkbox.

Espero que lo hayas entendido, es bastante sencillo.

Suerte y un saludo

juscar 13-02-2009 10:22:32

hola de nuevo
 
Muchas gracias por contestar.EL tema es que la info la saco de una query que no puedo modificar en el dataset. Aunque por lo que dices y no habia pensado en eso, otra opcion sería ir coloreando filas cada vez que seleccione el usuario (usando el stringlist para guardar los IDs de cada fila).
Voy a intentar hacerlo por mi cuenta y ya os comento si me sale.
Gracias por darme otro punto de vista

fjcg02 13-02-2009 21:52:21

Para orientarte 'un poco'
Previamente he creado un campo en el dbgrid titulado 'Seleccionado'
Este campo no tiene asociado campo de la bbdd y es el primero de todos
Además mecesitas un memo con nombre Memo1. Puedes sustituirlo por un stringlist. A tu gusto.
Importante, el grid no permite editar. No sé que pasaría si fuese posible la edición!!

Pintado del grid. Si el id está en la lista, se escribe el checkbox y se pone en negrita toda la fila. Si no lo está
Código Delphi [-]
procedure TFSelPartidas.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var R:TREct; longitud, selecc: integer;
begin
Selecc:= 0;
// utilizo un memo para hacer de lista de id's de registros modificados ¿?
if  memo1.LineS.IndexOf(QTarifas.FieldByName('IdTarifa').AsString) >= 0 then
  begin
    (Sender as TDBGrid).Canvas.Font.Style:=[fsbold];
    (Sender as TDBGrid).Canvas.FillRect(Rect);
    Selecc:= DFCS_CHECKED;
  end
else DBGrid1.Canvas.Font.Style:=[];
   if Column.Title.Caption= 'Seleccionado' then 
// si es el campo indicado, pinto un check seleccionado o no en base al valor de selecc
        DrawFrameControl(DBGrid1.Canvas.Handle,REct, DFC_BUTTON, DFCS_BUTTONCHECK or Selecc)
    else
       (Sender as TDBGrid).DefaultDrawColumnCell(Rect, DataCol, Column, State);

end;
Para incluir los id's en el memo utilizo el siguiente procedimiento
Código Delphi [-]
procedure TFSelPartidas.DBGrid1KeyPress(Sender: TObject; var Key: Char);
var posicion: integer;
begin
if (key = ' ') and ( not WEdicion) then // si se pulsa espacio, se añade o borra el id
begin
  posicion:= memo1.LineS.IndexOf(QTarifas.FieldByName('IdTarifa').AsString);
 if posicion < 0 then Memo1.Lines.Add(QTarifas.FieldByName('IdTarifa').AsString)
 else Memo1.Lines.Delete(posicion);
 DBGrid1.Repaint;
end;
if not WEdicion then
StatusBar1.PAnels[0].Text:= 'Seleccionadas '+inttoStr(Memo1.lines.Count)+' partidas';

end;
También si clickamos sobre el checkbox de la fila seleccionamos o seleccionamos
Código Delphi [-]
procedure TFSelPartidas.DBGrid1CellClick(Column: TColumn);
var key:  char;
begin

if Column.Title.Caption= 'Seleccionado' then
begin
  key := ' ';
  DBGrid1KeyPress(DBGrid1, key);
end;
end;
La solución queda cuanto menos 'elegante'
Suerte y saludos

juscar 16-02-2009 09:31:45

Ya sale
 
Al final, usando parte de tu codigo y algo que tenia ya echo, he optado por colorear las filas, aunque me quedo con tu codigo por si alguna vez me hace falta. Funciona de p.m.

Has sido muy amable.

Vales08 02-04-2013 20:03:57

checkbox n dbgrid
 
Buenas tardes..
te hago una consulta fjcg02. Porque he probado tu código y me funciona a la perfección, pero yo querría que en lugar de pasar los ID al memo, me gustaria pasar los nombres de los registros, de paso sirve el memo para ir mostrando los registros que voy seleccionando
.. Eso se puede lograr con este mismo codigo??

Muchas gracias.!!

fjcg02 02-04-2013 22:21:27

Hola, sí que se puede. Donde pone idtarifa pon el nombre de tu campo. Supongo que será 'nombre'.
En el memo se guardan strings. Da igual que sean ids a que sea cualquier campo de otro tipo ( en tu caso nombre) . Lo que sí debes tener claro es que el campo no tendría que ser repetido, aunque también valdría, pero sólo te lo incluirá en el memo una sola vez.

Prueba y nos dices si te vale.

Saludos

Vales08 03-04-2013 00:36:08

Muchas gracias por la respuesta. Te digo que yo eh probado de cambiar el ID, por el NOMBRE y me lo carga, el problema esta en que cuando yo deselecciono un registro me lo carga de nuevo y me lo repite.

fjcg02 03-04-2013 09:09:28

Entonces es porque cuando buscas el nombre en el memo no lo encuentra. Por eso lo vuelve a cargar.

Revisa la línea

posicion:= memo1.LineS.IndexOf(QTarifas.FieldByName('IdTarifa').AsString);

que es la que no te devuelve un valor mayor que 0 , es decir, no lo encuentra. De ahí que te lo agregue. Supongo que en esa línea también has cambiado el campo a buscar.

Saludos

Vales08 03-04-2013 13:52:27

Ahh claro, pero como puedo solucionar eso? el campo a buscar si lo cambie..

Te hago otra consulta si me la puedes responder o ayudar. Yo con esos registros extraidos o seleccionados del dbgrid, necesito guardarlos en otra tabla que tengo en la base de datos, la cual viene a ser la relacion entre dos otras tablas. Puedes ayudarme con eso?

Muchas gracias y disculpa tantas preguntas juntas.
Un saludo

fjcg02 03-04-2013 14:19:44

Para solucionarlo en todos los sitios donde ponga QTarifas.FieldByName('IdTarifa').AsString pones tu campo.

Para añadir los registros seleccionados en otra tabla, recorres las líneas del memo y haces una inserción en la otra tabla con los valores adecuados. De ahí que yo guarde los id's. El usuario ve lo seleccionado pintado de otro color. Al darle al botón "guardar" o "procesar", puedes pedir confirmación al usuario, y sólo te queda trasegar los id's.

Código Delphi [-]
For n:= 0 to memo1.Lines.Count -1 do
begin
  -- aquí haces lo que necesites; 
  -- configuras los parámetros de la inserción
  -- ejecutas la inserción
end;

Espero que te sirva de ayuda

Saludos
PD: para que no nos echen la buya, nuevas preguntas, nuevo hilo.

Vales08 03-04-2013 14:34:55

Muchisimas gracias, es justo lo que necesitaba.. Lo pbuebo y cualquier cosa vuelvo a consultar..
Si, ya sabia que para nueva pregunta, nuevo hilo, pero sos tan preciso y claro a la hora de responder que preferi preguntarte en ese moemnto..

Muchas gracias de nuevo.
Saludos

Vales08 03-04-2013 20:44:50

fjcg02 te podria pedir que me des un ejemplo de como pasas los ID's a otra tabla, yo lo hago, pero me guarda un solo registro pero repetido(es decir 2 veces). Eh dejado los campos ID como estaba el codigo de base que habias pasado en vez de los nombres. Pero aun asi no me funciona.

Primero hago un append de la tabla para la inserción
Luego asigno los ID's a la tabla (tengo las claves foraneas)
y luego guardo.

Gracias

fjcg02 04-04-2013 13:17:57

No tengo ningún ejemplo que haga eso.

lo normal es que tengas un TQuery de inserción parametrizado, e iteres por cada línea del memo. Por cada línea, asignas parámetros y ejecutas el Tquery ( TQuery.Execute ).

Es básicamente lo que te he comentado anteriormente.

Con un append, por cada línea deberás hacer el append y tendrás que alimentar los campos del registro dado de alta.

Abre un hilo nuevo, expón tu código y solicita ayuda al respecto.

Saludos

Vales08 04-04-2013 13:53:31

Perfecto, muchas gracias por todo.. Han sido de gran ayuda tus respuestas.

Saludos.

ginesgomezlopez 11-01-2016 23:00:18

procedure TFSelPartidas.DBGrid1KeyPress(Sender: TObject; var Key: Char);
var posicion: integer;
begin
if (key = ' ') and ( not WEdicion) then // si se pulsa espacio, se añade o borra el id
begin
posicion:= memo1.LineS.IndexOf(QTarifas.FieldByName('IdTarifa').AsString);
if posicion < 0 then Memo1.Lines.Add(QTarifas.FieldByName('IdTarifa').AsString)
else Memo1.Lines.Delete(posicion);
DBGrid1.Repaint;
end;
if not WEdicion then
StatusBar1.PAnels[0].Text:= 'Seleccionadas '+inttoStr(Memo1.lines.Count)+' partidas';

end;

Hola quiero seleccionar varias filas indistintamente de su orden dentro de un DBGrid, lo mismo que se explica en este ejemplo, pero la me da error en "(not WEdicion), a qué puede ser debido

fjcg02 11-01-2016 23:35:01

Hola,
ha llovido mucho y no me acuerdo qué demonios hacía el código exactamente.

Supongo que WEdicion es una variable del formulario que indica si está en edición el dataset o no.

Podrías sustituirlo por algo parecido a
and ( not estadoEdicion in DBGrid.Datasource.Dataset.Status )

ó

and ( not estadoEdicion in TDBGrid(Sender).Datasource.Dataset.Status )

siendo estadoEdicion el estado de edición del TDBGrid ( creo que es stEdit) y siendo DBGrid el grid que estás utilizando.

Siento no poder darte más pistas, pero mi tiempo es algo limitado, y ya no tengo delphi instalado en mi equipo.

En el foro y en la ayuda de delphi puedes encontrar información al respecto.

Un saludo y suerte

Casimiro Notevi 12-01-2016 00:00:51

Cita:

Empezado por ginesgomezlopez (Mensaje 501174)
..

Recuerda poner los tags al código fuente, ejemplo:


ginesgomezlopez 12-01-2016 22:33:23

Perdona Casimiro, lo hice pero no sé por qué no salió.

Gracias Fjcg02, los sustituí por

Código Delphi [-]
dbgrid1.EditorMode=false

y funciona a la perfección, un millón de gracias

Por cierto, no te gusta Delphi? si no es indiscrección.

fjcg02 12-01-2016 22:39:02

Cita:

Empezado por ginesgomezlopez (Mensaje 501201)
Por cierto, no te gusta Delphi? si no es indiscrección.

No me parece una indiscrección...

No uso delphi porque en principio en el trabajo no lo utilizamos, y en casa pues ando haciendo otras cosillas. Compré un mac y para instalar Delphi tendría que instalar una máquina virtual. Con el poco tiempo que tengo, y dado que como ya te he dicho no lo utilizo en estos momentos, pues no quiero perder ni un minuto en hacer la instalación.

Si algún día tengo oportunidad de utilizarlo de nuevo, lo instalaré sin problemas. De hecho me gusta, es el entorno de programación que más controlo y que más me gusta.

Un saludo


La franja horaria es GMT +2. Ahora son las 05:02:43.

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