Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   problema para detectar el numero de fila en un stringgrid con checkbox (https://www.clubdelphi.com/foros/showthread.php?t=73781)

kapcomx 16-05-2011 21:21:14

problema para detectar el numero de fila en un stringgrid con checkbox
 
ke tal amigos del foro, tengo la siguiente situacion, etoy programando en delphi 7. uso mysql 5 conectado con zeos.

el punto es que queria colocar un checkbox en una stringgrid, que muestra las tareas pendientes, cosa que ya logre hacer.. al seleccionar un dia en un calendario me muestra en la stringgrid las tareas del dia, en la tercer columna me muestra un checkbox, el cual me indica si la tarea esta o no realizada.

el punto es que al darle un clic al checkbox de una determinada fila, no me puede determinar en que fila estoy haciendo el clic y no puedo hacer la modificacion del status de la tarea en la tabla. tengo por fuerza que hacer un clic en la tarea y despues en el checkbox, solo asi puedo obtener el numero de la fila. Con este numero puedo hacer todo lo demas.

Mi pregunta es ¿Cómo puedo hacer para que al hacer un click en el checkbox me determine en que fila de la stringgrid estoy actualmente?


tal vez exista alguna propiedad o evento en el checkbox o en la stringgrid que este omitiendo.

si alguno de ustedes ha podido integrar un checkbox en un stringgrid y sabe de esta situacion le agradeceria que me dijera como puedo hacer para resolver este problema.

les mando un saludo a todos.

ecfisa 17-05-2011 00:21:15

Cita:

Mi pregunta es ¿Cómo puedo hacer para que al hacer un click en el checkbox me determine en que fila de la stringgrid estoy actualmente?
Hola kapcomx.

Creo que la opción más simple es aprovechar el evento OnClick del TCheckBox:
Código Delphi [-]
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  ShowMessage(Format('%d %d',[StringGrid1.Col, StringGrid1.Row])); // Col: Columna, Row: Fila
end;

Un saludo.

kapcomx 17-05-2011 01:04:47

muchas gracias por responder amigo ecfisa, elpunto es que precisamente es lo que estoy haciendo, pero al hacer click en el checkbox simplemente no me reconoce el numero de fila. tengo que activar otra celda y luego el checkbox.

¿que podra ser?

y la cosa se me complica por que ahora quieren que ponga en otra columna una imagen de una X y al darle clic me borre ese registro (tarea).

ecfisa 17-05-2011 03:17:51

Hola kapcomx.

No tenés nada que agradecer estamos para ayudarnos. ;)

Pero la verdad, así sin código, es muy difícil saber por que no obtenes la fila en ese evento...

Saludos.

newtron 17-05-2011 09:17:57

Hola.

Imagino que cuando picas en el checkbox, al no ser un elemento del grid, no sabe en qué fila está. Se me ocurre que cuando creas el checkbox podrías guardar en el tag del mismo el número de columna y así lo tendrías a mano cuando lo necesites.

Saludos

kapcomx 17-05-2011 18:40:19

Hola Newtron, muchas gracias por tu ayuda, seguramente lo que pasa es eso, de hecho cuando creo el checkbox le asigno en el tag el numero de la fila, el problema es que estoy asociando el evento onclic del checkbox a otro ya creado. y ahi se me pierde el numero.

bueno les explico como lo hice.

1. tengo un panel (panel1).
2. una stringgrid (stringgrid2)
3. un calendario (xxxx) //no me acuero por que le puse ese nombre...
4. un label para indicar la fecha (label18).
5. tengo un checkbox donde hago la actualizacion (checkbox3).

al darle click a un dia del calendario hago lo siguiente:

Código Delphi [-]
 
procedure TForm3.XXXXClick(Sender: TObject);
var
 x,i:Integer;
 Present: TDateTime;
 Year, Month, Day, Hour, Min, Sec, MSec: Word;
 dia, mes: string;

begin

Present:= XXXX.date;
DecodeDate(Present, Year, Month, Day);
 
 CASE DayOfTheWeek(XXXX.date) OF
 1: DIA:='Lunes';
 2: DIA:='Martes';
 3: DIA:='Miercoles';
 4: DIA:='Jueves';
 5: DIA:='Viernes';
 6: DIA:='Sabado';
 7: DIA:='Domingo';
 END;
 
 case month of
  1: mes := 'Enero';
  2: mes := 'Febrero';
  3: mes := 'Marzo';
  4: mes := 'Abril';
  5: mes := 'Mayo';
  6: mes := 'Junio';
  7: mes := 'Julio';
  8: mes := 'Agosto';
  9: mes := 'Septiembre';
  10: mes := 'Octubre';
  11: mes := 'Noviembre';
  12: mes := 'Diciembre';
end;
 
 LABEL18.CAPTION:=DIA +' '+ IntToStr(Day) + ' de ' + mes  + ' de ' + IntToStr(Year);
 

panel1.Visible:=True;

StatusBar1.SimpleText:='Para modificar la hora o el concepto de la tarea 
haga doble clic sobre la tarea';

 stringgrid2.ColCount:=5;
     stringgrid2.RowCount:=50 ;
     Stringgrid2.ColWidths[0]:=80;
     Stringgrid2.ColWidths[1]:=450;
     Stringgrid2.ColWidths[2]:=50;
     Stringgrid2.ColWidths[3]:=0;
     Stringgrid2.ColWidths[4]:=0;
     for I := 1 to StringGrid2.RowCount - 1 do
     StringGrid2.Rows[i].Clear;
   //*****
    with Stringgrid2 do
     begin
       // Título de las columnas
        Cells[0, 0] := '' ;
        Cells[0,1] := '9:00 a.m.' ;
        Cells[0,2] := '9:30 a.m.' ;
        Cells[0,3] := '10:00 a.m.' ;
        Cells[0,4] := '10:30 a.m.' ;
        Cells[0,5] := '11:00 a.m.' ;
        Cells[0,6] := '11:30 a.m.' ; 
        Cells[0,7] := '12:00 p.m.' ;
        Cells[0,8] := '12:30 p.m.' ;
        Cells[0,9] := '1:00 p.m.' ;
        Cells[0,10] := '1:30 p.m.' ;
        Cells[0,11] := '2:00 p.m.' ;
        Cells[0,12] := '2:30 p.m.' ;
        Cells[0,13] := '3:00 p.m.' ;
        Cells[0,14] := '3:30 p.m.' ;
        Cells[0,15] := '4:00 p.m.' ;
        Cells[0,16] := '4:30 p.m.' ;
        Cells[0,17] := '5:00 p.m.' ;
        Cells[0,18] := '5:30 p.m.' ;
        Cells[0,19] := '6:00 p.m.' ;
        Cells[0,20] := '6:30 p.m.' ;
        Cells[0,21] := '7:00 p.m.' ;
        Cells[0,22] := '7:30 p.m.' ;
        Cells[0,23] := '8:00 p.m.' ;
        Cells[0,24] := '8:30 p.m.' ;
        Cells[0,25] := '9:00 p.m.' ;
        end;

with query1 do   //esta es para buscar las tareas de la fecha seleccionada
begin
close;
sql.clear;
sql.add('SELECT * from tareas');
SQL.add('where fecha =' + QUOTEDSTR(FormatDateTime('yyyy/mm/dd',xxxx.Date)));
execSQL;
open;
end;
 
   Query1.first;   //  con este ciclo mando a escribir las tareas encontradas...
while not (Query1.eof) do
begin
 with stringgrid2 do
 begin

  Present:= Query1.FieldValues['hora'];
  DecodeTime(Present, Hour, Min, Sec, MSec);
  Label2.Caption := 'The time is Minute ' + IntToStr(Min) + ' of Hour '
    + IntToStr(Hour);

      //*************
      case hour of
      9: x:=1;
      10: x:=3;
      11: x:=5;
      12: x:=7;
      1:  x:=9;
      2:  x:=11;
      3:  x:=13;
      4:  x:=15;
      5:  x:=17;
      6:  x:=19;
      7:  x:=21;
      8:  x:=23;
      end;
 

  if   Query1.fieldvalues['tarea']=null then
  Cells[1, x] := ''
  else
  Cells[1, x] :=(Query1.fieldvalues['tarea']);
   if   Query1.fieldvalues['folio']=null then
  Cells[3, x] := ''
  else
  Cells[3, x] :=inttostr(Query1.fieldvalues['folio']);
   if   ((Query1.fieldvalues['status']=null) or (Query1.fieldvalues['status']=0)) then
  Cells[4, x] := '0'
  else
  Cells[4, x] :='1';
 
   inc(x);
end;
  Query1.Next;
   end;

   agregachecks.Click  //este boton agrega los checks.

end;

hasta aqui todo va bien .....

en el agregachecks tengo lo sig.
Código Delphi [-]
 
 
procedure TForm3.agregachecksClick(Sender: TObject);
var
i: Integer;
NewCheckBox: TCheckBox;
Rect: TRect;
begin
 clean_previus_buffer.click; //  limpia los controles no utilizados
 for i := 1 to stringgrid2.RowCount do
begin
NewCheckBox := TCheckBox.Create(Application);
NewCheckBox.Width := 0;
NewCheckBox.Visible := false;
NewCheckBox.Caption := '';
 
// aqui determino si lo marca o no dependiendo el valor de la columna 4 (status)...
 
if (StringGrid2.Cells[4,i]='1') then
   NewCheckBox.Checked :=True
   else
    NewCheckBox.Checked :=false ;

NewCheckBox.Color := clwhite;

NewCheckBox.Tag := i;  //aqui guardo el numero de tag

NewCheckBox.OnClick := CheckBox3.OnClick; // aqui es donde asocio el evento onclick a un check ya existente

NewCheckBox.Parent := Panel1;
StringGrid2.Objects[2,i] := NewCheckBox;
StringGrid2.RowCount := i;
 end;
 
// esta parte es para alinearlos...

  for i := 1 to StringGrid2.RowCount do
  begin
  NewCheckBox := (StringGrid2.Objects[2,i] as TCheckBox);
  if NewCheckBox <> nil then
  begin
  Rect := StringGrid2.CellRect(2,i); // here, we get the cell rect for our contol...
  NewCheckBox.Left := StringGrid2.Left + Rect.Left+2;
  NewCheckBox.Top := StringGrid2.Top + Rect.Top+2;
  NewCheckBox.Width := Rect.Right - Rect.Left;
  NewCheckBox.Height := Rect.Bottom - Rect.Top;
  NewCheckBox.Visible := True;
  end;
 end;   //end de alineacion
 
end;

hasta aqui llevo todo bien me salen las tareas del dia, me salen marcadas o desmarcadas segun el valor que tengan en la tabla.

si marco primero la descripcion (columna 1 de la stringgrid) y luego le hago clic al checkbox me funciona muy bien ....

el punto es que si no hago un clic previo en la stringgrid y hago un clic en el checkbox directamente, pues no me hace nada por queno reconoce el numero de fila o peor aun me modifica el ultimo que halla seleccionado...

en el evento onclic del checkbox3 tengo lo siguiente

Código Delphi [-]
 
procedure TForm3.CheckBox3Click(Sender: TObject);
begin
 
IF StringGrid2.Cells[4,StringGrid2.Row]='' THEN
ShowMessage('Haga un clic sobre la tarea que quiere modificar');

if (StringGrid2.Cells[4,StringGrid2.Row]='0') then
begin
queryng2x.Close;
queryng2x.SQL.Text:='update tareas set status=1 where folio=' + StringGrid2.Cells[3,StringGrid2.Row];
queryng2x.ExecSQL;
end;
 
//en la columna 3 tengo el numero de folio(consecutivo) de las tareas
// en la columna 4 el status 0 1
 
if (StringGrid2.Cells[4,StringGrid2.Row]='1') then
begin
queryng2x.Close;
queryng2x.SQL.Text:='update tareas set status=0 where folio=' + StringGrid2.Cells[3,StringGrid2.Row];
queryng2x.ExecSQL;
end;

end;

ya entendi el concepto del tag, este es el numero de indice cuando se tiene un arreglo de controles, pero el punto es como lo obtengo. o como lo paso al checkbox3.

o si estoy mal con eso, tal vez no sea necesario tenerlo asociado a un checkbox ya creado, bueno compañeros esa es la situacion espero que teniendo el codigo me puedan orientar un poco mas.

newtron 18-05-2011 10:16:46

Hola de nuevo.

Yo creo que si en el CheckBox3Click preguntas por el tag del activecontrol te encuentras el número de linea.

Activecontrol.tag

Saludos

kapcomx 18-05-2011 19:07:48

Muchas gracias Newtron, ecfisa gracias a su ayuda me ha quedado muy bien, es correcto lo que mencionaste Newtron, con activecontrol.tag obtengo el numero sin problema alguno.

mi checkbox3 quedo asi

Código Delphi [-]
 
procedure TForm3.CheckBox3Click(Sender: TObject);
var
nfila: Integer;
begin
nfila:=ActiveControl.Tag;

IF StringGrid2.Cells[3,nfila]='' THEN
ShowMessage('La tarea que selecciono esta vacia, Haga un clic sobre la tarea que quiere modificar')
else
begin
if (StringGrid2.Cells[4,nfila]='0') then
begin
queryng2x.Close;
queryng2x.SQL.Text:='update tareas set status=1 where folio=' + StringGrid2.Cells[3,nfila];
queryng2x.ExecSQL;
end;
if (StringGrid2.Cells[4,nfila]='1') then
begin
queryng2x.Close;
queryng2x.SQL.Text:='update tareas set status=0 where folio=' + StringGrid2.Cells[3,nfila];
queryng2x.ExecSQL;
end;

end;
end;

ahora investigare un poco lo de la imagen de la X para borrar una tarea, y cuando lo tenga listo les pongo el codigo. Para ver si a alguien le sirve.

Saludos....

Caro 19-05-2011 04:23:52

Hola, otra forma de obtener la fila del stringGrid podría ser mediante las coordenadas:

Código Delphi [-]
var
 aCol, aRow : Integer;
 punto : TPoint;
begin
 GetCursorPos(punto);
 With StringGrid do
  begin
   MouseToCell(punto.X-ClientOrigin.X, punto.Y-ClientOrigin.Y, aCol, aRow);
   if (aCol>0) and (aRow>0) then
    begin
     Col := aCol;
     Row := aRow;
    end;
   showmessage(IntToStr(Row));
  end;
  ...........................................

Saluditos

kapcomx 20-05-2011 03:04:33

Caro, te agradezo mucho tu respuesta, no la he probado aun, pero seguro que lo hare, no dudo nada que funcione correctamente.

Espero algún dia poder ayudarlos asi como ustedes me han ayudado a mi.

Jetzuvely21 22-06-2012 23:54:25

Duda..
 
Hola a todos...escribo en este hilo, ya que estoy tratando de implementar algo parecido.

He estado buscando en los foros acerca de como leer un campo boleano de una Base de Datos y mostrar su contenido en forma de checkbox en un StringGrid.Ya sea que el campo contega 1,0 (marcado/desmarcado) respectivamente,ya avancé algo. Muestro los datos en mi string grid y me aparecen ya como true/false. Pero no sé como indicarle que dependiendo del valor del campo me aparezca el checkbox y lo marque o desmarque :(. Tambien ya avancé algo en cuanto a dibujar los Checks en el grid.

Tomé una parte del código mostrado aqui,pero en la parte :
Código Delphi [-]
if (StringGrid2.Cells[4,i]='1') then    
NewCheckBox.Checked :=True   
 else     
NewCheckBox.Checked :=false ;

Leyendo el campo, siempre me aparece marcado. :confused:

Agradecería alguna sugerencia de la lectura de este tipo de campos para mostrarlos en StringGrid en forma de Checkbox. (Estoy en Delphi5,Sql Server) -Gracias!

Casimiro Notevi 23-06-2012 00:08:18

Hola, aunque tu pregunta involucra a un grid y un checkbox, no tiene nada que ver con esta. Es mejor que crees un hilo nuevo para tratar tu tema exclusivamente,
este es un hilo ya solucionado de hace más de un año.
Gracias y saludos.


La franja horaria es GMT +2. Ahora son las 02:08:47.

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