Zmiana koloru tła określonego rekordu w DBGrid

0

Witam,
mam problem z zmianą koloru tła wybranych rekordów w DBGridzie.
Mam w DbGrid2 Tabelę wyświetlającą id_sprzeru oraz nazwę_sprzętu.
Połączona ona jest z główną tabelą, która jest wyświetlana w DBGrid1
W FormCreate przeszukuje tabele podrzędną(tą z DBGrid2) w celu sprawdzenia które sprzęty nie posiadają żadnego rekordu w Tabeli głównej.
W DBGrid2 chce zaznaczyć na zielono rekordy bez żadnej wartości.

procedure Tslownik_podczas_pracy.FormCreate(Sender: TObject);
var wartosc:integer;
  OutRect: TRect;
  I: Integer;
begin
// Przechodzi po wszystkich rekordach w DBGrid2 sprawdzając, który nie ma żadnej wartości.
DBGrid2.DataSource.DataSet.first;
while not(DBGrid2.DataSource.DataSet.Eof) do
  begin
    DBGrid2.SelectedRows.CurrentRowSelected := True;
    wartosc:=DBGrid2.Columns[0].Field.Value; // numer rekordu 

IBQuery1.Close;
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add('Select  B."Numer", B."KARTA" FROM  "Czyny" B, "Obiekt" F WHERE  B."ID_Ob"= F."ID_Ob" AND  B."ID_OBI"= ' + inttostr(wartosc));
IBQuery1.Open;

if( (DBGrid1.DataSource.DataSet.Fields[0].IsNull) AND (DBGrid1.DataSource.DataSet.Fields[1].IsNull)  ) THEN
    begin
        DBgrid2.DefaultDrawColumnCell(OutRect, wartosc, DBGrid2.Columns[0], []) ; //Tutaj nieskutecznie próbuje wywołać procedurę
        // która pomaluję tła rekordów bez wartości
    end;

 DBGrid2.SelectedRows.CurrentRowSelected := False;
 DBGrid2.DataSource.DataSet.next;
end;
DBGrid2.DataSource.DataSet.first;
end;

      // TUTAJ PROCEDURA  
procedure Tslownik_podczas_pracy.DBGrid2DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
 var
    begin

       DBGrid2.Canvas.Brush.Color := clgreen;

      grid.DefaultDrawColumnCell(Rect, DataCol, Column, State) ;
end;

Niestety maluję mi wszystkie rekordy i wiem że to coś z tą procedurą, ale próbowałem na różne sposoby i nic.
Proszę o pomoc.

0

no przecież malujesz na zielono KAŻDĄ komórkę.

  1. dodaj do SQLa pole, które będzie zwracało ilość "podrzędnych" rekordów
  2. w zdarzeniu rysowania sprawdzaj jaką wartość ma to pole i w zależności od tego koloruj lub nie
    bo tak jak teraz to nie zadziała z tego prostego powodu, że zdarzenie jest wołane przy każdym odświeżeniu grida a nie tylko na początku
0

@abrakadaber

  1. Mogę dać w tym createForm zliczanie rekordów i Niech będzie że mam 22.
  2. Tak to sprawdzić if( (DBGrid1.DataSource.DataSet.Fields[0].IsNull) AND (DBGrid1.DataSource.DataSet.Fields[1].IsNull) ) ?

Bo nie rozumiem zbyt twojego toku myślenia.

0

Nawet jak próbuję pokolorować określony rekord to maluje mi wszystkie na zielono a tam gdzie jest F-16 nic.

procedure Tslownik_podczas_pracy.DBGrid2DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
 const
  RowColors: array[Boolean] of TColor = (clSilver, clDkGray);
  var
  OddRow: Boolean;
 wartosc:string;
  a:integer;
begin
 

wartosc:=DBGrid2.Columns[1].Field.Value;

   
if (column.Field.FieldName='NAZWA_OB')AND (wartosc='F-16') then
        DBGrid2.Canvas.Brush.Color := clred
  else
  DBGrid2.Canvas.Brush.Color := clgreen;
    TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
 

Wie ktoś dlaczego?

I co ważniejsze jak dodam

   a:=DBGrid2.Columns[0].Field.Value;  
if (column.Field.FieldName='NAZWA_OB')AND (a=2) then  

To działa, tylko dla stringa mi nie wyszukuje, a zależałoby mi na tym.
Proszę o pomoc.

1

sformatuj prawidłowo kod , łatwiej będzie go ogarnąć

procedure Tslownik_podczas_pracy.DBGrid2DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
const
  RowColors: array [Boolean] of TColor = (clSilver, clDkGray);
var
  OddRow: Boolean;

begin
  nazwa := 'D';

  if (Column.Field.FieldName = 'NAZWA_OB') AND (nazwa = 'D') then
    DBGrid2.Canvas.Brush.Color := clred
  else if (Column.Field.FieldName = 'NAZWA_OB') AND NOT(nazwa = 'D') then
    DBGrid2.Canvas.Brush.Color := clgreen;
  TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

po co te nie uzywane deklaracje ??

const
  RowColors: array [Boolean] of TColor = (clSilver, clDkGray);
var
  OddRow: Boolean;

to fragment mojego działającego kodu


      if Column.Field.AsFloat < 1.29 then
        self.DBGrid1.Canvas.Brush.color := clred
      else if Column.Field.AsFloat < 1.44 then
        self.DBGrid1.Canvas.Brush.color := clyellow
      else
        self.DBGrid1.Canvas.Brush.color := cllime;

      self.DBGrid1.Canvas.FillRect(Rect);
      DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
  

column.Field.FieldName='NAZWA_OB' ??/
co to jest "NAZWA_OB" ??? nie widzę w zapytaniu takiego pola

0

@grzegorz_so
Dziękuję za odpowiedź, zmieniłem kod (u góry), bo jak usiadłem ponownie to zrozumiałem ocb xD
Ale nie chodzi mi dla stringów.
Znasz może przyczynę ?

0
grzegorz_so napisał(a)

po co te nie uzywane deklaracje ??

Tego typu tablica pozwoli uniknąć warunku i zmniejszy ilość potrzebnego kodu do ustalenia koloru tła komórki; Czyli podane przez Ciebie rozwiązanie:

if (Column.Field.FieldName = 'NAZWA_OB') AND (nazwa = 'D') then
  DBGrid2.Canvas.Brush.Color := clred
else if (Column.Field.FieldName = 'NAZWA_OB') AND NOT(nazwa = 'D') then
  DBGrid2.Canvas.Brush.Color := clgreen;

TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);

można skrócić do poniższej postaci:

const
  CELL_BRUSH_COLOR: array [Boolean] of TColor = (clGreen, clRed);

{...}

if Column.Field.FieldName = 'NAZWA_OB' then
  DBGrid2.Canvas.Brush.Color := CELL_BRUSH_COLOR[Nazwa = 'D'];

TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);

co będzie szybsze w działaniu i krótsze; Poza tym powyższy skrócony zapis zawiera tylko jeden warunek z tylko jedną składową, a Twój @grzegorz_so zawierał dwa, przy czym dublowałeś sprawdzanie wartości Column.Field.FieldName;

Inna sprawa:

grzegorz_so napisał(a)

to fragment mojego działającego kodu


      if Column.Field.AsFloat < 1.29 then
        self.DBGrid1.Canvas.Brush.color := clred
      else if Column.Field.AsFloat < 1.44 then
        self.DBGrid1.Canvas.Brush.color := clyellow
      else
        self.DBGrid1.Canvas.Brush.color := cllime;

      self.DBGrid1.Canvas.FillRect(Rect);
      DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);

Jeśli AsFloat nie zwraca typu Currency, to porównania wartości zmiennoprzecinkowych powinny być oparte o funkcję CompareValue, aby uniknąć przekłamań.

1 użytkowników online, w tym zalogowanych: 0, gości: 1