Aynı tarihi bir kez gösterme

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
dogan
Üye
Mesajlar: 173
Kayıt: 17 Eki 2014 10:11

Aynı tarihi bir kez gösterme

Mesaj gönderen dogan »

İyi günler;

Kullanıcının seçtiği iki tarih arasındaki verileri listviewe listeliyorum;
Daha sonra bu listeyi excele aktarıyorum buraya kadar herhangi bir sıkıntı yok; Fakat aynı tarihi excele bir kez oluşmasını nasıl sağlayabilirim...

Durumu daha iyi anlatabilmek için iki görsel ekledim. :D

Kod: Tümünü seç

Row := 2; // İkici satırdan başla
    // KAYITLARI AKTARMAYA BAŞLA
    try
      with TFDQuery.Create(Nil), Form1.ListView1 do
      begin
        for J := Items.Count - 1 downto 0 do
        begin
          Connection := Form1.Connection; // Tarihlerin alındığı database
          Close;
          SQL.Clear;
          SQL.Add('Select * From AYSONUDOKUM');
          SQL.Add('Where TARIHLER=:TRL Order By ID DESC');
          ParamByName('TRL').AsDate := StrToDate(Items.Item[J].SubItems[11]);
          Prepare;
          Open;
          if FieldByName('TARIHLER').AsString = Items.Item[J].SubItems[11] then
          begin
            Sheet.Cells[Row, 3] := FormatDateTime('d/mm/yyyy dddd',
              StrToDate(FieldByName('TARIHLER').AsString));
          end;
          Row := Row + 1;
          Sheet.Cells[Row, 1] := Items.Item[J].SubItems[0];
          Sheet.Cells[Row, 2] := Items.Item[J].SubItems[1];
          Sheet.Cells[Row, 3] := Items.Item[J].SubItems[2];
          Sheet.Cells[Row, 4] := Items.Item[J].SubItems[3];
          Sheet.Cells[Row, 5] := Items.Item[J].SubItems[4];
          Sheet.Cells[Row, 6] := Items.Item[J].SubItems[5];
          Sheet.Cells[Row, 7] := Items.Item[J].SubItems[6];
          Inc(Row);
        end;
Olan:
Resim

Benim yapmak istediğim:
Resim
ertank
Kıdemli Üye
Mesajlar: 1653
Kayıt: 12 Eyl 2015 12:45

Re: Aynı tarihi bir kez gösterme

Mesaj gönderen ertank »

Merhaba,

Gönderilen kod ilgili bölümün tamamını içermiyor. Aşağıdaki cevaben sunulan kod bu bakımdan direk compile edilip çalışmayabilir.

Cevaben sunulan koda geçmeden önce bazı konulara dikkat etmekte fayda var.
1- with kullanımından mümkün mertebe kaçınmakta fayda var. Daha az klavye kullanımı daha çok karışıklığa sebep olabilir.
2- TFDQuery.Create(nil) ifadesi hafıza kaçağına sebep verebilir. Kodun tamamı görülmediği için ihtimal olarak yazıyorum. Ancak yüksek ihtimal diye hissediyorum.
3- Connection nesnelerinin en güzel kullanımı bir DataModule içinde olması ve mümkün olduğunca "uygulama ve database başına" bir tane connection nesnesi olmasıdır. Örnek kod "Form1.Connection" ifadesi kullanıyor. Bu kod bir DataModule kullanılmadığını ve her birden fazla form üzerinde farklı Connection nesneleri olabileceğini gösteriyor.
4- Sorulan soru ile ilgili çalıştırılacak SQL komutu hep aynı, sadece parametresi değiştirileceği için for döngüsü dışında bir defa oluşturulması yeterlidir.
5- FormatDateTime kullanır iken "d/mm/yyyy" gibi bir ifade 3 Ağustos 2016 için "3/08/2016" şeklinde bir değer gösterir. Eğer istenilen davranış bu ise sorun yok. Ancak genelde "03/08/2016" şeklinde bir ifade gösterilmesi alışkanlıktandır. Sonraki gösterim için formatın "dd/mm/yyyy" şeklinde olması gerekiyor.

Sorulan soruda istenilen işlemi gerçekleştirmenin birden fazla yolu var. Ben aklıma gelen ilk örneği veriyorum.

Kod: Tümünü seç

uses
  DateUtils;
  
var
  J: Integer;
  Query: TFDQuery;
  ExcelSonTarih: string;
begin
  Query := TFDQuery.Create(nil);
  try
    Query.Connection := Form1.Connection;
    Query.Close();
    Query.SQL.Clear();
    Query.SQL.Add('Select * From AYSONUDOKUM');
    Query.SQL.Add('Where TARIHLER=:TRL Order By ID DESC');
    Query.Prepare();
    
    ExcelSonTarih := EncodeDate(1900, 1, 1);   // Boş değer (EmptyStr) ihtimali var. Olmayacak bir tarih ataması yap. 
    for J := Form1.ListView1.Items.Count-1 downto 0 do
    begin
      Query.Close();
      Query.ParamByName('TRL').AsDate := StrToDate(Items.Item[J].SubItems[11]);
      Query.Open();
      if Query.RecordCount > 0 then
      begin
        if ExcelSonTarih <> Query.FieldByName('TARIHLER').AsString then
        begin
          ExcelSonTarih := Query.FieldByName('TARIHLER').AsString;
          Sheet.Cells[Row, 3] := FormatDateTime('d/mm/yyyy dddd', StrToDate(ExcelSonTarih));
        end;

        Inc(Row);
        Sheet.Cells[Row, 1] := Form1.ListView1.Items.Item[J].SubItems[0];
        Sheet.Cells[Row, 2] := Form1.ListView1.Items.Item[J].SubItems[1];
        Sheet.Cells[Row, 3] := Form1.ListView1.Items.Item[J].SubItems[2];
        Sheet.Cells[Row, 4] := Form1.ListView1.Items.Item[J].SubItems[3];
        Sheet.Cells[Row, 5] := Form1.ListView1.Items.Item[J].SubItems[4];
        Sheet.Cells[Row, 6] := Form1.ListView1.Items.Item[J].SubItems[5];
        Sheet.Cells[Row, 7] := Form1.ListView1.Items.Item[J].SubItems[6];
        Inc(Row);
      end;
    end;
  finally
    Query.Free();
  end;
end;
Kullanıcı avatarı
yhackup
Üye
Mesajlar: 115
Kayıt: 09 Ağu 2014 09:09
İletişim:

Re: Aynı tarihi bir kez gösterme

Mesaj gönderen yhackup »

Merhaba, Sql'de Rollup siye bir komut var tam da senin istediğin şeye yarıyor bir araştır ;)
Çaylak Delphici :D

Yakup ULUTAŞ
ertank
Kıdemli Üye
Mesajlar: 1653
Kayıt: 12 Eyl 2015 12:45

Re: Aynı tarihi bir kez gösterme

Mesaj gönderen ertank »

yhackup yazdı:Merhaba, Sql'de Rollup siye bir komut var tam da senin istediğin şeye yarıyor bir araştır ;)
Merhaba,

ROLLUP, MSSQL ORACLE database sistemlerinin CUBE işlemlerini kolaylaştırmak için geliştirdikleri bir özellik. Eğer @dogan farklı bir database sistemi kullanıyor ise ROLLUP kullanamayabilir.

Diğer taraftan ROLLUP'ın buradaki kullanımı çok pratik olmayabilir. ROLLUP'ın yaptığı grup toplamı bittiği zaman ara toplam almak gibi oluyor.
Kayak: https://technet.microsoft.com/en-us/lib ... l.90).aspx

Kod: Tümünü seç

SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
            ELSE ISNULL(Item, 'UNKNOWN')
       END AS Item,
       CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
            ELSE ISNULL(Color, 'UNKNOWN')
       END AS Color,
       SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH ROLLUP

Item                 Color                QtySum                     
-------------------- -------------------- -------------------------- 
Chair                Blue                 101.00                     
Chair                Red                  210.00                     
Chair                ALL                  311.00                     
Table                Blue                 124.00                     
Table                Red                  223.00                     
Table                ALL                  347.00                     
ALL                  ALL                  658.00                     
Her ne kadar gönderilen örnek kod ROLLUP kullanımı mümkün gibi dursa da,
1- Örnek kod ara toplam almıyor. Sadece datayları listeliyor.
2- Örnek kod tüm tarihleri içermiyor. Daha önceden kullanıcının seçmiş olduğu tarihleri kullanıyor.

Dolayısı ile daha spesifik bir SQL komutu yazılması ve daha farklı kontroller ile tarih geçişlerinin kontrolü gerekli olacaktır.
Kullanıcı avatarı
dogan
Üye
Mesajlar: 173
Kayıt: 17 Eki 2014 10:11

Re: Aynı tarihi bir kez gösterme

Mesaj gönderen dogan »

ertank yazdı:Merhaba,

Gönderilen kod ilgili bölümün tamamını içermiyor. Aşağıdaki cevaben sunulan kod bu bakımdan direk compile edilip çalışmayabilir.

Cevaben sunulan koda geçmeden önce bazı konulara dikkat etmekte fayda var.
1- with kullanımından mümkün mertebe kaçınmakta fayda var. Daha az klavye kullanımı daha çok karışıklığa sebep olabilir.
2- TFDQuery.Create(nil) ifadesi hafıza kaçağına sebep verebilir. Kodun tamamı görülmediği için ihtimal olarak yazıyorum. Ancak yüksek ihtimal diye hissediyorum.
3- Connection nesnelerinin en güzel kullanımı bir DataModule içinde olması ve mümkün olduğunca "uygulama ve database başına" bir tane connection nesnesi olmasıdır. Örnek kod "Form1.Connection" ifadesi kullanıyor. Bu kod bir DataModule kullanılmadığını ve her birden fazla form üzerinde farklı Connection nesneleri olabileceğini gösteriyor.
4- Sorulan soru ile ilgili çalıştırılacak SQL komutu hep aynı, sadece parametresi değiştirileceği için for döngüsü dışında bir defa oluşturulması yeterlidir.
5- FormatDateTime kullanır iken "d/mm/yyyy" gibi bir ifade 3 Ağustos 2016 için "3/08/2016" şeklinde bir değer gösterir. Eğer istenilen davranış bu ise sorun yok. Ancak genelde "03/08/2016" şeklinde bir ifade gösterilmesi alışkanlıktandır. Sonraki gösterim için formatın "dd/mm/yyyy" şeklinde olması gerekiyor.

Sorulan soruda istenilen işlemi gerçekleştirmenin birden fazla yolu var. Ben aklıma gelen ilk örneği veriyorum.

Kod: Tümünü seç

uses
  DateUtils;
  
var
  J: Integer;
  Query: TFDQuery;
  ExcelSonTarih: string;
begin
  Query := TFDQuery.Create(nil);
  try
    Query.Connection := Form1.Connection;
    Query.Close();
    Query.SQL.Clear();
    Query.SQL.Add('Select * From AYSONUDOKUM');
    Query.SQL.Add('Where TARIHLER=:TRL Order By ID DESC');
    Query.Prepare();
    
    ExcelSonTarih := EncodeDate(1900, 1, 1);   // Boş değer (EmptyStr) ihtimali var. Olmayacak bir tarih ataması yap. 
    for J := Form1.ListView1.Items.Count-1 downto 0 do
    begin
      Query.Close();
      Query.ParamByName('TRL').AsDate := StrToDate(Items.Item[J].SubItems[11]);
      Query.Open();
      if Query.RecordCount > 0 then
      begin
        if ExcelSonTarih <> Query.FieldByName('TARIHLER').AsString then
        begin
          ExcelSonTarih := Query.FieldByName('TARIHLER').AsString;
          Sheet.Cells[Row, 3] := FormatDateTime('d/mm/yyyy dddd', StrToDate(ExcelSonTarih));
        end;

        Inc(Row);
        Sheet.Cells[Row, 1] := Form1.ListView1.Items.Item[J].SubItems[0];
        Sheet.Cells[Row, 2] := Form1.ListView1.Items.Item[J].SubItems[1];
        Sheet.Cells[Row, 3] := Form1.ListView1.Items.Item[J].SubItems[2];
        Sheet.Cells[Row, 4] := Form1.ListView1.Items.Item[J].SubItems[3];
        Sheet.Cells[Row, 5] := Form1.ListView1.Items.Item[J].SubItems[4];
        Sheet.Cells[Row, 6] := Form1.ListView1.Items.Item[J].SubItems[5];
        Sheet.Cells[Row, 7] := Form1.ListView1.Items.Item[J].SubItems[6];
        Inc(Row);
      end;
    end;
  finally
    Query.Free();
  end;
end;
Üstat çok güzel bir makale eline diline sağlık özellikle with bilgi kısmı bazen sorun yaşıyordum...

Üstat satırlar arası boş alan kalıyor bu neden olabilir.
Resim
ertank
Kıdemli Üye
Mesajlar: 1653
Kayıt: 12 Eyl 2015 12:45

Re: Aynı tarihi bir kez gösterme

Mesaj gönderen ertank »

Başlık değişim kontrolü kısmındaki mantık hatası sebep oluyor sanırım. Aşağıdaki şekilde düzelmesi gerekli.

Kod: Tümünü seç

uses
  DateUtils;
  
var
  J: Integer;
  Query: TFDQuery;
  ExcelSonTarih: string;
begin
  Query := TFDQuery.Create(nil);
  try
    Query.Connection := Form1.Connection;
    Query.Close();
    Query.SQL.Clear();
    Query.SQL.Add('Select * From AYSONUDOKUM');
    Query.SQL.Add('Where TARIHLER=:TRL Order By ID DESC');
    Query.Prepare();
    
    ExcelSonTarih := EncodeDate(1900, 1, 1);   // Boş değer (EmptyStr) ihtimali var. Olmayacak bir tarih ataması yap. 
    for J := Form1.ListView1.Items.Count-1 downto 0 do
    begin
      Query.Close();
      Query.ParamByName('TRL').AsDate := StrToDate(Items.Item[J].SubItems[11]);
      Query.Open();
      if Query.RecordCount > 0 then
      begin
        if ExcelSonTarih <> Query.FieldByName('TARIHLER').AsString then
        begin
          ExcelSonTarih := Query.FieldByName('TARIHLER').AsString;
          Sheet.Cells[Row, 3] := FormatDateTime('d/mm/yyyy dddd', StrToDate(ExcelSonTarih));
          Inc(Row); // Başlık eklemesi yapıldığında ekstradan boş satır olsun
        end;

        Sheet.Cells[Row, 1] := Form1.ListView1.Items.Item[J].SubItems[0];
        Sheet.Cells[Row, 2] := Form1.ListView1.Items.Item[J].SubItems[1];
        Sheet.Cells[Row, 3] := Form1.ListView1.Items.Item[J].SubItems[2];
        Sheet.Cells[Row, 4] := Form1.ListView1.Items.Item[J].SubItems[3];
        Sheet.Cells[Row, 5] := Form1.ListView1.Items.Item[J].SubItems[4];
        Sheet.Cells[Row, 6] := Form1.ListView1.Items.Item[J].SubItems[5];
        Sheet.Cells[Row, 7] := Form1.ListView1.Items.Item[J].SubItems[6];
        Inc(Row);
      end;
    end;
  finally
    Query.Free();
  end;
end;
Cevapla