RDLC für NAV Entwickler #5 – RDLC Belegdesign – Grundlagen & unterschiedliche Kopfgrößen

Von | 12. März 2016

Hey Leute,

nachdem wir uns mit den Einstiegs-Themen zum Thema RDLC beschäftigt haben:

möchte ich nun auf Belegdesign eingehen und wie Belege aus meinen Erfahrungen gestaltet werden müssen. Dabei meine ich mit Belegen, alle Berichte, die eine Kopf-/Zeilenstruktur besitzen. Beispiele sind Einkaufs- und Verkaufsbelege (Verkaufsrechnung, Einkaufsbestellung, …). In meinen heutigen Beispiel gehe ich daher auf ein paar Grundlagen ein und zeige wie man unterschiedliche Kopfgrößen in RDLC realisieren kann!

Ich werde auf verschiedene Dinge eingehen, allerdings keine kompletten Belege zur Verfügung stellen. Wenn ich also nicht auf den CopyLoop eingehe oder andere Dinge (Mehrsprachigkeit, unterschiedliche Währungen, Übertragen von Textkonstanten) eingehe, dann bitte ich dies zu entschuldigen. Falls es dort Bedarf gibt, lasst es mich wissen, dann schauen wir uns das noch in einem späteren Beitrag an.

Zu allererst benötigen wir eine Ausgangsbasis. Dafür habe ich einen neuen Bericht erstellt und ein grundlegendes Dataset erstellt.

RDLC5_1_Dataset_CompInfo

Wichtig ist hierbei, dass ich das Bild in einem separaten DataItem übergebe. Das mache ich natürlich aus einem bestimmten Grund:

  1. Das Bild ist normalerweise auf jedem Ausdruck gleich. Würde ich es im “Sales Invoice Header” an das Dataset übergeben, dann sorge ich für ein stark vergrößertes Dataset. Das kann im schlimmsten Fall zu einer “OutofMemoryException” führen. Daher immer dafür sorgen, dass das Bild nur einmal übergeben wird!
  2. Da die Firmendaten und der Sales Invoice Header auf der ersten Ebene sind, funktioniert der “SETTABLEVIEW”-Befehl für den Bericht immer noch. Es hat also keine Nachteile.
  3. In Visual Studio müssen wir dann aber auch berücksichtigen, dass wir diesen ersten Eintrag im Dataset “wegfiltern”.

Darüber hinaus gibt es von Microsoft selbst auch ein paar Tipps zur Performance (blogs.msdn.microsoft.com – RDLC Performance Optimization Tips).

Sollte man beim Erstellen und Testen von Berichten auf leere Seiten stoßen, dann kann ich nur diesen Blog von Natalie empfehlen: nataliesnav.de – Leere Seiten im NAV Report

Des Weiteren habe ich folgenden Code eingefügt:

RDLC5_2_Code

mit folgenden Variablen:

RDLC5_3_Variablen

Mehr brauchen wir im ersten Schritt nicht. Nun werde ich Schritt für Schritt erläutern, wie das Layout aufgebaut werden muss. In Visual Studio stelle ich natürlich wieder das Format auf A4 Hochformat und auf Zentimeter:

RDLC5_4_Berichtseigenschaft

Wenn wir uns nun den Kopf eines Berichtes anschauen, dann müssen wir folgendes akzeptieren. Die Kopfgröße ist immer statisch. Es gibt keine Möglichkeit diese Größe flexibel zu gestalten. Habe ich nun einen Kopf, der 5 cm hoch ist, dann kann ich das auf der nächsten Seite nicht verkleinern:

RDLC5_5_Kopfhöhe

Wir sollten also nicht versuchen, dieses Verhalten zu verändern, da es technisch nicht möglich ist. Aber was ist mit der folgenden Idee?

Warum nicht den Kopf im RDL so gestalten, wie er auf der zweiten, dritten, vierten Seite sein soll. Ich kann doch auch den Textkörper für den großen Kopf der ersten Seite benutzen. 

Die große Frage ist nun, wie soll das Ganze funktionieren? Das werde ich nun Schritt für Schritt erläutern.

RDLC5_6_KopfimTextkörper

Einfügen einer Liste in den Textkörper. Eine Liste dient uns als Tabelle und gleichzeitig ein Rechteck. Der große Vorteil? Ich kann einen Seitenumbruch pro Beleg generieren und kann in meinem Rechteck alles platzieren, was auf einem Beleg gedruckt werden soll. Dafür erstellen wir also eine Liste, gruppieren nach der Nummer des Sales Invoice Header und erzeugen einen Seitenumbruch, wenn sich das Gruppenmerkmal “No.” ändert.

RDLC5_7_ListeDokument

RDLC5_8_ListeGruppierung

RDLC5_9_Seitenumbruch

Zusätzlich setze ich die Seitennummer in RDL zurück, wenn sich der Beleg ändert und setze einen Filter auf die “No.” damit der erste Datensatz ausgeblendet wird.

RDLC5_10_ZurücksetzenSeitennr2

RDLC5_9_2_Filter

Nun erstelle ich einfach einfach einen Kopf für die erste Seite und für die zweite Seite. Alles was auf der ersten Seite nicht in den Kopf passt, packen wir dann in Textkörper. Dafür benutze ich auch SetData / GetData. Diese Funktionen werden benötigt um Daten pro Beleg im Stapeldruck an den Kopf zu übergeben (Im Kopf kann man nämlich nur auf den ersten oder den letzten Eintrag im Dataset zugreifen). Das kann man auch hier nachlesen: SetData / GetData – Why it’s required? und hier: MSDN – SetData / GetData

In dem ersten Beitrag zu SetData/GetData sollte man aber die Geschichte mit der VB Funktion “GetGroupPageNumber” vergessen. Mit Dynamics NAV 2013 R2 ist das Feature “ResetPageNumber” (s.o.) verfügbar und man braucht keinen extra Code dafür. Ich benutze die SetData/GetData-Funktionen aus dem MSDN mit einer kleinen Änderung. Wichtig ist meiner Meinung nach dabei, dass man die Aufrufe in die Hidden-Eigenschaft packt und das SetData immer True als Return Value zurückgibt.

So sieht dann mein Kopfbereich aus:

RDLC5_11_Köpfe_Sichtbarkeiten

Ich habe also zwei Rechtecke und habe dort das Bild platziert (erst mal ohne flexible Positionierung) und mit einigen Werten. Ebenfalls blende ich das jeweilige Rechteck je nach der Seitennummer ein. Als Folgeschritt erstelle ich nun den zweiten Teil meines Kopfs auf der ersten Seite im Textkörper.

RDLC5_12_KopfImTextköprerBeispiel

Ich packe noch ein paar Zeilen dazu und sorge für große Platzhalter um eine zweite Seite zu erzwingen:

 

RDLC5_13_Zeilen

Das Ergebnis sieht dann so aus:

Seite 1

RDLC5_14_KopfSeite1

Seite 2

RDLC5_15_Seite2

So nun hat man zwei verschieden große Köpfe auf Seite 1 und den folgenden Seiten. Hier findet ihr wie immer das Objekt: 160312_RobertsVKRechnung

Falls Fragen bestehen, dann schreibt mir einfach einen Kommentar.

 

10 Gedanken zu „RDLC für NAV Entwickler #5 – RDLC Belegdesign – Grundlagen & unterschiedliche Kopfgrößen

  1. Natalie

    Das Bild nicht in jeder DataSet-Zeile zu wiederholen ist in der Tat ein wichtiger Ansatz.
    Man muss dafür aber nicht zwingend ein eigenes DataSet mit gleicher Einückung erstellen – es reicht auch, das Bild in der zweiten DataSet-Zeile mittels CLEAR zu löschen. Und im Report-Layout greift man mittels FIRST nur auf den ersten Datensatz des gesamten DataSets zu.
    So bzw. so ähnlich wird das auch hier beschrieben: http://dynamicsuser.net/blogs/waldo/archive/2012/06/12/nav-2009-rdlc-reporting-working-with-multiple-datasets.aspx

    Antworten
  2. FJS

    Hallo, super Ansatz! Ich hab den Report 206 in NAV2017 entsprechend angepasst und es funktioniert perfekt. Nur ein Problem konnte ich nicht beheben: Sobald ich im Druck mehrere Kopien auswähle, beginnen diese Kopien auch schon in der ersten Seite mit dem verkürzten Kopf. Wie könnte das noch gelöst werden?

    Antworten
    1. Robert Beitragsautor

      Hi,

      eigentlich wird das über die Sichtbarkeiten der beiden Köpfe gesteuert. Du musst die Hidden Eigenschaft des Kopfes (erste Seite) auch auf PageNo > 1 setzen. Also den ersten Kopf immer ausblenden, wenn es nicht die erste Seite ist. Umgekehrt dann für den Kopf der zweiten Seite.

      Nun muss man dafür sorgen, dass die Dokumentgruppe (bei mir Document) nach Belegnr. und Kopienr. gruppiert und die Eigenschaft ResetPageNumber bei der Gruppe aktiviert ist. Die Seitennummer muss bei einer Kopie auch wieder bei 1 anfangen. Das ist oben beschrieben, aber ich gruppiere nicht nach der Kopiennr. Da sollte der Unterschied zu deinem Beleg liegen.

      Antworten
  3. Pingback: RDLC für NAV Entwickler #6 – RDLC Belegdesign – Übertrag - Microsoft Dynamics NAV Community

  4. JU

    Hallo Robert,
    wie kann man das ganze quasi umgekehrt machen, dass ich auf der ersten Seite einen kleineren Header habe als auf der zweiten Seite? Mir wird noch nicht ganz klar wie das gesteuert wird, wann der Header erscheint und wann nicht ?Ich hoffe du kannst mir weiterhelfen.

    Antworten
    1. Robert Beitragsautor

      Du kannst versuchen, den Kopf auf der ersten Seite genauso groß zu machen, wie du ihn für die zweite Seite benötigst. Damit dann keine leere Stelle auf der ersten Seite entsteht, verschiebst du so viele Elemente aus dem Textkörper in den Kopf der ersten Seite. Das geht allerdings nur, wenn das keine Gruppenelemente sind (z.B.: Tabellen). Das geht nur mit statischen Elementen, wie Textboxen. Die Elemente können per Set/GetData in den Kopf übertragen werden (falls notwendig)

      Ansonsten sollte man andere Lösungsansätze suchen (2 Berichte, ohne den Kopfbereich arbeiten und stattdessen Kopfzeilen aus Listen und Tabellen verwendet, …).

      Falls du da mehr Hilfe benötigst, kannst du deine Frage im deutschen NAV Forum msdynamics.de stellen. Da gibt es viel Know-How und dann kann man auch spezifischer auf dein Problem eingehen.

      Antworten
  5. DSE

    Hallo Robert,
    habe Deine Anleitung am Report 206 so nachgestellt und für den Header-1.Seite die Kunden- und Firmen-Anschrift aus dem Header-2.Seite verschoben. Die Detailzeilen habe ich dann so breit gemacht, dass zwei Seiten entstehen.
    Mein Ziel ist es aber, die Header-1.Seite auf allen Seiten erscheinen zu lassen, bis ein bestimmter Trigger gesetzt wird. Erst danach soll nur ein reduzierter Header ausgegeben werden.
    Bei Deinem Beispiel würde ich z.B. nur das Picture als echten Header nehmen, den Rest auf den Seiten 1 – N anzeigen und auf den Seiten N+1 – M den reduzierten Header.
    Geht das und wenn ja, wie?

    Antworten
    1. Robert Beitragsautor

      Mit den statischen Headern ist das meiner Meinung nach nicht möglich. Das von beschriebene Konzept geht immer davon aus, dass der Header auf Seite 1 einmal größer ist, als auf Seite 2. Daher wird der Kopf grundsätzlich so groß gezogen, wie auf Seite 2.

      Ich kenne zwar deine Anforderung nicht im Detail, aber vermutlich würde ich in diesem Fall die Berichte aufteilen. Demnach habe ich einen Bericht mit einem statischen Header und einen zweiten Bericht mit deinem reduzierten Header. Wenn du einen Ausblick gibst, warum du die von dir angesprochene Anforderung brauchst, kann man ggf. nochmal nach Alternativen suchen.

      Experimentell könnte man auch den Kopf komplett in den Textkörper schieben und diesen als Überschrift einer Tabelle verwenden. Dort könnte man die statischen Zeilen mit den Eigenschaften “KeepWithGroup = After” und “RepeatOnNewPage = true” so einstellen, dass die Überschriften auf jeder Seite gedruckt werden. In einem solchen Fall kann man alle Zellen einer Zeile zusammenführen und dann per Rechtsklick ein Rechteck einfügen. Dort kann man sich dann austoben. Wenn man zwei Überschriftszeilen (Rechtecke als Tabellenkopf) macht, kann man die statischen Zeilen auch generisch per Bedingung (Hidden Property) einblenden und ausblenden. Die Tabelle muss dann aber so aufgebaut werden, dass auf die statischen Zeilen eine Gruppe folgt (mehrere angrenzende Gruppen gehen nicht). Die Gruppe kann dann beliebig viele Untergruppen haben. Das bedeutet dann, dass die komplette Tabelle den gesamten Berichtsdruck abdecken muss (wäre aber ggf. ein Versuch wert). Eine Einschränkung gibt es auf jeden Fall: Auf die PageNo kann man im Textkörper nicht zugreifen. Dafür muss man sich dann überlegen, ob die nicht irgendwo im Kopf oder Fuß platziert werden muss.

      Antworten
  6. Waldemar Brakowski

    Moin Robert,
    baue hier gerade einen Report und brauchte genau das. Da habe ich mich direkt daran erinnert, dass du mal einen Beitrag dazu geschrieben hast. Ich lerne immer noch vom Meister 😉

    Danke dafür.

    Grüße
    Waldemar

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert