Hallo zusammen,
heute möchte ich ein erklären, wie ich den Übertrag in RDLC löse. Wer sich vorher nochmal einlesen möchte, kann sich hier die vorherigen Beiträge ansehen:
- RDLC für NAV Entwickler #1 – Allgemeine Informationen & das Dataset
- RDLC für NAV Entwickler #2 – Grundlagen des Layouts – Teil 1 „Der Kopf“
- RDLC für NAV Entwickler #3 – Grundlagen des Layouts – Teil 2 „Der Textkörper“
- RDLC für NAV Entwickler #4 – Kopieren von Berichten / Layouts
- RDLC für NAV Entwickler #5 – RDLC Belegdesign – Grundlagen & unterschiedliche Kopfgröße
Folgende Restriktionen sollten vorher bekannt sein:
- Der Übertrag kann nur in der Kopfzeile und/oder in der Fußzeile angezeigt werden.
- Der Übertrag kann sich nur auf eine Textbox beziehen. Werden mehrere Layoutzeilen in einer Verkaufsrechnung benötigt (beispielsweise eine Zeile für Artikel und eine Zeile für Sachkonten), wird ein Workaround benötigt. Wie das gelöst werden kann, wird hier nicht detailliert behandelt. Evtl. erkläre ich das am Beispiel der Mahnung in einem anderen Beitrag (kleiner Tipp: Arbeitet nicht mit zwei Zeilen, sondern mit einer Zeile. Verbindet alle Textboxen (außer dem Zeilenbetrag) miteinander und klickt dann Rechtsklick “Einfügen” -> “Rechteck”. In dem Rechteck bildet ihr dann mit zwei separaten Rechtecken und entsprechenden Sichtbarkeiten die unterschiedlichen Layouts für Artikel / Sachkonten ab. Das hat den Vorteil, dass ihr dann nur eine Textbox für den Zeilenbetrag habt und über diesen summieren könnt. In diesem Fall funktioniert auch die in diesem Beitrag beschriebene Logik.).
- Der Übertrag muss manuell mit eigenem Programmcode gebildet werden. Es gibt keine integrierte Funktion in Visual Studio, die uns eine Übertragsfunktion ermöglicht (bei der Seitennummer gibt es beispielsweise die Eigenschaft “ResetPageNo” an der Gruppe).
Damit ihr nachvollziehen könnt, was genau ändere, nutze ich als Basis benutze den Beispielbeleg aus meinem letzten Beitrag zum Thema RDLC: 160312_RobertsVKRechnung
Diesen Bericht habe ich in eine Dynamics NAV 2018 Datenbank eingespielt und dann in Visual Studio 2017 (Ansicht + Layout) geöffnet. Dafür benötigt ihr die Visual Studio 2017 Professional Version oder Visual Studio 2017 Community Edition (https://www.visualstudio.com/de/downloads/). Bitte informiert euch über die Lizenzbedingung der Community Edition, bevor ihr diese benutzt. Zusätzlich benötigt ihr die Erweiterungen “Microsoft Rdlc Report Designer for Visual Studio” (https://marketplace.visualstudio.com/items?itemName=ProBITools.MicrosoftRdlcReportDesignerforVisualStudio-18001). Nach einen Neustart des Computers, solltet ihr RDLC Belege wieder ordnungsgemäß mit Visual Studio öffnen können. Ohne die Erweiterung kann Visual Studio das Layout nicht laden und ihr bekommt nur eine XML angezeigt.
So sieht das Layout aus, mit dem wir starten:
Bevor wir beginnen, sollten wir zuerst zusammenfassen, welche Anforderungen wir erfüllen müssen.
- Der Übertrag darf im Kopf nur gedruckt werden, wenn auf der vorherigen Seite bereits Zeilen gedruckt wurden und die Gesamtsumme auf der vorherigen Seite noch nicht gedruckt wurde.
- Der Übertrag darf im Fuß nur zu sehen sein, wenn die Gesamtsumme nicht auf der aktuellen Seite gedruckt wurde.
- Beim Stapeldruck mehrerer Verkaufsrechnungen muss der Übertrag zurückgesetzt werden.
Auf die Summenlogik gehe ich hier nicht weiter ein. Falls das von Interesse ist, kann das in den Standardbelegen nachgeschaut werden. Für unser Beispiel und zur Erläuterung füge ich eine einfache Summenzeile in unserem Layout ein. Das ist keine Empfehlung, sondern ausschließlich exemplarisch gedacht. Somit sollte die Positionierung von Elementen klar erkennbar und auch auf andere Belege anwendbar sein.
In der Textbox außerhalb der Gruppe und unterhalb des Zeilenbetrags ergänze ich den Ausdruck “=Sum(Fields!LineAmount_Line.Value)”. Die Formatierung ändere ich auf Fett und ergänze in der Textbox links daneben den Text “Summe”. Zusätzlich entferne ich den leeren Platzhalter.
- Summenzeile hinzufügen:
- Ausdruck hinterlegen:
- Platzhalter löschen und Caption “Summe” ergänzen:
- Zum Druck von Textzeilen ergänze ich die Funktion “BlankZero” in den Feldern Menge, Verkaufspreis und Betrag:
- Im Feld “Betrag” darf dies nicht gemacht werden. Mit der Funktion “BlankZero” wird aus einer Null ein Leerzeichen. Ein Leerzeichen kann nicht summiert werden, was aber dringend für den Übertrag notwendig ist. Daher ändere ich die Schriftfarbe auf weiß, wenn der Betrag null ist (Ausdruck: =iif(Fields!LineAmount_Line.Value = 0, “White”, “Black”)).
Im heutigen Beispiel buche ich mir eine Verkaufsrechnungen mit genug Zeilen in meine Demodatenbank. Im Druck sieht das nun so aus:
Nun ergänzen wir die Summenlogik. Dafür arbeite ich mit VB Code. Diesen können wir öffnen, indem wir die Berichtseigenschaften öffnen.
Anschließend können wir folgenden Code ergänzen:
Shared RunningTotals As New System.Collections.Hashtable Shared LastPage as boolean Shared TransHeaderValue as boolean Public Function StartPage() as boolean LastPage = false return LastPage End Function Public Function SetLastPage() as boolean LastPage = true return LastPage End Function Public Function GetLastPage() as boolean return LastPage End Function Public Function GetRunningTotal(ByVal CurrentPageNumber) Return IIF(CurrentPageNumber > 0, RunningTotals(CurrentPageNumber), 0) End Function Public Function SetRunningTotal(ByVal CurrentPageTotal, ByVal CurrentPageNumber) RunningTotals(CurrentPageNumber) = CurrentPageTotal + GetRunningTotal(CurrentPageNumber - 1) Return RunningTotals(CurrentPageNumber) End Function Public Function SetTransHeader(ByVal Value) as boolean TransHeaderValue = Value Return TransHeaderValue End Function Public Function GetTransHeader() as boolean Return TransHeaderValue End Function
Damit sind die Vorbereitungen abgeschlossen. Hier eine kurze Erläuterung, wozu die Funktionen dienen:
- StartPage: Setzt die boolsche Variable “LastPage” zurück. Erforderlich, damit im Stapeldruck der Übertrag nicht auf der ersten Seite des nächsten Beleges gedruckt wird.
- SetLastPage: Setzt eine boolsche Variable “LastPage”. Die Funktion muss aufgerufen werden, nachdem die Summe gedruckt wurde. Die boolsche Variable gibt uns an, wie lange wir den Übertrag drucken müssen. Solange die Variable nicht True ist, drucken wir den Übertrag.
- GetLastPage: Ruft die Variable “LastPage” ab.
- GetRunningTotal: Ruft den aktuellen Übertrag für eine spezifische Seite ab.
- SetRunningTotal: Setzt den Übertrag.
- SetTransHeader: Setzt ein Marker. Wird im Footer gesetzt (notwendig wegen Renderlogik von RDL – Zuerst wird der Textkörper aufgebaut und danach der Kopf und der Fuß angedockt).
- GetTransHeader: Ruft den Marker ab um zu prüfen, ob der Übertrag gedruckt werden soll oder nicht.
Die Funktionen müssen nun im Layout aufgerufen werden.
Beginnen wir mit der Funktion “StartPage“. Folgendes wird dafür getan:
- Neue Tabelle “Table_SetFirstPage” ohne Gruppe im Rechteck “HeaderFirstPage_2” einfügen und mit nur einer Textbox “StartPage” erstellen.
- In der Textbox “Startpage” den Ausdruck “=Code.StartPage()” hinterlegen.
- Die Textbox “Startpage” auf Hidden “True” und die Hintergrundfarbe auf Rot (zeigt besser, dass es sich um ein rein funktionales Element handelt) setzen.
Wichtig ist hierbei folgendes:
- Die Funktion “StartPage” muss garantiert auf der ersten Seite ausgeführt werden.
Als nächstes deklarieren wir das Ende, also ab wenn der Übertrag nicht mehr gedruckt werden soll. Das machen wir mit der Funktion “SetLastPage“. Diese platzieren wir in einer Tabelle nach der Summe.
- Neue Tabelle “Table_SetLastPage” ohne Gruppe unter der Summe einfügen (innerhalb des Rechtecks “DocumentContent”) und mit nur einer Textbox “SetLastPage” erstellen.
- In der Textbox “SetLastPage” den Ausdruck “=Code.SetLastPage()” hinterlegen.
- Die Textbox “Startpage” auf Hidden “True” und die Hintergrundfarbe auf Rot setzen.
Dabei muss berücksichtigt werden, dass sich das Element immer direkt hinter der Summe befindet.
Nun benötigen wir noch ein Element für die Funktion “SetTransHeader“, welches beim Rendern der Fußzeile erkennt, ob die letzte Seite des Beleges bereits gedruckt wurde oder nicht. Dieses Element wird nicht ausgeblendet. Damit gibt es nämlich vor allem in älteren Versionen Probleme. Dafür tue ich folgendes:
- Einfügen einer Fußzeile
- Einfügen einer Textbox “Transheader_Marker”
- Einfügen des Ausdruckes “=Code.SetTransHeader(Code.GetLastPage())”
- Setzen der Eigenschaft “CanGrow” auf False
- Platzieren des Elementes in der Fußzeile oben links und verkleinern der Textbox auf Size = “1cm; 0,1cm”
Damit sind die Vorbereitungen getroffen. Wir benötigen nun die Textboxen für den Übertrag. Beginnen wir im Fuß für die Funktion “SetRunningTotal“:
- Einfügen eines Rechteckes “CarryOverContentFooter” in der Fußzeile mit der Eigenschaft “Hidden” = “=IIF((Globals!PageNumber < Globals!TotalPages) AND NOT Code.GetLastPage(), False, True)”.
- Einfügen einer Textbox “CarryOverCaptionFooter” mit dem Ausdruck “Fortsetzung”
- Einfügen einer Textbox “CarryOverAmountFooter” mit dem Ausdruck “=Code.SetRunningTotal(Sum(ReportItems!LineAmount_Line.Value), Globals!PageNumber)” und Format “#,0.00;(#,0.00)”
Nun erstellen wir im Kopf ebenfalls den Bereich für den Übertrag. Da wir zwei Rechtecke haben (eins für Seite 1 und eins für die restlichen Seiten) fügen wir den Übertrag auf dem Rechteck für Seite 2+ (HeaderSecondPage) ein. Damit stellen wir sicher, dass der Übertrag niemals auf der ersten Seite im Kopf gedruckt wird. Enthält euer Berichtslayout nur eine Seite, dann benötigt das Rechteck für den Übertrag im Kopf in der Hidden Eigenschaft auch eine Prüfung auf die Seitennummer (nur drucken, wenn Seite > 1).
- Einfügen eines Rechteckes “CarryOverContentHeader” im Rechteck “HeaderSecondPage” mit der Eigenschaft “Hidden” = “=iif(Code.GetTransHeader() = False, False, True)”.
- Einfügen einer Textbox “CarryOverCaptionHeader” mit dem Ausdruck “Fortsetzung”
- Einfügen einer Textbox “CarryOverAmountHeader” mit dem Ausdruck “=Code.GetRunningTotal(Globals!PageNumber-1)” und Format “#,0.00;(#,0.00)”
Schauen wir uns nun den Druck in der Seitenansicht an:
Solltet ihr mehrere Rechnungen am Stück drucken, so stellt sicher, dass die Seitennummer bei jedem Beleg zurückgesetzt wird. Sofern das sichergestellt ist, ist diese Funktion auch für den Stapeldruck geeignet.
That’s it. Have fun.
Abschließend möchte ich noch sagen, dass es einige Übertragsbeíspiele im Netz gibt. Darunter ist auch eine Option ohne das Element “TransferHeader_Marker” und die entsprechenden Funktionen. Letztlich hängt es auch von der Dynamics NAV Version ab, welche Integration funktioniert. Ich kann dazu nur sagen, dass vor allem in früheren Dynamics NAV Versionen (2009-2013 R2) Probleme mit ausgeblendeten Elementen (mit der Eigenschaft Hidden = True) gab. Meiner Erfahrung nach funktioniert die oben beschriebene Variante in allen Dynamics NAV Versionen (2009 bis 2018) und daher nutze ich diese auch.
Meinen angepassten Bericht findet ihr hier als ZIP (enthält TXT und FOB): 180408_RobertsRechnungÜbertrag
Ich hoffe dies hilft dem ein oder anderem. 🙂
Pingback: RDLC für NAV Entwickler #6 – RDLC Belegdesign – Übertrag - Robert's Dynamics NAV Entwickler Blog - D365 Business Central/NAV - DUG
Pingback: RDLC für NAV Entwickler #6 – RDLC Belegdesign – Übertrag - Robert's Dynamics NAV Entwickler Blog - Dynamics 365 Business Central/NAV User Group - Dynamics User Group