Login Login
MORE

WIDGETS

Widgets

Wanted articles
Who is online?
Article tools

CSharp:Microsoft Reporting Services SSRS

From Aino Wiki

Jump to: navigation, search

Premessa

Getting started
Locate and start Reporting server Tools
Nell'IDE di Visual Studio per consentire di aggiungere nuovi item di tipo reporting leggi qui

Report RDLC

I reports sono files con estensione RDLC (che sta per Report Definition Language Client Side). Sono documenti (Report) a cui agganciare i dati provenienti da una fonte che può essere un DB SQL Server. Si possono collegare direttamente al DB o attraverso opportune classi da popolare prima di inviarle, con i relativi dati associati, al report.

I report da WPF

In questo scenario useremo un controllo XAML nel quale ci sarà l'oggetto che recepirà dinamicamente il file *.rdc vero e proprio e lo rappresenterà.

Lo XAML

Nel codice seguente, lo XAML ha l'oggetto ReportView nel quale confluirà il report da visualizzare:

<UserControl x:Class="WpfApp1.ReportControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp1"
             xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Loaded="UserControl_Loaded">
    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <WindowsFormsHost>
            <rv:ReportViewer x:Name="rptMain"></rv:ReportViewer>
        </WindowsFormsHost>
    </Grid>
</UserControl>

L'elemento <rv:ReportViewer> (riga 13) è il segnaposto del report da visualizzare.

Code Behind

L'evento che gestirà il popolamento dinamico del report da visualizzare è il TAG "Loaded="UserControl_Loaded" (riga 10) del primo elemento <UserControl> nello XAML. Lato C#, nel codeBehind:

public enum ReportType
{
	Customer,
	QuickSale,
	SubA1,
	MainA,
	SalesPrivateCustomer,
	ACCReferralLetter
	// TODO
}
//...
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
	//TestJson();
	rptMain.LocalReport.SubreportProcessing += LocalReport_SubreportProcessing;
	switch (CurrentReportType)
	{
		case ReportType.Customer:
			TestCustomerReport();
			break;
		case ReportType.QuickSale:
			TestQuickSaleReport();
			break;
		case ReportType.SubA1:
			TestSubA1Report();
			break;
		case ReportType.MainA:
			TestMainAReport();
			break;
		case ReportType.SalesPrivateCustomer:
			TestSalePrivateCustomerReport();
			break;
		case ReportType.ACCReferralLetter:
			Test_ClinetFile_ACCReferralLetter();
			break;
		default:
			throw new Exception("Report type not found");
	}
}
//...
 
// Assegnazione delle info per visualizzare il report voluto
private void TestQuickSaleReport()
{
	rptMain.LocalReport.ReportPath = string.Format("{0}\\Sale\\r_QuickSale.rdlc", m_reportsRootPath);

	object o = QuickSaleTest.GetTestReport(); // Classe che ha questo metodo per popolare la classe da mandare come dataset al report *rdlc

	ReportDataSource rds_h = new ReportDataSource();
	rds_h.Name = "QuickSale_Header";
	rds_h.Value = o;
	rptMain.LocalReport.DataSources.Add(rds_h);

	ReportDataSource rds_d = new ReportDataSource();
	rds_d.Name = "QuickSale_Details";
	rds_d.Value = ((List<r_QuickSaleModel_Header>)o).First().Details;
	rptMain.LocalReport.DataSources.Add(rds_d);

	ReportDataSource rds_p = new ReportDataSource();
	rds_p.Name = "QuickSale_PaymentMethods";
	rds_p.Value = ((List<r_QuickSaleModel_Header>)o).First().PaymentMethods;
	rptMain.LocalReport.DataSources.Add(rds_p);

	rptMain.RefreshReport();
}

Segue calse e metodo di test per popolare con dati tipo il report

internal class QuickSaleTest
    {
        private static Random random = new Random();

        private static string RandomString() {
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
            return new string(Enumerable.Repeat(chars, random.Next(10, 101)).Select(s => s[random.Next(s.Length)]).ToArray());
        }

        public static IEnumerable< r_QuickSaleModel_Header> GetTestReport()
        {
            r_QuickSaleModel_Header r = new r_QuickSaleModel_Header()
            {

                // clinic info
                ClinicName = "Clinic Name",
                ClinicAddress1 = "23, Test road",
                ClinicAddress2 = "20153 Castellanza (VA)",
                ClinicPhone = "0123-456789",
                ClinicGSTNumber = "IT0123456789",

                // doc info
                DocType = "Quick sale",
                DocDate = "2018-05-09",
                DocNumber = "QS-18/0001A3",

                // invoice to
                CustomerFirstName = "Andrea", CustomerLastName = "Colombo",
                CustomerAddress1 = "via C. De Simoni, 15", CustomerAddress2 = "21049 Tradate (VA)",
                CustomerCode = "DUMMY001",

                // clinician
                ClinicianFirstName = "Mario", ClinicianLastName = "Rossi",

                // amount info
                GSTPercentage = 15m,
                RoundingAmount = 0.74m,
                CompanyCode = "071"
            };
            if (r.CompanyCode == "071")
                r.CompanyName = "Bay Audiology";
            else if (r.CompanyCode == "072")
                r.CompanyName = "Dilworth Hearing";
            else
                r.CompanyName = "";

            // Dettagli
            r.Details = new List<r_QuickSaleModel_Detail>();
            for (int i = 0; i < random.Next(1,200); i++)
            {
                r_QuickSaleModel_Detail d = new r_QuickSaleModel_Detail()
                {
                    Code = random.Next(100000).ToString().PadLeft(8, '0'),
                    Description = RandomString(),
                    Quantity = random.Next(15),
                    UnitPrice = (decimal)random.Next(100000) / 100m
                };
                d.Amount = random.Next(100000) % 5 == 0 ? d.Quantity * d.UnitPrice - (decimal)random.Next((int)(d.Quantity * d.UnitPrice / 2 * 100)) / 100m : d.Quantity * d.UnitPrice;
                r.Details.Add(d);
            }

            // Metodi di pagamento
            r.PaymentMethods = new List<r_QuickSaleModel_Payment>();
            r.PaymentMethods.Add(new r_QuickSaleModel_Payment() { MethodDescr = "Method 1", MethodAmount = 123.45m });
            r.PaymentMethods.Add(new r_QuickSaleModel_Payment() { MethodDescr = "Method 2", MethodAmount = 555.0m });

            return new List<r_QuickSaleModel_Header>() { r };
        }
    }

Classe dataset

Conterrà i dati, opportunamente recuperati, da inviare al report *.rdlc

public class r_QuickSaleModel_Header
{
	public string ClinicName { get; set; }
	public string ClinicAddress1 { get; set; }
	public string ClinicAddress2 { get; set; }
	public string ClinicPhone { get; set; }
	public string ClinicGSTNumber { get; set; }

	public string DocType { get; set; }
	public string DocNumber { get; set; }
	public string DocDate { get; set; }

	public string CustomerFirstName { get; set; }
	public string CustomerLastName { get; set; }
	public string CustomerAddress1 { get; set; }
	public string CustomerAddress2 { get; set; }
	public string CustomerCode { get; set; }
	public string CustomerName { get { return string.Join(", ", new string[] { this.CustomerFirstName, this.CustomerLastName }); } }

	public string ClinicianFirstName { get; set; }
	public string ClinicianLastName { get; set; }
	public string ClinicianName { get { return string.Join(", ", new string[] { this.ClinicianFirstName, this.ClinicianLastName }); } }

	public List<r_QuickSaleModel_Detail> Details { get; set; }

	public decimal GSTPercentage { get; set; }
	public decimal GSTAmount { get { return this.InvoiceAmount * (this.GSTPercentage / 100m); } }
	public string GSTString { get { return string.Format("Includes {0:N2}% GST {1:N2}", this.GSTPercentage, this.GSTAmount); } }
	public decimal InvoiceAmount { get { return this.Details.Sum(s => s.Amount); } }
	public decimal RoundingAmount { get; set; }

	public List<r_QuickSaleModel_Payment> PaymentMethods { get; set; }

	public decimal BalanceDue { get { return -(this.InvoiceAmount - this.RoundingAmount - this.PaymentMethods.Sum(s => s.MethodAmount)); } }

	public string CompanyCode { get; set; }
	public string CompanyName { get; set; }
}

public class r_QuickSaleModel_Detail
{
	public string Code { get; set; }
	public string Description { get; set; }
	public decimal Quantity { get; set; }
	public decimal UnitPrice { get; set; }
	public decimal Amount { get; set; }
	public decimal Discount { get { return this.Amount - (this.UnitPrice * this.Quantity); } }
}

public class r_QuickSaleModel_Payment
{
	public string MethodDescr { get; set; }
	public decimal MethodAmount { get; set; }
}

Es di Report rdlc

Il contenuto vero e proprio è un XML, ma dall'editor dell'IDE si presenta così:

Report rdlc binding with dataset.png

Aggiungere un dataset

Per aggiungere un dataset, il seguente esempio si basa sui dati come dal paragrafo precedente 'I report da WPF':

Report rdlc adding dataset.png

Mappa e Link


C# | SQL Server Sistemi di Reporting


Visual Studio | MS SQL | SSIS


Parole chiave: Report | RDLC | .RDLC

Author