DBGrid - rotinas para clicar no cabecalho e ordernar por uma coluna sql e indice

Top  Previous  Next

// rotinas para clicar no cabeçalho e ordernar 

 

///////////// USANDO SQL

 

// Coloque isto no evento GridTitleClick

procedure GridOrderColuna(Grid: TDBGrid; Column: TColumn);

var

  SQL, Col, ColIndexed: string;

  I                   : Integer;

begin

  if (Grid.DataSource = nil) or (Grid.DataSource.DataSet = nil) then Exit;

  SQL := TDQuery(Grid.DataSource.DataSet).Text;

  // não tem order by ainda?

  if Pos('ORDER BY', UpperCase(SQL)) = 0 then

    TDQuery(Grid.DataSource.DataSet).Select(SQL + ' order by ' + Column.Field.FieldName)

  else

  begin

    // pega o nome da coluna que está ordenada

    ColIndexed := Trim(Copy(SQL, Pos('ORDER BY', UpperCase(SQL)) + 9, Length(SQL)));

    ColIndexed := Separa(ColIndexed, ','1);

    // nome da coluna clicada

    Col := Column.Field.FieldName;

    // Esta já estava indexada!

    if Pos( UpperCase(Col), UpperCase( ColIndexed ) ) > 0 then

      if Pos('DESC', UpperCase(ColIndexed)) = 0 then  // não estava DESC?

        Col := Col + ' desc'        // adiciona o desc

      else

        Col := Separa(Col, #321); // remove o desc

    // deleta o antigo order by do código SQL

    Delete(SQL, Pos('ORDER BY', UpperCase(SQL)) + 9, Length(SQL));

    // reindexa novamente

    TDQuery(Grid.DataSource.DataSet).Select(SQL + Col);

 

    // identifica a coluna indexada

    for I:= 0 to Grid.Columns.Count-1 do Grid.Columns[I].Color := clWindow;

    if Pos('DESC', UpperCase(Col)) > 0 then

      Column.Color := $00F0FDFF

    else

      Column.Color := $00F0FAFF;

 

    Grid.Tag := 0

  end;

end;

 

/////////////////////// USANDO INDICES

// Coloque isto no evento GridTitleClick

// Nota: para usar esta é necessário que as colunas tenham 2 indices:

// iNomeCampo e dNomeCampo (ascendente e descendente).

// ATENCAO!! esta rotina nao funciona com ClientDataSet!

procedure GridIndexaColuna(Grid: TDBGrid; Column: TColumn);

var

  ColIndexed: string;

  I         : Integer;

begin

  if (Grid.DataSource = nil) or (Grid.DataSource.DataSet = nil) then Exit;

  // vê se é descendente ou ascendente

  if Copy(TTable(Grid.DataSource.DataSet).IndexName, 11) = 'd' then

    ColIndexed := 'i' + Column.Field.FieldName

  else

    ColIndexed := 'd' + Column.Field.FieldName;

 

  ColIndexed := LowerCase(ColIndexed);

  // reindexa novamente

  TTable(Grid.DataSource.DataSet).IndexName := ColIndexed;

 

  // identifica a coluna indexada

  for I:= 0 to Grid.Columns.Count-1 do Grid.Columns[I].Color := clWindow;

  if Copy(ColIndexed, 11) = 'd' then

    Column.Color := $00F0FDFF

  else

    Column.Color := $00F0FAFF;

 

  Grid.Tag := 0 // isto chama o redraw

end;

 

// coloque isto no evento GridDrawColumnCell

procedure GridDrawSeta(Grid: TDBGrid; Column: TColumn; Rect: TRect);

 

  procedure DesenhaDesc(const X, Y: Integer);

  begin

    // desenha linha cinza

    Grid.Canvas.Pen.Color := clBtnShadow;

    Grid.Canvas.MoveTo(X + 7, Y);      Grid.Canvas.LineTo(X, Y);

    Grid.Canvas.LineTo(X + 4, Y + 7);  Grid.Canvas.MoveTo(X, Y + 1);

    Grid.Canvas.LineTo(X + 3, Y + 6);

    // desenha linha branca

    Grid.Canvas.Pen.Color := clBtnHighlight;

    Grid.Canvas.MoveTo(X + 7, Y + 1);  Grid.Canvas.LineTo(X + 4, Y + 7);

    Grid.Canvas.MoveTo(X + 6, Y + 1);  Grid.Canvas.LineTo(X + 4, Y + 6);

  end;

 

  procedure DesenhaAsc(const X, Y: Integer);

  begin

    // desenha linha cinza

    Grid.Canvas.Pen.Color := clBtnShadow;

    Grid.Canvas.MoveTo(X + 3, Y);      Grid.Canvas.LineTo(X, Y + 6);

    Grid.Canvas.MoveTo(X + 3, Y + 1);  Grid.Canvas.LineTo(X, Y + 6);

    // desenha linha branca

    Grid.Canvas.Pen.Color := clBtnHighlight;

    Grid.Canvas.MoveTo(X + 4, Y);      Grid.Canvas.LineTo(X + 7, Y + 6);

    Grid.Canvas.MoveTo(X + 5, Y + 1);  Grid.Canvas.LineTo(X + 7, Y + 6);

    Grid.Canvas.MoveTo(X, Y + 6);      Grid.Canvas.LineTo(X + 8, Y + 6);

  end;

 

begin

  // se a tag for ZERO é uma "mensagem" para redesenhar...

  if (Grid.Tag <> 0or ( Column.Color = clWindow ) then Exit// não é esta coluna que está indexada?

 

  if (Column.Color = $00F0FAFF) then  // asc ou desc?

    DesenhaAsc( Rect.Left + Column.Width - 155 )

  else

    DesenhaDesc( Rect.Left + Column.Width - 155 );

  Grid.Tag := 1;  // isto faz com que ele desenhe somente uma vez (pode ser tirado)

end;