boss
boss

Reputation: 1606

How to use Custom multiple Objects on Crystal Report

I didn't use crystal report before. But for a project, I need to use it instead of fastreport because of printing issues.. I have bene trying to solve my problem for many hours but haven't found out any solution yet..

Well, I have two classes to use on crystal report. I want to create a bill report.

I organized some data from my database and put them to my these classes.

public class ReportInfo
{
    public DateTime Date { get; set; }
    public string BillNumber { get; set; }
    public string Address { get; set; }
    public string BillAddress { get; set; }
    public string BillOwner { get; set; }
    public string TaxNumberIDNumber { get; set; }
    public List<ReportProduct> Products { get; set; }
    public string PaymentType { get; set; }
    public string MoneyWithText { get; set; }

}

public class ReportProduct
{                          
    public string ProductInfo { get; set; }
    public double Amount { get; set; }
    public string ProductCode { get; set; }
    public double Tax { get; set; }
    public double Price { get; set; }

}

As you see, there is one bill class (report info) and a list for products (report producs) in reportinfo class..

I want to create a report that would be some value (bill number, date...) on header and some value (products info) on details area.

here i did it for one bill (Also I dont know how to put bills in a report viewert)

var serialID = Convert.ToInt32(dgBillSerials.SelectedRows[0].Cells[0].Value);
var bills= BillsFromDatabase.Bills.Where(b => b.BillSerialID == serialID && (b.BillNumber>=txtFirstBillNumber.Value && b.BillNumber<=txtLastBillNumber.Value)).ToList();

var products = BillsFromDatabase.Products.Where(p => p.BillID == bills[0].ID).ToList();
ReportInfo ri = new ReportInfo();
ri.Address = bills[0].Address;
ri.BillAddress = bills[0].BillAddress;
ri.BillNumber =bills[0].SerialNumber + bills[0].BillNumber.ToString();
ri.BillOwner = bills[0].OwnerType == "sirket" ? bills[0].PersonTitle : bills[0].Name;
ri.Date = bills[0].BillDate;
ri.MoneyWithText = "deneme";
ri.PaymentType = bills[0].PaymentType;
ri.TaxNumberIDNumber=bills[0].OwnerType=="sirket"?bills[0].TaxDepartment + " " + bills[0].TaxNumber:bills[0].NationalID;
ri.Products = new List<ReportProduct>();
double sum=0;

foreach (var product in products)
{
 sum += product.Price;
 ri.Products.Add(new ReportProduct()
 {
   Price = product.Price,
   ProductCode = product.ProductCode,
   ProductInfo = product.ProductInfo,
   Amount = Math.Round((product.Price/118)*100,2),
   Tax =Math.Round( product.Price -((product.Price / 118) * 100),2)
 });

}

 ri.MoneyWithText = Utils.MoneyToText(sum);

 ReportDocument crystalReport  = new ReportDocument();

 crystalReport.Load(@"..my path....\BillCrystalReport.rpt");

 crystalReport.SetDataSource(ri);

crystalReportViewer1.ReportSource = crystalReport;

when I run that code an exception throws that is "source object is not valid" on crystalReport.SetDataSource(ri);

I know that it looks unfair but I dont know how to implement two tables to my crystal report. when I add my both classes to the crystal repot it looks like that

crystal report

I made this one for one class and its OK. but this tutoraial doesnt talk about multiple data objects.

http://msdn.microsoft.com/en-us/library/ms227595(v=vs.80).aspx

ps: using vs 2012 and fw 4.0 and installed sap crystal report.

Upvotes: 2

Views: 3656

Answers (1)

boss
boss

Reputation: 1606

I solved my problem.. Well firstly I added an int value which is about relation between bill and products and removed public List Products { get; set; } that property from ReportInfo

public class ReportInfo
{
    public DateTime Date { get; set; }
    public string BillNumber { get; set; }
    public string Address { get; set; }
    public string BillAddress { get; set; }
    public string BillOwner { get; set; }
    public string TaxNumberIDNumber { get; set; }
    public string PaymentType { get; set; }
    public string MoneyWithText { get; set; }
    public int OrderId { get; set; }
}

public class ReportProduct
{                          
    public string ProductInfo { get; set; }
    public double Amount { get; set; }
    public string ProductCode { get; set; }
    public double Tax { get; set; }
    public double Price { get; set; }
    public int OrderId { get; set; }

}

and here is get bills and products and open a new form

  var serialID = Convert.ToInt32(dgBillSerials.SelectedRows[0].Cells[0].Value);
               var bills= BillsFromDatabase.Bills.Where(b => b.BillSerialID == serialID && (b.BillNumber>=txtFirstBillNumber.Value && b.BillNumber<=txtLastBillNumber.Value)).ToList();


              var reportInfoList = new List<ReportInfo>();
               var reportProductList = new List<ReportProduct>();
               var tmp1 =new ReportInfo();
               var tmp2 = new ReportProduct();
               foreach (var bill in bills)
               {

                   tmp1= new ReportInfo()
                       {
                           Address = bill.Address,
                           BillAddress = bill.BillAddress,
                           BillNumber =bill.SerialNumber + bill.BillNumber.ToString(),
                           BillOwner = bill.OwnerType == "sirket" ? bill.PersonTitle : bill.Name,
                        //   Date = bill.BillDate,
                           MoneyWithText = "deneme",
                           PaymentType = bill.PaymentType,
                           TaxNumberIDNumber=bill.OwnerType=="sirket"?bill.TaxDepartment + " " + bill.TaxNumber:bill.NationalID,
                           OrderId = bill.ID,
                           Date = bill.BillDate
                       };

                   var products = BillsFromDatabase.Products.Where(p => p.BillID == bill.ID).ToList();
                   double sum = 0;
                   foreach (var product in products)
                   {
                       sum += product.Price;
                       reportProductList.Add(new ReportProduct()
                                             {  
                                                 Price = product.Price,
                                                 ProductCode = product.ProductCode,
                                                ProductInfo = product.ProductInfo,
                                                Amount = Math.Round((product.Price/118)*100,2),
                                                Tax =Math.Round( product.Price -((product.Price / 118) * 100),2),
                                                OrderId = product.BillID

                                             });  
                   }

                   tmp1.MoneyWithText = Utils.MoneyToText(sum); 
                   reportInfoList.Add(tmp1);
               }

               FrmReportPreview preview = new FrmReportPreview(reportInfoList,reportProductList);
               preview.Show();

and the new form shows crystal report viewer

    private List<ReportInfo> _reportInfoList;
    private List<ReportProduct> _reportProductList;

    public FrmReportPreview(List<ReportInfo> reportInfoList, List<ReportProduct> reportProductList)
    {
        InitializeComponent();
        _reportInfoList = reportInfoList;
        _reportProductList = reportProductList;

    }

    private void FrmReportPreview_Load(object sender, EventArgs e)
    {
        LoadReport();
    }

    private void LoadReport()
    {

        ReportDocument crystalReport = new ReportDocument();                      

        crystalReport.Load(@"...mypath\BillCrystalReport.rpt");


        crystalReport.Database.Tables[0].SetDataSource(_reportInfoList);
        crystalReport.Database.Tables[1].SetDataSource(_reportProductList);


        crystalReportViewer1.ReportSource = crystalReport;

        crystalReportViewer1.RefreshReport();

    }

and here is my crystal report design

crystal report design

and this is the result

the result

Upvotes: 3

Related Questions