C#: Kostenlose Druckberichte mit Visual Studio Express, SQL Server Report Builder und lokalen SQL Server Reports

Ich hatte schon mal unter RDLC Reports mit Visual Studio Express und Einfache Reports mit MyNeoReport etwas über Möglichkeiten geschrieben wie man Reports mit der kostenlosen Version vom Visual Stusio (Express) hin bekommen kann.
Beide varianten waren noch eher suboptimal und nicht ganz professionell.

Hier möchte ich nun eine „neue“ bzw. „bessere“ Möglichkeit vorstellen Reports mit dem SQL Server Report Builder 3.0 und
SQL Server Reports (2012) zu gestalten.
Am Ende dieses Artikels wollen wir eine kleine Mini-Rechnung haben, welche aus einen C#-Programm mit Daten gefüllt, und im Report-Viewer angezeigt wird.

Dazu braucht man erst einmal als vorraussetzung folgende 2 Installationspakete:

Microsoft® SQL Server® 2012 SP1 Report Builder
http://www.microsoft.com/de-de/download/details.aspx?id=35576
(Report-Designer zum erstellen der Reports)

MICROSOFT REPORT VIEWER 2012-LAUFZEIT
http://www.microsoft.com/de-de/download/details.aspx?id=35747
(Report Viewer zum Vorschau-Anzeigen der Reports)

Nach dem die 2 Pakete Installiert sind, startet man den Report Builer und geht in folgenden Schritten vor um einen neuen, leeren Bericht zu erstellen:

Neuer Bericht -> Leerer Bericht

Nun sollte der Report Builder in etwa so aussehen:
RDLC1

Damit wir nun auch etwas in dem Bericht anzeigen können, müssen wir Datenquellen definieren.
Die Datenquelle kommt später aus dem C# Programm das wir im Anschluss noch entwickeln werden.
Um eine Datenquelle im Report-Builder zu definieren geht man wie folgt vor:

Rechtsklick auf Datenquelle 
    -> Datenquelle Hinzufügen
       - Name: Datasource1
       - In meinem Bericht eingebettete Verbindung verwenden
       - Verbinsungstyp: XML
       - Verbindungszeichenfolge: leer lassen

Zu jeder Datenquelle gehört auch Mindestens ein DataSet.
In einem DataSet liegen die eigentlichen Daten welche auf dem report angedruckt werden sollen.
Praktischerweise kann man das DataSet im Report-Builder auch gleich mit Beispiel-Daten füllen.
Wir fügen in diesem Beispiel 2 DataSets hinzu (eines für Kopfaten und eines für Leistungen).
Die DataSets definieren wir in folgenden Schritten:

Rechtsklick auf Datasets 
    -> Dataset hinzufügen
       - Name: Kopfdaten
       - Ein in den eigenen Bericht eingebettetes Dataset verwenden
       - Datenquelle: Datasource1
       - Abfragetyp: Text

Die Abfrage selbst wird hier als XML definiert.
Im Prinzip fragt man hier ein Komplettes XML Dokument ab, welches einen Tabellarischen Inhalt hat.
Für dieses beispiel hier eine Tabelle mit 5 Spalten (Titel, Datum, RGNR, Referenz und Fusstext) und einer Daten-Zeile.
Diese Abfrage würde für uns so aussehen:

1
2
3
4
5
6
7
8
9
10
11
<Query>
<XmlData>
<Kopfdaten>
  <Titel>Rechnung</Titel>
  <Datum>12.07.2013</Datum>
  <RGNR>25786</RGNR>
  <REFERENZ>REFNO1234567</REFERENZ>
  <Fusstext>Hier Steht der Fußtext drin</Fusstext>
</Kopfdaten>
</XmlData>
</Query>

Da wir noch eine tabelle für die Leistungen brauchen, müssen wir noch ein zweites DataSet anlegen.
Das funktioniert genauso wie beim ersten DataSet auch, nur das der Name „Leistungen“ ist und die Abfrage wie folgt aussieht:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<Query>
<XmlData>
<Root>
<item>
  <Text>Text 1</Text>
  <Menge>1</Menge>
  <Betrag>10,00</Betrag>
  <Waehrung>EUR</Waehrung>
</item>
<item>
  <Text>Text2</Text>
  <Menge>2</Menge>
  <Betrag>20,00</Betrag>
  <Waehrung>EUR</Waehrung>
</item>
<item>
  <Text>Text 3</Text>
  <Menge>3</Menge>
  <Betrag>30,00</Betrag>
  <Waehrung>EUR</Waehrung>
</item>
</Root>
</XmlData>
</Query>

Nun erscheinen die Berichtsdaten im gleichnahmigen linken Fenster.
Die Felder der Kopfdaten kann man nun via Drag&Drop auf den Report ziehen.
Um eine Tabelle für die Leistungen der Rechnung auf dem Report anzeigen zu können, gehen wir wieder in folgenden Schritten vor:

Menü: Einfügen 
    -> Tabelle 
        -> Tabelle Einfügen 
            -> Tabelle auf den Report ziehen

Um eine weitere Spalte in der Tabelle anzuzeigen gehen wir wie folgt vor:

Rechtsklick auf die Tabelle 
    -> Spalten einfügen -> rechts

Anschließend können wir auch hier die Felder des DataSets „Leistungen“ via Drag&Drop auf die Tabelle ziehen.

-> Menge
-> Text
-> Betrag
-> Waehrung

Nun sollte der Fertige Bericht in etwa so aussehen:
RDLC2

Um uns nun mit dem Fortschritt zu belohnen, können wir jetzt schon oben links im Report Builder auf „Ausführen“ klicken.
Nun wird der Bericht ausgeführt und uns eine Vorschau angezeigt wie in etwa wie folgt aussehen sollte:

RDLC3

Wenn der Report in etwa so aussieht wurde bis hier hin alles korrekt gemacht – Glückwunsch! 🙂

Diesen Bericht speichere ich hier unter dem Namen „frickelblogrg.rdl“ – dieser wird später noch einmal gebraucht.


———————————————————————————————————————————————————————

Visual Studio Express 2012

IM VS 2012 Express erstellen wir nun ein neues Projekt (Windows Forms).
Dieses Projekt speichere ich bei mir in dem Verzeichnis: F:\Visual_Studio_2012\Express\RDLtest\.

Wir wollen nun unseren soeben erstellen Bericht in einem ReportViewer Control anzeigen lassen.
Für diesen haben wir extra das ReportViewer MSI Paket am Anfang installiert.
Dieses Control erscheint leider nicht Standardmäßig in der ToolBox.
Um dieses in die ToolBox zu bekommen sind folgende Schritte notwendig:

Werkzeugkasten 
    -> Rechtsklick 
        -> Elemente Auswählen 
            -> .NET Framework Komponenten 
                -> ReportViewer (WinForms) Version 11.0.0.0

In den auszuwählenden Elementen sieht der Eintrag so aus:
RDLC4

Und wenn der ReportViewer in der ToolBox eingefügt ist, sieht er dort wie folgt aus:
RDLC5

Dieses Control nehmen wir nun und ziehen es via Drag&Drop auf die leere Form.

Vorbereitend kopieren wir jetzt den Bericht (in meinem Fall: „frickelblogrg.rdl“) in den „bin“ Pfad des Projektes.
Dies wäre bei mir das Verzeichnis „F:\Visual_Studio_2012\Express\RDLtest\RDLtest\bin\Debug\“.
Von dort aus werden wir den Bericht auch gleich aufrufen.

Für die Daten des Berichtes müssen wir Analog zu den DataSets im Bericht auch in unserem Programm die Daten zur Verfügung stellen.
Am Einfachsten geht dies über 2 List welche Elemente von 2 Klassen Analog zu den DataSets besitzen.

Die Klassendefinition für die Datenklassen wäre folgende:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class kopfdaten
{
    public string Titel { get; set; }
    public string Datum { get; set; }
    public string RGNR { get; set; }
    public string REFERENZ { get; set; }
    public string Fusstext { get; set; }
}
 
public class leistungen
{
    public string Text { get; set; }
    public string Menge { get; set; }
    public string Betrag { get; set; }
    public string Waehrung { get; set; }
}

Das füllen erstellen dieser Klassen und Füllen der Listen sieht wie folgt aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Kopfdaten erstellen
List<kopfdaten> K = new List<kopfdaten>();
kopfdaten k = new kopfdaten();
k.Titel     = "Recnung";
k.RGNR      = "4711";
k.REFERENZ  = "HBSS0805";
k.Datum     = "18.07.2013";
k.Fusstext  = "Rechnung zahlbar innerhalb von 14 Tagen!";
K.Add(k);
 
// Leistungen erstellen
List<leistungen> L = new List<leistungen>();
L.Add(new leistungen() { Text = "Gummibärchen", Menge = "14 Tüten", Betrag = "28,45", Waehrung = "EUR" });
L.Add(new leistungen() { Text = "Zaunlatten",   Menge = "50 Stk.",  Betrag = "99,00", Waehrung = "EUR" });
L.Add(new leistungen() { Text = "Bier",         Menge = "2 Kisten", Betrag = "22,00", Waehrung = "EUR" });
L.Add(new leistungen() { Text = "Grillwurst",   Menge = "5 Pack",   Betrag = "14,99", Waehrung = "EUR" });

Das Übergeben der Daten an den ReportViewer sieht so aus:

1
2
3
4
5
// Dem Report die Datasourcen übergeben
ReportDataSource rds_K = new ReportDataSource("Kopfdaten", K);
ReportDataSource rds_L = new ReportDataSource("Leistungen", L);
reportViewer1.LocalReport.DataSources.Add(rds_K);
reportViewer1.LocalReport.DataSources.Add(rds_L);

Danach muss eigentlich nur noch der Bericht angegeben werden und das ReportViewer Control einmal Refresh´t werden:

1
2
3
4
// Den Report angeben
reportViewer1.LocalReport.ReportPath = "frickelblogrg.rdl";
// Den Report im ReprotViewer Control Refreshen
this.reportViewer1.RefreshReport();

Der komplette Quelltext der Form sieht dann so aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace RDLtest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            // Kopfdaten erstellen
            List<kopfdaten> K = new List<kopfdaten>();
            kopfdaten k = new kopfdaten();
            k.Titel     = "Recnung";
            k.RGNR      = "4711";
            k.REFERENZ  = "HBSS0805";
            k.Datum     = "18.07.2013";
            k.Fusstext  = "Rechnung zahlbar innerhalb von 14 Tagen!";
            K.Add(k);
 
            // Leistungen erstellen
            List<leistungen> L = new List<leistungen>();
            L.Add(new leistungen() { Text = "Gummibärchen", Menge = "14 Tüten", Betrag = "28,45", Waehrung = "EUR" });
            L.Add(new leistungen() { Text = "Zaunlatten",   Menge = "50 Stk.",  Betrag = "99,00", Waehrung = "EUR" });
            L.Add(new leistungen() { Text = "Bier",         Menge = "2 Kisten", Betrag = "22,00", Waehrung = "EUR" });
            L.Add(new leistungen() { Text = "Grillwurst",   Menge = "5 Pack",   Betrag = "14,99", Waehrung = "EUR" });
 
            // Den Report angeben
            reportViewer1.LocalReport.ReportPath = "frickelblogrg.rdl";
 
            // Dem Report die Datasourcen übergeben
            ReportDataSource rds_K = new ReportDataSource("Kopfdaten", K);
            ReportDataSource rds_L = new ReportDataSource("Leistungen", L);
            reportViewer1.LocalReport.DataSources.Add(rds_K);
            reportViewer1.LocalReport.DataSources.Add(rds_L);
 
            // Den Report im ReprotViewer Control Refreshen
            this.reportViewer1.RefreshReport();
        }
    }
 
    public class kopfdaten
    {
        public string Titel { get; set; }
        public string Datum { get; set; }
        public string RGNR { get; set; }
        public string REFERENZ { get; set; }
        public string Fusstext { get; set; }
    }
 
    public class leistungen
    {
        public string Text { get; set; }
        public string Menge { get; set; }
        public string Betrag { get; set; }
        public string Waehrung { get; set; }
    }
}

Haben wir nun alles korrekt gemacht können wir das Programm ausführen und erhalten folgende Ansicht:
RDLC6

Wenn die Ausgabe bei euch genau so (oder ähnlich) aussieht, habt ihr alles richtig gemacht (und ich habe den Artikel halbwegs verständlich geschrieben) – Herzlichen Glückwunsch noch mal an dieser Stelle hier! 🙂

Nun bleibt nicht mehr viel zu sagen – Ich wünsche euch viel Spaß bei dieser tollen, neuen, besseren Möglichkeit des Kostenlosen Reportings 🙂

Anmerkung:
Das Beispiel-Projekt dazu könnt ihr euch unter https://code.google.com/p/frickelblog/source/browse/#svn%2Ftrunk%2Fsamples%2FCSharp%2FRDLtest anschauen.

Oder direkt als SVN Checkout (http): http://frickelblog.googlecode.com/svn/trunk/samples/CSharp/RDLtest/

3 Responses to C#: Kostenlose Druckberichte mit Visual Studio Express, SQL Server Report Builder und lokalen SQL Server Reports

  1.  

    Danke für deinen Beitrag.

    Eine Frage hätte ich noch. Eignet sich der SQL ReportBuilder auch für Dokumente über mehrere Seiten? Kommt er mit Seitenumbrüchen klar?
    Hast du da schon Erfahrungen gesammelt?

  2. Hallo Thomas,
    ich denke schon das die SQL Server reports so mächtig sind und Seitenumbrüche beherrschen.
    Selbst gebraucht habe ich es noch nicht, darum kein Beispiel verfügbar – aber unter http://technet.microsoft.com/de-de/library/dd255278%28v=sql.105%29.aspx und http://technet.microsoft.com/de-de/library/dd207058%28v=sql.105%29.aspx sollte sich etwas zu Seitenumbrüchen in den SQl Server Reports finden lassen 🙂

     
  3.  

    Hallo Sven,

    der Eintrag ist zwar schon älter, aber ich muss aktuell einen kleinen Bericht von Werten in einer Datenbank erzeugen.

    Zur Einfachheit und klaren Struktur arbeite ich hier mit dem Entity Framework.

    Das Ganze kann man auch entsprechend übergeben: reportViewer2.LocalReport.ReportPath = „test.rdl“;
    var result = global.db.Rechnungspositionen.Where(s => s.Rechnungen.Nr == „25786“).
    Select(s => new { Menge = s.Menge, Text = s.Artikel.Name });
    ReportDataSource source = new ReportDataSource(„DataSet1“, result);
    reportViewer2.LocalReport.DataSources.Add(source);

    Das Datenset kann man auch schön im Designer erstellen lassen.

    Fazit: Wer seine Datenbank schön angelegt hat, kommt mit relativ wenig, zu einem relativ schnellen Ergebnis.

    Mit OleDB und ODBC ist man hier auch nicht eingegrenzt. Nicht schlecht MS!

leave your comment

*

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

Unterstütze den Frickelblog!