Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   [Truco] TDBGrid(Columna, Fila) (https://www.clubdelphi.com/foros/showthread.php?t=71052)

ecfisa 26-11-2010 20:49:07

[Truco] TDBGrid(Columna, Fila)
 
Hola.

He visto que varios han preguntado por la posibilidad de posicionarse en determinadas columnas y filas de un TDBGrid e hice un código
con algunos trucos 'sucios' para lograrlo.

No lo ví en la sección trucos así que decidí ponerlo aquí por si le sirve a alguien:
Código Delphi [-]
type
  TDBGridExt = Class(TDBGrid);
  TForm1 = class(TForm)
    ...
    DBGrid1: TDBGrid;
    ...
  private
    function DBgridColFil(ACol,AFil: integer; GE: TDBGridExt): string;
  public
  end;
...
implementation
...
function TForm1.DBgridColFil(ACol, AFil: integer; GE: TDBGridExt): string;
begin
  Result:= '';
  GE.DataSource.DataSet.MoveBy(1 - GE.Row); //  DataSet en fila 1 del DBGrid
  // Verifocar validez de ACol y AFil
  if (AFil > 0)and(ACol > 0)and(AFil < GE.RowCount)and(ACol < GE.ColCount) then
  begin
    GE.DataSource.DataSet.MoveBy(Afil-1); // Posicionarse en  AFil
    GE.Refresh;
    GE.FocusCell(ACol,AFil,True);         // Foco en la celda
    GE.SetFocus;
    Result:= GE.SelectedField.AsString;
  end
  else
    raise Exception.Create('Selección fuera de rango');
end;

Ejeplo de uso:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption:= DBGridColFil(2, 3, TDBGridExt(DBGrid1));
end;

Si Algún moderador cree que vale la pena, subo el código con un ejemplo funcional donde me indiquen.

Un saludo. :)

Casimiro Noteví 26-11-2010 21:18:57

Cita:

Empezado por ecfisa (Mensaje 383413)
Si Algún moderador cree que vale la pena, subo el código con un ejemplo funcional donde me indiquen.
Un saludo. :)

Vale la pena, pero creo que la sección de "trucos" está en sólo lectura mientras resolvemos unos problemillas en ella.

rgstuamigo 26-11-2010 22:55:25

Muy buen truco amigo ecfisa.;)
Yo tambien quiero agregar mi propia version del truco:
Para Posicionarme en una determinada fila y columna se puede hacerlo así:
Código Delphi [-]
TStringGrid(DBGrid1).Col:=2;
TStringGrid(DBGrid1).Row:=5;
DBGrid1.SetFocus;
Pero mejor hacer un método que me haga todo, idéntico al tuyo:
Código Delphi [-]
function TForm1.DBgridColFil(ACol, AFil: integer; Rejilla: TDBGrid): string;
begin
Result:='';
 if (ACol < 1)  or (ACol > TStringGrid(Rejilla).ColCount) or (AFil<1) or (AFil > TStringGrid(Rejilla).RowCount) then
    raise Exception.Create('Selección fuera de rango');
TStringGrid(Rejilla).Row:=AFil;
TStringGrid(Rejilla).Col:=ACol;
Rejilla.SetFocus;
Result:=Rejilla.SelectedField.AsString;//<---Linea agregada que me olvidé 
end;
Elemplo de uso:
Código Delphi [-]
 DBgridColFil(2,5,DBGrid1);
En otras palabras se puede hacer un casting a nuestro DBGrid convirtiendolo en un StringGrid normal y trabajarlo como tal.;)
Saludos...;)

Casimiro Noteví 26-11-2010 23:06:09

Cita:

Empezado por rgstuamigo (Mensaje 383423)
[..] En otras palabras se puede hacer un casting a nuestro DBGrid convirtiendolo en un StringGrid normal y trabajarlo como tal.

¿No puede ser "peligroso" hacer eso?, uno es de BD y el otro no, no sé, no me inspira mucha confianza, pero si lo has probado y va bien, pues estupendo.

rgstuamigo 26-11-2010 23:11:09

Cita:

Empezado por Casimiro Notevi (Mensaje 383424)
¿No puede ser "peligroso" hacer eso?

Bueno...:rolleyes:, hay que tener el cuidado respectivo y probar hasta dónde puedes llegar, en éste caso tanto el StringGrid como el DBGrid tienen como ancestro(Padre) comun mas cercano a la clase TCustomGrid y por eso es permitido hacer dicho casting y accesar a tales propiedades.;)
Saludos...:)

ecfisa 26-11-2010 23:28:17

Hola rgstuamigo.

Está muy bien pensado, posiciona perfectamente.

Yo lo busque por el lado del TCustomDBGrid por que me permite posicionar y tambien obtener el campo de dicha posición.
Por ejemplo:
Código Delphi [-]
function TForm1.DBGridColFil(ACol, AFil: integer; GE: TDBGridExt): TField;
begin
  Result:= nil;
  GE.DataSource.DataSet.MoveBy(1 - GE.Row);
  if (AFil > 0)and(ACol > 0)and(AFil < GE.RowCount)and(ACol < GE.ColCount) then
  begin
    GE.DataSource.DataSet.MoveBy(Afil-1);
    GE.Refresh;
    GE.FocusCell(ACol,AFil,True);
    GE.SetFocus;
    Result:= GE.SelectedField;
  end
  else
    raise Exception.Create('Selección fuera de rango');
end;

...
begin
   Caption:= DBGridColFil(4, 3,TDBGridExt(DBGrid1)).AsString;
  ...

No sé si se puede obtener el campo trabajándolo como TStringGrid... :rolleyes:, pero será cosa de buscarle la vuelta...

Saludos. :)

Casimiro Noteví 26-11-2010 23:28:30

Sí, bueno, por supuesto que se puede hacer, pero siempre me ha producido cierto "reparo" hacer estas cosas, aunque también las hago cuando hace falta, claro.


Edito: era respondiendo a rgstuamigo :)

rgstuamigo 26-11-2010 23:32:29

Cita:

Empezado por ecfisa (Mensaje 383427)
...No sé si se puede obtener el campo trabajándolo como TStringGrid... :rolleyes:, pero será cosa de buscarle la vuelta...
...

A Caray se me olvidó esa linea de agregarle a la funcion que hize:o:D, pero ya lo he agregado.
Saludos...:)

ecfisa 26-11-2010 23:43:57

Cita:

Empezado por rgstuamigo (Mensaje 383429)
A Caray se me olvidó esa linea de agregarle a la funcion que hize:o:D, pero ya lo he agregado.
Saludos...:)

Acabo de probarlo y funciona correctamente.
Mejor entonces, ahora tienen dos trucos para elegir.
Y como en esto siempre hay más de una forma correcta de hacer algo, en cualquier momento se suma un tercero o cuarto... :D:D


Un saludo. :)

ecfisa 27-11-2010 00:08:28

Hola rgstuamigo.

Cuando quise cambiar el resultado de la función a TField para que me devuelva el campo no lo realiza. Es decir devuelve el valor del campo correctamente como string, pero no el campo en sí:

Código Delphi [-]
function TForm1.DBgridColFil(ACol, AFil: integer; Rejilla: TDBGrid): TField;
begin
  Result:= nil;
  if (ACol < 1)or(ACol > TStringGrid(Rejilla).ColCount)or(AFil<1)or(AFil > TStringGrid(Rejilla).RowCount) then
    raise Exception.Create('Selección fuera de rango');
  TStringGrid(Rejilla).Row:=AFil;
  TStringGrid(Rejilla).Col:=ACol;
  Rejilla.SetFocus;
  Result:= Rejilla.SelectedField;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption:= DBGridColFil(SpinEdit1.Value,SpinEdit2.Value, DBGrid1).AsString;
end;

Me toma los cambios de columna pero no el de las filas, probalo a ver si estoy haciendo algo equivocado...

Un saludo. :)

rgstuamigo 27-11-2010 00:13:53

Cita:

Empezado por ecfisa (Mensaje 383433)
Hola rgstuamigo.

Cuando quise cambiar el resultado de la función a TField para que me devuelva el campo no lo realiza. Es decir devuelve el valor del campo correctamente, pero no el campo:
...
...
Me toma los cambios de columna pero no el de las filas...

Tenés toda la razón, y eso ocurre por que al Dataset no lo hemos movido para nada, en todo caso habrá que moverlo con el método MoveBy para que tambien el dataset se posicione en el campo expecífico.:cool:
Saludos...:)

ecfisa 01-12-2010 20:11:09

Cita:

Empezado por rgstuamigo (Mensaje 383434)
Tenés toda la razón, y eso ocurre por que al Dataset no lo hemos movido para nada, en todo caso habrá que moverlo con el método MoveBy para que tambien el dataset se posicione en el campo expecífico.:cool:
Saludos...:)

Exacto, así como está, sólo posiciona bien en pantalla, pero al no desplazar el DataSet, la línea:
Código Delphi [-]
  Result:= Rejilla.SelectedField.AsString;
puede devolver cualquier valor dependiendo del registro donde este posicionado en ese momento.

Un saludo. :)


La franja horaria es GMT +2. Ahora son las 10:12:05.

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