DBGrid satırlarını gruplayarak renklendirme

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen mmg »

Merhaba,

Delphi 10.2 DBGrid satırlarını sipariş fiş numarasına veya sipariş id numarasına göre gruplayarak renklendirmek istiyorum. Girilmiş tüm sipariş maddelerini DBGrid üzerinde sipariş numarasına göre sıralı olarak listeliyorum. 1 numaralı sipariş satırlarını kırmızı 2 numaralı siparişin satırlarını beyaza boyasın sonra 3 numaralı siparişin maddelerini yeniden kırmızıya boyasın istiyorum. Satır renklendirme ile ilgili birçok örnek inceledim fakat bir alana göre gruplayarak satırları renklendirme ile ilgili bir örnek bulamadım, bunu yapabilir miyim acaba ? Yardımlarınızı rica ediyorum.
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2357
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen freeman35 »

Aklıma gelen ilk basit yöntem, Bulduğun renklendirme kodlarına göre, iki değişken kullan, birinde renk bilgisi diğerinde ise ardışıklığı neyle sağlıyorsan (Numara yada id) yi sakla. her satır basıldığında, elindeki değişkenle satırdaki değişkeni karşılaştır, farklı ise renk ve bu değişkeni satırdakilerle değiştir, alt satırda da değişkendeki renk bilgisine göre satırı renklendir.
kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen ertank »

mmg yazdı: 14 Ara 2023 11:15 Merhaba,

Delphi 10.2 DBGrid satırlarını sipariş fiş numarasına veya sipariş id numarasına göre gruplayarak renklendirmek istiyorum. Girilmiş tüm sipariş maddelerini DBGrid üzerinde sipariş numarasına göre sıralı olarak listeliyorum. 1 numaralı sipariş satırlarını kırmızı 2 numaralı siparişin satırlarını beyaza boyasın sonra 3 numaralı siparişin maddelerini yeniden kırmızıya boyasın istiyorum. Satır renklendirme ile ilgili birçok örnek inceledim fakat bir alana göre gruplayarak satırları renklendirme ile ilgili bir örnek bulamadım, bunu yapabilir miyim acaba ? Yardımlarınızı rica ediyorum.
Merhaba, önce "gruplayarak renklendirmek istiyorum" demişsiniz. Sonra sıralı kırmızı beyaz kırmızı şeklinde istiyorum diye açıklamışsınız. Gruplama mı yoksa zebra şeklinde koyu/açık gibi renklendirme mi yapmak istiyorsunuz?
Kullanıcı avatarı
loaded
Üye
Mesajlar: 122
Kayıt: 12 Eki 2010 09:45
Konum: Konya
İletişim:

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen loaded »

Lazarus'ta TDBGrid'de satır renklendirmeyi şu şekilde yapıyorum;

Kod: Tümünü seç

procedure TForm_Main.DBGrid_ZeminPrepareCanvas(sender: TObject;
  DataCol: Integer; Column: TColumn; AState: TGridDrawState);
begin
   if (Sender as TDBGrid).Datasource.DataSet.FieldByName('id').AsString='1' then
   begin
   (Sender as TDBGrid).Canvas.Brush.Color:=clYellow;
   (Sender as TDBGrid).Canvas.Font.Color:=clBlack;
   end;
end;  
Orjinal kodda karşılaştırma daha farklı fakat anlaşılır olması için bu şekilde basitleştirdim. Sanırım sizde Delphi'de buna benzer şekilde yapabilirsiniz.
Kalk ve işe yarar bir şey yap! Çünkü Allah (c.c.) yeniden başlayanların yardımcısıdır.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen mmg »

ertank yazdı: 15 Ara 2023 09:57
mmg yazdı: 14 Ara 2023 11:15 Merhaba,

Delphi 10.2 DBGrid satırlarını sipariş fiş numarasına veya sipariş id numarasına göre gruplayarak renklendirmek istiyorum. Girilmiş tüm sipariş maddelerini DBGrid üzerinde sipariş numarasına göre sıralı olarak listeliyorum. 1 numaralı sipariş satırlarını kırmızı 2 numaralı siparişin satırlarını beyaza boyasın sonra 3 numaralı siparişin maddelerini yeniden kırmızıya boyasın istiyorum. Satır renklendirme ile ilgili birçok örnek inceledim fakat bir alana göre gruplayarak satırları renklendirme ile ilgili bir örnek bulamadım, bunu yapabilir miyim acaba ? Yardımlarınızı rica ediyorum.
Merhaba, önce "gruplayarak renklendirmek istiyorum" demişsiniz. Sonra sıralı kırmızı beyaz kırmızı şeklinde istiyorum diye açıklamışsınız. Gruplama mı yoksa zebra şeklinde koyu/açık gibi renklendirme mi yapmak istiyorsunuz?
Merhaba,

Gruplandırmaktan kastım aynı sipariş maddelerini aynı renge boyamayı ifade etmek içindi. Bildiğimiz group by değil. Sipariş maddeleri dbgridde fiş noya göre sıralı gelecek. 1 numaralı siparişin örneğin 5 adet maddesi olsun ve bu maddeler mavi olsun sonra 2 numaralı sipariş maddeleri 10 adet olsun bunların rengide kırmızı olsun. 3 Numaralı sipariş maddeleri yine maviye dönsün yani bir mavi bir kırmızı şeklinde sipariş numarasına göre renklendirsin istiyorum.
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen ertank »

mmg yazdı: 15 Ara 2023 05:53 Merhaba,

Gruplandırmaktan kastım aynı sipariş maddelerini aynı renge boyamayı ifade etmek içindi. Bildiğimiz group by değil. Sipariş maddeleri dbgridde fiş noya göre sıralı gelecek. 1 numaralı siparişin örneğin 5 adet maddesi olsun ve bu maddeler mavi olsun sonra 2 numaralı sipariş maddeleri 10 adet olsun bunların rengide kırmızı olsun. 3 Numaralı sipariş maddeleri yine maviye dönsün yani bir mavi bir kırmızı şeklinde sipariş numarasına göre renklendirsin istiyorum.
Bunu yapabilmek için sorgunuza grid içinde gözükmeyen ancak sorgu kolonları arasında olan bir kolon ekleyerek değerini fiş no değiştiği zaman 0/1 arası dönüşüm yaptırmalısınız. Sonra grid rengini bu 0/1 değerine göre örneklerde gösterildiği şekilde düzenleyebilirsiniz.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen mmg »

ertank yazdı: 15 Ara 2023 06:14
mmg yazdı: 15 Ara 2023 05:53 Merhaba,

Gruplandırmaktan kastım aynı sipariş maddelerini aynı renge boyamayı ifade etmek içindi. Bildiğimiz group by değil. Sipariş maddeleri dbgridde fiş noya göre sıralı gelecek. 1 numaralı siparişin örneğin 5 adet maddesi olsun ve bu maddeler mavi olsun sonra 2 numaralı sipariş maddeleri 10 adet olsun bunların rengide kırmızı olsun. 3 Numaralı sipariş maddeleri yine maviye dönsün yani bir mavi bir kırmızı şeklinde sipariş numarasına göre renklendirsin istiyorum.
Bunu yapabilmek için sorgunuza grid içinde gözükmeyen ancak sorgu kolonları arasında olan bir kolon ekleyerek değerini fiş no değiştiği zaman 0/1 arası dönüşüm yaptırmalısınız. Sonra grid rengini bu 0/1 değerine göre örneklerde gösterildiği şekilde düzenleyebilirsiniz.
Merhaba,

Bu tarz bir kontrol ile yapmayı bende düşündüm önce fakat girilmiş eski kayıtlar çok fazla bunlar içinde geçmişe dönük olarak bu kodu yazmak gerekecek. Maalesef bu DBGrid'in eksikliklerinden çektiklerimiz bitmiyor bir türlü. Ücretli componentler ile bu işleri çok kolay yapıyorlar. Yardımınız için teşekkür ediyorum.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen mmg »

Merhaba,

Ben şöyle bir yöntemle istediğimi yapabildim, ihtiyacı olan arkadaşlara yol göstermesi açısından bulduğum çözümü basit bir şekilde aşağıda paylaşıyorum. Sadece şöyle küçük bir problemi var, ben kayıtları sayfa sayfa gösteriyorum. İkinci sayfaya geçip sonra bir önceki sayfaya dönersem eğer Renk_Id resetleniyor. Son değeri 1 ise 0 oluyor veya tam tersi. Ama sonuçta renklendirmede hiçbir problem olmuyor sadece daha önce mavi boyadığı sipariş maddelerini gri yapıyor gri olanları da maviye boyuyor ama sipariş bazında maddeleri yine ayırıyor. Bunun üzerinde çok fazla durmadım açıkçası. Umarım işe yarar.

Öncelikle DGBrid'e bağlı tabloya bir tane RENK_NO (calculated) alanı ekledim. Diğer bölümleri aşağıda paylaşıyorum.

Kod: Tümünü seç

unit U_SIPARIS_BRW;

var
  SonId: Double= 0;
  RenkID: Integer= 0;


procedure TSIPARIS_BRW.btlisteleClick(Sender: TObject);
begin
  //.. Sipariş maddeleri tablosu açılıyor.
  SIPMADDE.Close;
  SIPMADDE.SQL.Clear;
  SIPMADDE.SQL.Add('SELECT * FROM SIPMADDE');
  SIPMADDE.Open;

  if SonID= 0 then
     SonId:= SIPMADDEBASLIK_ID.Value;
end;

procedure TSIPARIS_BRW.SIPMADDECalcFields(DataSet: TDataSet);
begin
  if SIPMADDEBASLIK_ID.Value = SonId then
  begin
    SIPMADDERENK_NO.Value:= RenkId;
    SonId:= SIPMADDEBASLIK_ID.Value;
  end
  else
  begin
    if RenkId= 0 then
       RenkId:= 1
    else
       RenkId:= 0;

    SonId:= SIPMADDEBASLIK_ID.Value;
    SIPMADDERENK_NO.Value:= RenkId;
  end;
end;

procedure TSIPARIS_BRW.DBGrid2DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  with DBGrid2.Canvas do
  begin
    if SIPMADDERENK_NO.Value= 0 then
       DBGrid2.Canvas.Brush.Color:= clBtnFace;
    else
       DBGrid2.Canvas.Brush.Color:= $00FFDA79;
    FillRect(rect);

    if (gdSelected in State) then
    begin
      brush.color := $00E6E6FF;
      Font.Name := 'Arial';
      Font.Color := Clred;
      FillRect(rect);
    end;
  end;
  DBGrid2.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen ertank »

Alternatif olarak;
Sorgu değerlerini MemoryTable içine alın. MemoryTable içinde ek bir kolon olsun. Sorgu yapıldığında içini doldurun. Baştan sona işleyip fiş no değiştiği zaman gözükmez kolonu 0/1 olarak değerini düzenleyin. Ekranda gösterirken de klasik dbgrid renklendirmesi ile ilgili kolonun 0/1 değerine göre rengini değiştirin.
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2357
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen freeman35 »

memtable yerine Calculated veya Computed field lada yapılabilir
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen mmg »

ertank yazdı: 19 Ara 2023 08:20 Alternatif olarak;
Sorgu değerlerini MemoryTable içine alın. MemoryTable içinde ek bir kolon olsun. Sorgu yapıldığında içini doldurun. Baştan sona işleyip fiş no değiştiği zaman gözükmez kolonu 0/1 olarak değerini düzenleyin. Ekranda gösterirken de klasik dbgrid renklendirmesi ile ilgili kolonun 0/1 değerine göre rengini değiştirin.
ertank değerli katkıların için çok teşekkür ediyorum. Öneriniz doğrultusunda kodu aşağıda görüldüğü şekliyle güncelledim Şu an sayfa geçişlerinde de bir sorun kalmadı. Yine de akışla ilgili ustalarımızın öneri ve yorumlarını duymak bize çok değerli katkılar sağlayacaktır.

Öncelikle DGBrid'e bağlı tabloya bir tane RENK_NO (calculated) alanı ekledim. Sayfa geçişlerinde renk karıştığı için sipariş maddelerinin renk kodunu saklayan bir tane MemoryTable ekledim. MermoryTable'da BASLKIK_ID ve RENK_ID alanlarını takip ediyorum. Diğer bölümleri aşağıda paylaşıyorum.

Kod: Tümünü seç

unit U_SIPARIS_BRW;

var
  SonId: Double= 0;
  RenkID: Integer= 0;

Kod: Tümünü seç

procedure TSIPARIS_BRW.btlisteleClick(Sender: TObject);
begin
  //.. Sipariş maddeleri tablosu açılıyor.
  SIPMADDE.Close;
  SIPMADDE.SQL.Clear;
  SIPMADDE.SQL.Add('SELECT * FROM SIPMADDE');
  SIPMADDE.Open;

  if SonID= 0 then
     SonId:= SIPMADDEBASLIK_ID.Value;
end;

Kod: Tümünü seç

procedure TSIPARIS_BRW.SIPMADDECalcFields(DataSet: TDataSet);
begin
    if MEMTABLE_RENK.Active= False then
      MEMTABLE_RENK.Active:= True;

  if SIPMADDEBASLIK_ID.Value = SonId then
  begin
    SIPMADDERENK_NO.Value:= RenkId;
    SonId:= SIPMADDEBASLIK_ID.Value;
  end
  else
  begin
    if MEMTABLE_RENK.Locate('BASLIK_ID', VarArrayOf([SIPMADDEBASLIK_ID.Value]), []) then
       RenkId:= MEMTABLE_RENKRENK_ID.Value
    else
    begin
      if RenkId= 0 then
         RenkId:= 1
      else
         RenkId:= 0;

      MEMTABLE_RENK.Append;
      MEMTABLE_RENK.FieldByName('BASLIK_ID').Value:= SIPMADDEBASLIK_ID.Value;
      MEMTABLE_RENK.FieldByName('RENK_ID').Value:= RenkId;
      MEMTABLE_RENK.Post;
    end;

    SonId:= SIPBASLIKBASLIK_ID.Value;
    SIPBASLIKRENK_NO.Value:= RenkId;
  end;
  
end;

Kod: Tümünü seç

procedure TSIPARIS_BRW.DBGrid2DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  with DBGrid2.Canvas do
  begin
    if SIPMADDERENK_NO.Value= 0 then
       DBGrid2.Canvas.Brush.Color:= clBtnFace;
    else
       DBGrid2.Canvas.Brush.Color:= $00FFDA79;
    FillRect(rect);

    if (gdSelected in State) then
    begin
      brush.color := $00E6E6FF;
      Font.Name := 'Arial';
      Font.Color := Clred;
      FillRect(rect);
    end;
  end;
  DBGrid2.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2357
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen freeman35 »

OnCalcFields event i, Her field ve her satır için tekrarlanır, yani çok fazla tekrar ve buradaki çok işlem performans kaybıdır.

Kod: Tümünü seç

if MEMTABLE_RENK.Active= False then MEMTABLE_RENK.Active:= True;
Son derece gereksiz bir satır. "MEMTABLE_RENK" bir değişken, bunu sürekli kontrol etmek yersiz. İllaki kontrol gerekirse, ilgili Class ın (MemTable, TTable vs) onun OnAfterOpen Event ine eklemek yeterlidir. Tabi kodda bunu başka yerlerde değiştiriliyorsa ona göre düzenleme yapılabilinir, ama OnCalc Yanlış yer

Kod: Tümünü seç

IPMADDERENK_NO.Value:= RenkId;

Değişken değilde FieldByName özellikle tavsiye edilir. Ayrıca TColor bir Integer değerdir. Onun için kodu sadeleştirebilirsin

Kod: Tümünü seç

IPMADDERENK_NO.Value:= Integer(clRed);
gibi Cast edebilirsin, faydası

Kod: Tümünü seç

    if SIPMADDERENK_NO.Value= 0 then
       DBGrid2.Canvas.Brush.Color:= clBtnFace;
    else
       DBGrid2.Canvas.Brush.Color:= $00FFDA79;
yerine

Kod: Tümünü seç

    if SIPMADDERENK_NO.Value= 0 then DBGrid2.Canvas.Brush.Color:= TColor(SIPMADDERENK_NO.Value);
yeterli olacaktır.

Kod: Tümünü seç

if MEMTABLE_RENK.Locate('BASLIK_ID', VarArrayOf([SIPMADDEBASLIK_ID.Value]), []) then
       RenkId:= MEMTABLE_RENKRENK_ID.Value
    else
Locate cursor u de konumlandırır, satır üzerinde değişiklik yapılmayacaksa "MEMTABLE_RENK.Lookup(" cursor konumlanmaz o yüzdende oldukça performanslıdır.
Neden MemTable kullandın? SIPMADDE e de Calculated field ekleyebilirdin.
kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen ertank »

freeman35 yazdı: 22 Ara 2023 10:31

Kod: Tümünü seç

IPMADDERENK_NO.Value:= RenkId;

Değişken değilde FieldByName özellikle tavsiye edilir. Ayrıca TColor bir Integer değerdir. Onun için kodu sadeleştirebilirsin
Aslında FieldByName kullanımı döngülerde tavsiye edilmez. Çünkü okuma/yazma yapmadan önce parametre geçilen alan adını arka planda yine döngü ile arayıp alan indeks değerini tespit eder.

Yukarıda alıntı yapılmış kullanımda query nesnesi içine SQL sorgu ile gelen alanlar tasarım zamanında "TField" türevi nesne olarak eklenmiş ve indeks değerleri belli. Dolayısıyla harici olarak alan indeks değeri tespitine ihtiyaç duymadan direk okuma/yazma yapar, performanslı çalışırlar.
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2357
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: DBGrid satırlarını gruplayarak renklendirme

Mesaj gönderen freeman35 »

ertank yazdı: 22 Ara 2023 03:26 Aslında FieldByName kullanımı döngülerde tavsiye edilmez. .....
Benim başıma geçmişte bu konuyla ilgili hata çıkmıştı ve epey bir vakit kaybettirmişti, hata, döngü içinde TField tipli değişkene (DesignTime da IDE tarafından tanımlanan) atama yapılmamasıydı. FieldByName ise beni yanıltmadı. Forumun amacı tecrübelerimiz paylaşmak. İsteyen istediğini yapmakta özgür
kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
Cevapla