Sonntag, 11. Januar 2015

Mit ReportItems auf Inhalte in Tablix-Zellen zugreifen

In etwas anspruchsvolleren Berichten benötigen Sie gelegentlich die Möglichkeit, den Inhalt der Zelle in einer Tabelle oder Matrix an anderer Stelle noch einmal zu verwenden. Das ist durchaus möglich aber nicht ganz offensichtlich.

Ein einfaches Beispiel

Im vorliegenden Beispiel sehen Sie zwei Tabellen, in denen die Umsätze unterschiedlicher Länder dargestellt werden. Der Bericht soll nun noch um ein Textfeld erweitert werden, das die Summe der beiden "Total" Zellen berechnet.


Das Textfeld rechts unten zeigt die Summe der "Total"-Zellen der beiden Tabellen an

Um das zu erreichen, ist es nützlich den beiden Tabellenzellen erst einmal sprechende Namen zu geben. Exakter ausgedrückt: Eine Tabelle (Tablix) in SSRS besteht aus TextBoxen. Diejenigen TextBoxen in den Tabellen, welche den "Total" Wert enthalten, bekommen die Namen "SummeTablix1" und "SummeTablix2". Das folgende Bild zeigt dies deutlicher.


Der Name dieser TextBox wird geändert nach "SummeTablix1"
Nach dieser Vorbereitung kann die neue TextBox rechts unten im Bericht hinzugefügt werden. Der folgende Ausdruck leistet das Gewünschte: 

 =ReportItems!SummeTablix1.Value + ReportItems!SummeTablix2.Value

Die hier verwendete ReportItems Collection enthält alle TextBoxen einer Berichtsdatei. Allerdings ist sie an der grafischen Oberfläche nicht sichtbar. Sie müssen einfach wissen, dass es diese Collection gibt und dann können Sie diese in einer Expression eintippen. Lassen Sie sich nicht irritieren - erst nachdem Sie das Ausrufezeichen nach dem Wort "ReportItems" eingegeben haben, erscheint die Drop-Down Liste als Eingabeunterstützung und bietet Ihnen die Namen aller TextBoxen in diesem Bericht zur Auswahl an. Dies ist der Punkt, wo sich die sprechenden Namen der betreffenden TextBoxen als nützlich erweisen.

Erst nach Eingabe des Ausrufezeichens hinter dem Wort ReportItems nimmt die Eingabehilfe ihre Arbeit auf

Wenn sie diese Hürde genommen haben, ist es ein Leichtes den Ausdruck vollständig einzugeben.

Noch ein Beispiel

Sie möchten in einer Tabelle Verhältniszahlen berechnen? Mit ReportItems ist das kein Problem mehr. Nehmen wir folgende Anforderung als Beispiel: Neben dem Umsatz eines Jahres soll sein prozentualer Anteil am Umsatz aller Jahre angezeigt werden.

Der "Sales Amount" für das Jahr 2005 entspricht 20% des "Sales Amount" über alle Jahre

Der Ausdruck in der Spalte "% Umsatz" ist der Umsatz eines Jahres geteilt durch die Summe des Umsatzes über alle Jahre:

=ReportItems!SalesAmount1.Value / ReportItems!SummeTablix1.Value

ReportItems in Kopf- und Fußzeilen

Noch ein schöner Anwendungsfall ist der Einsatz von ReportItems in Kopf- oder Fußzeilen eines Berichts. Nehmen wir an, in der Kopfzeile soll das erste und das letzte Jahr angezeigt werden, das auf der jeweiligen Seite zu sehen ist. Um das besser demonstrieren zu können, habe ich meinen Beispiel-Bericht so verändert, dass nur noch maximal 3 Jahre auf einer Seite dargestellt werden. (Hierfür habe ich einfach in der Eigenschaft des Berichts "InteractiveSize" die Höhe auf 3 Zentimeter reduziert.)

In der Kopfzeile werden die erste und die letzte Jahreszahl auf dieser Seite angezeigt
Mit Hilfe der Aggregatfunktionen First() und Last() können Sie das erste Jahr und das letzte Jahr in der Spalte "OrderYear" ermitteln. Jedoch gibt es noch eine kleine Hürde zu nehmen. Denn wenn Sie versuchen, einen Ausdruck wie den folgenden zu verwenden, erhalten Sie eine Fehlermeldung:

="Von " & First(ReportItems!OrderYear.Value) & " bis " & Last(ReportItems!OrderYear.Value)

Die Fehlermeldung besagt, dass Sie in Kopf- und Fußzeilen pro Ausdruck jeweils nur ein ReportItem verwenden dürfen.
Zur Lösung könnten Sie zwei nahe nebeneinander gelegene TextBoxen verwenden. Noch eleganter finde ich allerdings die Verwendung von zwei Platzhaltern in derselben TextBox. Jeder Platzhalter wird über einen eigenen Ausdruck mit Inhalt gefüllt.

Eine TextBox kann mehrere Platzhalter enthalten
Der erste Platzhalter enthält diesen Ausdruck:

="Von " & First(ReportItems!OrderYear.Value) & " bis "

Der zweite Platzhalter enthält diesen Ausdruck:

=Last(ReportItems!OrderYear.Value)

Voilá!

Die offizielle Dokumentation

ReportItems sind natürlich auch in der MSDN dokumentiert, wenn auch etwas abstrakt, wie ich finde. Das entsprechende Kapitel in der MSDN enthält hierzu noch einige interessante Anmerkungen über die interne Arbeitsweise von Reporting Services.

Mittwoch, 7. Januar 2015

Auswahl mehrerer Werte im Bericht anzeigen

Reporting Services bietet die Möglichkeit, dass ein Berichtsparameter mehrere Werte enthalten kann. Im folgenden Beispiel ist das eine Liste von Ländern. Dieser Beitrag soll zeigen, wie Sie die Liste der ausgewählten Länder ganz einfach als Text im Bericht anzeigen können (im folgenden Bild grün hinterlegt).

Dieser einfache Bericht zeigt die Umsätze der ausgewählten Länder
 

Das sind die Schritte zur Lösung

Zunächst einmal braucht es einen Berichtsparameter, bei dem die Eigenschaft "allow multiple values" gesetzt ist.

Das hat zur Folge, dass der Parameter dem Anwender in dieser Form angezeigt wird:
 
Um jetzt die ausgewählten Länder im Bericht anzuzeigen, habe ich dem Bericht zwei TextBoxen hinzugefügt: eine mit dem statischen Text "Umsatz für folgende Länder:" und darunter eine TextBox mit einer Expression.


Die Expression nutzt die Funktion Join(). Diese Funktion wandelt den Inhalt eines mehrwertigen Parameters in eine Zeichenkette um. Das zweite Argument dieser Funktion gibt an, durch welche Zeichen die einzelnen Parameterwerte getrennt werden sollen.

Join(Parameters!pCountries.Value, ", ")

Eine Dokumentation der Join() Funktion sowie viele weitere nützliche Informationen über die Verwendung von Berichtsparametern in Expressions finden Sie hier in der MSDN.

Dienstag, 6. Januar 2015

Spaltenüberschriften auf jeder Seite wiederholen

Es ist eine typische Anforderung an einen Bericht, dass die Spaltenüberschriften einer langen Tabelle sich auf jeder Seite wiederholen. Dafür bietet Reporting Services eine scheinbar einfach zu verwendende Eigenschaft, die nach einem Rechtsklick auf die Tabelle und Auswahl von "Tablix Properties" zu sehen ist. Sie heißt "Column Headers" und bietet zwei Checkboxen. Die erste dient zum Wiederholen der Spaltenüberschriften auf jeder Seite und die zweite blendet die Spaltenüberschriften auch dann am oberen Bildrand ein, wenn Sie eine lange Seite im Browser herunterscrollen.

Diese Option hat bei Tabellen keine Auswirkung
Allerdings hat diese Eigenschaft bei Tabellen einen entscheidenden Nachteil: Sie funktioniert nicht. Die Spaltenüberschriften werden NICHT wiederholt, unabhängig davon, ob Sie den Haken setzen oder nicht.

Mit einer Matrix geht's

So ganz wirkungslos sind diese Checkboxen allerdings nicht. Wenn Sie mit einer Matrix anstelle einer Tabelle arbeiten, dann werden die Spaltenüberschriften sehr wohl wiederholt.


Bei einer Matrix werden die Spaltenüberschriften wiederholt
 
Was ist hier anders? Die Matrix zeichnet sich ja dadurch aus, dass die Anzahl der Spalten von den Daten im Dataset bestimmt wird. Im Beispiel gibt es Daten für die Jahre 2005 bis 2008. Gäbe es darüber hinaus noch Daten für das Jahr 2009, würde der Matrix automatisch eine entsprechende Spalte hinzugefügt. Man könnte auch sagen, dass bei der Matrix die Spalten dynamisch sind. Die Eigenschaft "Repeat header columns on each page" bezieht sich also auf dynamische Spalten.

Die Lösung für Tabellen

In einer Tabelle hingegen sind die Spalten statisch. Zur Entwurfszeit legen Sie fest, welche Spalten der Tabelle im Bericht angezeigt werden sollen. Und für statische Spalten gilt die Eigenschaft "Repeat header columns on each page" eben nicht.
Die Lösung für statische Spalten ist leider nicht so einfach, aber dafür zeigt sie uns tiefer liegende Eigenarten von Reporting Services. Es wird also spannend.
Schauen wir uns zunächst das Problem genauer an. Dazu habe ich einen Bericht erstellt, der eine Tabelle mit Umsatzzahlen pro Monat darstellt. Jedes Jahr beginnt auf einer neuen Seite. Die statischen Spaltenüberschriften (Order Year, Order Month und Sales Amount) werden auf der ersten Seite angezeigt, aber auf den Folgeseiten nicht mehr.
 
Bei einer Tabelle werden die statischen Spaltenüberschriften nicht wiederholt
 
Um die Eigenschaften der statischen Spaltenüberschriften zu sehen, brauchen Sie das wohl am besten versteckte Bedienelement der Visual Studio Oberfläche: rechts unten, im Bereich der Gruppenkonfiguration, finden Sie bei genauem Hinsehen einen kleinen Pfeil.
Dieser unscheinbare Pfeil (rot umrandet) ist der Schlüssel zur Lösung
Nach Klicken auf den Pfeil können Sie den "Advanced Mode" einschalten. Diese Betriebsart stellt in den beiden Fenstern der Gruppenkonfiguration (Row Groups und Column Groups) auch die statischen Elemente dar.

Nach Anklicken eines "Static" Eintrags wird das entsprechende Feld in der Tabelle dick umrandet
Was Sie jetzt noch brauchen, ist nach dem Anklicken des ersten "Static" Elements in der Row Group das "Eigenschaften" Fenster, um die Eigenschaften dieses statischen Elements zu sehen. Falls das Fenster nicht schon in Visual Studio angezeigt wird, können Sie es über den Menüpunkt "Ansicht" - "Eigenschaftenfenster" oder mit der Taste [F4] einblenden. Wenn Sie die Eigenschaft "KeepWithGroup" auf "After" einstellen und die Eigenschaft "RepeatOnNewPage" auf "True", dann erreichen Sie den gewünschten Effekt.

Die Eigenschaften KeepWithGroup und RepeatOnNewPage der statischen Spaltenüberschrift führen zur Lösung
Interessanterweise funktioniert das nur dann, wenn Sie diese Einstellung bei der ersten statischen Spaltenüberschrift durchführen.

Spaltenüberschriften beim Scrollen immer anzeigen

Am Anfang dieses Beitrags hatte ich noch eine weitere Eigenschaft erwähnt, die bei dynamischen Spaltenüberschriften möglich ist: "Keep header visible while scrolling". Auch bei statischen Überschriften können Sie das konfigurieren, allerdings heißt die entsprechende Eigenschaft im Eigenschaften-Fenster "FixedData".

Die (gelb hinterlegten) Spaltenüberschriften bleiben auch beim Scrollen am oberen Bildrand sichtbar
Übrigens finden Sie eine Beschreibung dieses Verhaltens auch in der MSDN Dokumentation. Allerdings in einer Form, die für mich nicht so offensichtlich war. Ich musste mich einige Zeit mit diesem Thema beschäftigen, bevor mir die Hintergründe klar wurden. Von daher hoffe ich, dass dieser Beitrag Ihnen das Arbeiten mit statischen Spaltenüberschriften in Reporting Services etwas einfacher macht.