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, #32, 1); // 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, 1, 1) = '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, 1, 1) = '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 <> 0) or ( 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 - 15, 5 ) else DesenhaDesc( Rect.Left + Column.Width - 15, 5 ); Grid.Tag := 1; // isto faz com que ele desenhe somente uma vez (pode ser tirado) end; |