Tekrar merhaba,

Bu seferki makalemiz yine FastReport.Net üzerine...

Bu makalede ise DataGridView üzerinde seçili satırların nasıl raporlanabileceğini incelemeye çalışacağız.

Aslında bu makale, temel olarak 'FastReport.Net Kullanımı - Visual Studio Integration' başlıklı yazıdan çok farklı değil. Aynı bilgileri, ancak farklı veritabanı ve nesne tiplerini kullanarak, başka bir işlem gerçekleştireceğiz.

Makalenin mevzuu olan kodlara geri dönelim.

Formumuzun görüntüsü şu şekilde olacak:

FastReportSample_001_Resim001.png

 

Forma ait kodlarımız da burada:


public partial class BookList : Form
{
   public BookList()
   {
      InitializeComponent();
      dgv.DataSource = GetList(); // Listeyi yüklüyoruz.
   }

   /// <summary>
   /// Sadece seçili satırları rapora yükler ve raporu gösterir.
   /// </summary>
   /// <param name="sender"></param>
   /// <param name="e"></param>
   private void ReportSelectedRows_Click(object sender, EventArgs e)
   {
      DataTable dt = GetFilledDataTableForReport(dgv);
      if (dt != null)
         CreateReport(dt);
   }

   /// <summary>
   /// Bütün satırları rapora yükler ve raporu gösterir.
   /// </summary>
   /// <param name="sender"></param>
   /// <param name="e"></param>
   private void ReportAllRows_Click(object sender, EventArgs e)
   {
      DataTable dt = GetFilledDataTableForReport(dgv, false);
      if (dt != null)
         CreateReport(dt);
   }

   /// <summary>
   /// Veritabanından kitap listesini çeker ve geriye döndürür.
   /// </summary>
   /// <returns></returns>
   List<BookInfoModel> GetList()
   {
      using (DBDataContext db = new DBDataContext())
      {
         return db.Books.OrderBy(x => x.Type.Name)
                        .ThenBy(x => x.Writer.Name)
                        .Select(x => new BookInfoModel()
                        {
                           Type = x.Type.Name,
                           Writer = x.Writer.Name,
                           Book = x.Name
                        })
                  .ToList();
      }
   }

   /// <summary>
   /// Rapor olarak sunulacak olan bilgileri DataTable'a yükler
   /// ve bu DataTable'ı geriye döndürür.
   /// </summary>
   /// <param name="dgv"></param>
   /// <param name="onlySelectedRows">Sadece seçili satırların
   /// yüklenip yüklenmeyeceğini belirler.</param>
   /// <returns></returns>
   DataTable GetFilledDataTableForReport(DataGridView dgv, bool onlySelectedRows = true)
   {
      // Sadece seçili satırlar talep edildiyse ve hiç satır seçilmemişse
      if (onlySelectedRows && dgv.SelectedRows.Count < 1)
      {
         MessageBox.Show("Seçili satır bulunamadığı için işlem iptal edildi.",
                         "Geçersiz İşlem", MessageBoxButtons.OK, MessageBoxIcon.Hand);
         return null;
      }

      DataTable dt = new DataTable();
      dt.Columns.AddRange(new DataColumn[] 
      { 
         new DataColumn("Book"),
         new DataColumn("Type"),
         new DataColumn("Writer") 
      });

      List<DataGridViewRow> rc;

      if (onlySelectedRows)
         rc = dgv.SelectedRows.Cast<DataGridViewRow>().ToList();
      else
         rc = dgv.Rows.Cast<DataGridViewRow>().ToList();

      for (int i = 0; i < rc.Count; i++)
      {
         dt.Rows.Add(
            rc[i].Cells[0].Value.ToString(),
            rc[i].Cells[1].Value.ToString(),
            rc[i].Cells[2].Value.ToString()
         );
      }

      return dt;
   }

   /// <summary>
   /// Raporu oluşturur.
   /// </summary>
   /// <param name="data">Rapora yüklenecek olan veri</param>
   private void CreateReport(DataTable data)
   {
      // Rapor dosyasını oluşturuyoruz.
      Report report = new Report();

      // Programla aynı dizinden şablon olarak kullandığımız raporu yüklüyoruz.
	  report.Load("Report_Sample.frx");

      // Gelen verileri şablon olarak oluşturduğumuz rapor içerisinde
      // ismi belirtilen tabloya register ediyoruz.
      report.RegisterData(data, "BooksWithTypes");

      // Raporu hazırlıyoruz.
      if (report.Prepare())
      {
         // Hazırlanmış olan raporun gösterilmesini sağlıyoruz.
         report.ShowPrepared();
      }
   }
}

Ve bu da modelleme gayesiyle oluşturduğumuz class:


public class BookInfoModel
{
   public string Book { get; set; }
   public string Type { get; set; }
   public string Writer { get; set; }
}

Kodları temel itibariyle bu mantık üzerinde (ya da  daha da geliştirerek) oluşturursanız; istediğiniz satırları rapor dosyasına göndererek, sadece onların raporlanmasını sağlayabilirsiniz.

Örnek kodları buradan indirebilirsiniz. Zip içindeki db.sql dosyası ile veritabanını oluşturduktan sonra app.config içindeki adres bilgisini kendi SQL sunucunuza ait bilgi ile değiştirerek doğrudan kodları çalıştırabilirsiniz.

 

Biraz kısa bir yazı oldu aslında ama zaten kodların aralarında yeterince açıklama mevcut.

Tekrar görüşünceye kadar hoşçakalın...

 

Yorumlar

Bilal AFŞAR 30.11.2016 13:42
Rica ederim, işinizi gördüyse ne alâ.

Kolay gelsin.
Aydın MEMİŞ 30.11.2016 13:40
Bilal bey merhaba, ben fastreport tarafında yapmaya çalışıyordum siz daha pratik yol gösterdiniz.. ve

foreach (var item in itemList)
{
for (int i = 0; i < int.Parse(item.miktar.ToString()); i++)
{
table.Rows.Add(item.barkod, item.fiyat, item.isk, item.iskontolufiyat, item.malincinsi, item._barkodStd, item.miktar);
}
}
bu şekilde istediğim adette çıktı aldım..
yardımlarınız için teşekkürler.. saygılar
Bilal AFŞAR 30.11.2016 13:34
Aydın Bey, resimden ve yazdıklarınızdan anladığım kadarıyla, raporlamada, satır başına farklı miktarda baskı almaya çalışıyorsunuz. Ancak bunun fastreport içinden yapılabileceğini sanmıyorum.

Buna dair size tavsiyem, rapor içine göndereceğiniz listeye, her bir mala ait kaç adet etiket çıkartmak istiyorsanız, o miktarda satır eklemenizdir. Gönderdiğiniz örnek resme göre söylemek gerekirse; göndereceğiniz listeye 1 adet krem kaydı, 2 adet kalem kaydı ve 3 adet ENA8 ürünü kaydı eklemeniz gerek. Bu sayede raporda da toplam 3 mala ait 6 etiket görebileceksiniz.

Bunu yapabilmek için de, evvelki mesajda yazdığınız C# kodu kısmında, foreach içinde bir for döngüsü kullanabilir ve bu döngüyü de mala ait miktar adedince çalıştırabilirsiniz.

Örnek kod olarak şöyle gösterebilirim:

foreach (var item in itemList)
{
for(int i = 0; i<etiketMiktari; i++)
{
table.Rows.Add(item.barkod, item.fiyat, item.isk, item.iskontolufiyat, item.malincinsi, item._barkodStd,item.miktar);
}
}
Aydın MEMİŞ 30.11.2016 11:47
Bilal bey verdiğiniz bilgiler için ve ayırdığınız zaman için teşekkürler..

yaptığım uygulama etiket çıkarma uygulaması

Görseli:

http://www.imgim.com/wpflistview.png

çıkarılacak etiketin miktarı girilecek ve çıkar deyince, miktarı kadar çıktı alınacak..
ben listview'deki tüm listeyi fastreporta gönderiyorum ama tablomda miktar diye bi kolonum yok, fast reportta kolon ekleyerek oluşturdum.
miktar sayısını mesaj olarak banada göstermedi. şuan böyle kaldım ilerleyemedim..
Bilal AFŞAR 30.11.2016 02:33
Tekrar merhaba Aydın Bey,

Anladığım kadarıyla, oluşturduğunuz raporun sayfalarını, birden fazla kere yazdırmak istiyorsunuz. Ancak, (her ne kadar ifadenizde bu mânâ net olarak görünmese de) muhtemelen raporu görüntülerken, gönderdiğiniz sayı kadar görmek yerine hep 1 kopya görüyorsunuz.

Buna binaen, evvela söylemem gerek ki, daha evvel bu şekilde bir kullanıma hiç ihtiyaç duymadım. Bu sebeple ufak bir araştırma yapmam gerekti.

https://www.fast-report.com/documentation/UserMan/index.html?report_printing.htm adresinde de yazdığı üzere, birden fazla kopya çıkarmak istediğiniz zaman, Report.PrintSettings.Copies ayarını değiştirmeniz gerekiyor. Bu sebeple, izlediğiniz yolun doğru olduğunu söylemem gerek. Bunun haricinde, bir ayardan daha bahsedilmiş. Collate (Report.PrintSettings.Collate) ayarı true iken, sayfaları harmanlar yani ilk kopya için bütün sayfaları sırasıyla çıkartır ve sonrasında diğer kopyalara geçer. Bu ayar false ise, evvela bütün kopyalara ait ilk sayfaları çıkarttıktan sonra, diğer sayfaları da aynı mantıkla çıkartmaya devam eder. Varsayılan olarak bu ayar true'dur.

Ancak bu ayarları doğru olarak yapsanız bile, raporu görüntülerken yine tek bir kopya olarak görürsünüz. Yaptığınız ayar burada görünmez. Verdiğiniz kopya sayısını, sayfayı yazdır dediğiniz zaman çıkan ekranda görürsünüz (Yukarıda bahsi geçen sayfada, number of copies diye aradığınızda göreceğiniz ekran).

Bu kullanıma rağmen, her seferinde yine 1 değerini görüyorsanız, muhtemelen yanlış bir bilgi gönderiyorsunuz demektir.

Bunu anlamak için, dilerseniz, yazdığınız kod içinde yer alan Report.GetColumnValue("Table.miktar") ifadesini MessageBox.Show ile görüntülemeyi deneyin.

Ayrıca dikkat etmeniz gereken diğer bir nokta da şudur ki, bu değeri tablo ile gönderirken, her satır ile birlikte bir kopyası daha gitmektedir. Bu yüzden, bu değeri sadece 1 kere okumanız gerek. Aksi halde, bir hata verme ya da en azından istediğinizi yapamama riski de karşınıza çıkabilir.

İnşaallah, sıkıntınızın teşhisi ve buna binaen çözümü doğrudur.
Aydın MEMİŞ 29.11.2016 20:26
Şimdide kopya sayısında kaldım..

var itemList = ListStok.ToList();

DataTable table = new DataTable();
table.Columns.Add("BARCODE", typeof(string));
table.Columns.Add("SATISFIYATI1", typeof(string));
table.Columns.Add("ISK", typeof(string));
table.Columns.Add("iskontolufiyat", typeof(string));
table.Columns.Add("MALINCINSI", typeof(string));
table.Columns.Add("BARCODESTD", typeof(int));
table.Columns.Add("miktar", typeof(int));

// Iterate through data source object and fill the table
foreach (var item in itemList)
{
table.Rows.Add(item.barkod, item.fiyat, item.isk, item.iskontolufiyat, item.malincinsi, item._barkodStd,item.miktar);

}
DataTable dt = table;
if (dt != null)
{

etiketCikar etiket = new etiketCikar();

etiket.CreateReportRafEtiketi(dt, yaziciAdi, _onizlemeYap);
}

tabloya listviewden kopya sayısını gönderiyorum ama tık yok, hep tek sayfa çıkartıyor..
aşağıdaki şekilde kopya sayısını çekiyorum. Yanlış mı yapıyorum ?
Fast report tarafında :
Report.PrintSettings.Copies= ((Int32)Report.GetColumnValue("Table.miktar"));
Aydın MEMİŞ 29.11.2016 20:22
if (((Int32)Report.GetColumnValue("Table.BARCODESTD"))== 5)
{
Code128Barcode.Visible=true;
Ean13Barcode.Visible=false;
Ean8Barcode.Visible=false;
} else if (((Int32)Report.GetColumnValue("Table.BARCODESTD"))== 1)
{
Code128Barcode.Visible=false;
Ean8Barcode.Visible=false;
Ean13Barcode.Visible=true;
}
else if (((Int32)Report.GetColumnValue("Table.BARCODESTD"))== 2)
{
Code128Barcode.Visible=false;
Ean13Barcode.Visible=false;
Ean8Barcode.Visible=true;
}
bu şekilde hallettim
Bilal AFŞAR 25.11.2016 15:35
Merhaba Aydın Bey,

Yapmak istediğiniz işlem için, alâkalı DataBand'in AfterData event'ini kullanabilirsiniz.

Bu event içinde yapmanız gereken, istediğiniz kolonun değerini eğer gerekliyse diğer bir tipe dönüştürüp kontrol etmek ve buna göre barkoda ait kolonu gizlemekten ibaret. Ancak burada da dikkat edilmesi gereken bir yer var.

Kolon ismi olarak, veritabanından gelen isim yerine, FastReport içinde eklediğiniz nesneye verilen ismi kullanmanız gerek (Text1 gibi).

Yine de çözemezseniz, elimden geldiğince yardımcı olmaya çalışırım.
Aydın MEMİŞ 25.11.2016 02:26
Sayenizde fast reportla bişeyler yapmaya başladım ve bi noktada takıldım ;Dizayn ekranında bir kolunun değerine göre barkodu gizlemek yada göstermek istiyorum. Code tarafında biraz uğraştım ama sonuç elde edemedim. bununla ilgili bir örnek verebilirmisiniz ? saygılarımla

Yorum Yaz

Adınız: *
E-Mail Adresiniz: *
Web Sitesi:
Yorum: *
Güvenlik Kodu: *
 
Tavsiye
Bağlantılar
Tavsiye Ettiğimiz Sunucu Hizmeti
Domain Hizmetleri