Mostrando entradas con la etiqueta TColumn. Mostrar todas las entradas
Mostrando entradas con la etiqueta TColumn. Mostrar todas las entradas

lunes, 13 de agosto de 2018

TDBGrid: ordenar por columnas ASC y DESC con flechas.



Anteriormente escribí acerca de ordenar las columnas de un DBGrid de forma simple y en un solo sentido. Ahora veremos como hacerlo de forma tal que además de poner en negrita el título de la columna que posee el orden, le agregue una flecha ascendente (arriba) o una descendente (abajo) y que si el usuario hace click en el título de una columna y la misma es la que está ordenando la grilla, entonces cambie el orden de la misma, es decir, si está ordenada ascendentemente pasará a ordenarse en sentido descendente.

Para las flechas necesitamos un TImageList.


Este componente se encuentra en la paleta Common Controls (el último que se ve en la imagen).


Desde el inspector de objetos estableceremos las propiedades Height (alto) y Width (ancho) de ImageList1 en 16 pixeles. Luego cargamos las imágenes de las flechas en dicho componente.

Éstas son las flechas utilizadas:


Ahora debemos conectar la lista de imágenes con la grilla.


Seleccionamos el DBGrid en el inspector de objetos y en TitleImageList asignamos ImageList1. Luego en "Eventos" creamos el procedimiento para OnTitleClick:

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
  i:Integer;
  AscDes:String;
begin
  if Column.Title.ImageIndex=0 then AscDes:=' DESC ' else AscDes:=' ASC ';
  for i:=0 to DBGrid1.Columns.Count-1 do
  begin
    DBGrid1.Columns.Items[i].Title.Font.Style:=[];
    DBGrid1.Columns.Items[i].Title.ImageIndex:=-1;
  end;
  ZQuery1.Close;
  sqlOrder:=' ORDER BY '+Column.FieldName+AscDes+';';
  sqlgrid:=sqlSelect+sqlWhere+sqlOrder;
  ZQuery1.SQL.Text:=sqlgrid;
  ZQuery1.Open;
  Column.Title.Font.Style:=[fsBold];
  if AscDes=' DESC ' then Column.Title.ImageIndex:=1 else Column.Title.ImageIndex:=0;
end;


Las variables sqlOrder, sqlGrid, sqlSelect y sqlWhere las defino como privadas para la clase del formulario, son del tipo string y su utilización es más que obvia, permitiendo por ejemplo, ordenar manteniendo un filtro definido por el usuario (sqlWhere).
Atención a no confundir Column con Columns, la primera viene como parámetro, es la columna en la cual el usuario hizo click. En cambio Column"s" es miembro de TDBgrid.
Lo primero que hacemos es averiguar si la columna (variable Column del tipo TColumn) está ordenada de manera descendente, caso contrario la damos como ascendente y establecemos el valor correspondiente a la variable local AscDes que luego utilizaremos en la consulta SQL.
Lo siguiente es recorrer las columnas (Columns) del grid y quitarles el [bold] y la flecha.
Cerramos el Query, armamos el string de la consulta y reabrimos la misma.
Finalmente marcamos en negrita el título de la columna y se asignamos la imagen de la flecha que le corresponde.










domingo, 17 de junio de 2018

TDBGrid: ordenar por columnas.

Ordenar los datos de una consulta SQL mostrados en un DBGrid al hacer click en la columna. En este caso además de ordenar, pondremos en bold (negrita) el título de la columna que está ordenada. (Para algo más avanzado aquí)

En el inspector de objetos, en DBGrid, eventos, buscar: OnTitleClick


y generar el evento (procedimiento):

procedure TFdCtas.DBGridCtasTitleClick(Column: TColumn);
var
  i:Integer;
begin
  for i:=0 to DBGridCtas.Columns.Count-1 do DBGridCtas.Columns.Items[i].Title.Font.Style:=[];
  ZQCtas.Close;
  ZQCtas.SQL.Text:='SELECT * FROM dcuentas ORDER BY '+Column.FieldName+';';
  ZQCtas.Open;
  Column.Title.Font.Style:=[fsBold];
end;


En el ciclo for quitamos "Bold" de todas las columnas y al final del código lo establecemos para la actual (que viene como parámetro).

Quedando así:



sábado, 27 de enero de 2018

DBGrid: Anchors de las columnas

Si bien TDBGrid tiene la propiedad Anchors (Anclajes), cuando la definimos y agrandamos y achicamos el formulario, la grilla también lo hace, mas no sus columnas, la cuales carecen de la propiedad Anchors, entonces el ancho de las columnas permanece estático, no cambia.

¿Cómo hacer que las columnas cambien el ancho cuando se agranda el formulario que contiene la DBGrid?

Creando el evento FormResize y asignarlo a los eventos del Form OnResize y OnChangeBounds. Desde ya el grid debe estar anclado al formulario y tener definido al menos las constraints de valores mínimos. Luego, un poco de matemáticas y eso es todo.


Así tengo definido el anclaje del DBGrid, mucho no entiendo de este tema, mucho prueba y error hasta dar con el resultado que busco.


Las Constraints del DBGrid, aunque esto es relativo si están definidas las del Form.


En los eventos del DBGrid, desde el inspector de objetos, creamos el evento para OnResize y también lo asignamos a OnChangeBounds.

procedure TfrmBancos.FormResize(Sender: TObject);
var
  ndiv, nmod, ndist:Integer;
begin
  ndist:=(Width-Constraints.MinWidth);
  if ndist < 4 then exit;
  ndiv:=ndist div 4;
  nmod:=ndist mod 4;
  DBGrid1.Columns.Items[1].Width:=160+ndiv;
  DBGrid1.Columns.Items[2].Width:=120+ndiv;
  DBGrid1.Columns.Items[3].Width:=150+ndiv;
  DBGrid1.Columns.Items[4].Width:=160+ndiv;
  if nmod>0 then
    DBGrid1.Columns.Items[4].Width:=DBGrid1.Columns.Items[4].Width+nmod;
end;


En este caso, la columna 0 (cero) no la muestro, solo las 1,2,3 y 4 con un ancho definido en la propiedad width de cada columna de 160, 120, 150 y 160 respectivamente.
Lo que hago es calcular en cuántos píxeles se agranda el formulario y en base a ello, lo distribuyo en las columnas, como son 4, hago la división entera sobre 4 y el resto (mod) lógicamente también sobre 4. Luego elijo a que columna se asigno el sobrante si es que lo hay (mod 4).

miércoles, 6 de septiembre de 2017

DBGrid: seleccionar una columna

El componente DBGrid carece de una opción para marcar una columna de la forma en que lo hacemos con una fila con dgRowSelect, es decir, no tenemos la opción dgColSelect. Lo cual no significa que no podamos hacerlo, de hecho el código es bastante simple:

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
  DBGrid1.Columns[Column.Index].Color := clHighlight;
  DBGrid1.Columns[column.Index].Title.Color := clHighlight;
end;


Basta con dos líneas de código para el evento TitleClick que nos envía parámetro Column del tipo TColumn, esto nos facilita todo, pues usamos la propiedad Index para saber sobre que columna (el itulo  de la columna) se hizo el click y le cambiamos el color tanto al título como a las celdas, según se desee.