[gelöst] Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 13:03

Heyho,

ich möchte einen alten ClassicReport in ein entsprechendes Layout überführen und bin komme an einer Stelle nicht so richtig weiter.

Im alten ClassicReport gibt es ein Array welches die Lieferanschrift enthält. Für jedes Arrayelement wurde eine Body-Section angelegt, welche nur dann gedruckt wird, wenn das entsprechende Arrayelement nicht leer ist (siehe Screenshot). Sind also nur 4 von 8 Elementen gefüllt, so wird der Platz für die leeren Elemente eingespart.

ClassicReport.png


Im Layout wird das mit einem Tablix umgesetzt. Allerdings habe ich hier den Effekt, dass der Platz für die leeren Elemente trotzdem verbraucht wird, im gedruckten Report also mitunter eine größere Lücke zu sehen ist. Wie kann ich das Konstrukt aus dem ClassicReport hier nachbauen bzw. kann ich das überhaupt nachbauen? Oder muss ich damit leben, dass der Platz für die leeren Arrayelemente eben trotzdem verbraucht wird?

FG
Thomas
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von ThomasFerstl am 15. März 2016 16:23, insgesamt 1-mal geändert.

Re: Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 13:31

Ich würde mir einen String mit Zeilenumbrüchen auf der NAV-Seite zusammenstellen. Der wird dann ja in genau so vielen Zeilen gedruckt, wie er enthält.
Ich weiß aber nicht, ob das in 2015 auch möglich ist.

Re: Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 13:39

Hallo,

Ich weiß aber nicht, ob das in 2015 auch möglich ist.


das ist möglich, und damit es einfacher zu übergeben ist würde ich das Feld HTML formatieren. In NAV musst du dann nach jedem Adressfeld, außer dem letzten, ein '<br>' dran hängen.

Wenn du ganz viel Platz sparen möchtest, übergibst du den Text schon im Header, und sparst dir die Lieferadress- Section ganz. :wink:

Gruß Fiddi

Re: Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 15:35

Heyho,

danke für den Tipp, das werde ich gleich einmal versuchen.

fiddi hat geschrieben:Wenn du ganz viel Platz sparen möchtest, übergibst du den Text schon im Header, und sparst dir die Lieferadress- Section ganz.


Ich stehe ein wenig auf dem Schlauch ... wie genau meinst du das?

FG
Thomas

Re: Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 16:30

Hallo,

Ich stehe ein wenig auf dem Schlauch ... wie genau meinst du das?


Bis jetzt hast du einen Integer- Block Total2. Das ShipToAddr hast du aber schon im Kopf gefüllt. dort kannst du auch den Übergabetext füllen.
Code:
ShipToStr:='';
for i:=ARRAYLEN(ShipToAddr) downto 1 DO BEGIN
 if ShipToStr <>'' then
   ShipToStr = ShipToAddr[i]+ '<br>'+ ShipToStr
 ELSE
   ShipToStr := ShipToAddr[i];
END;


ShipToStr kannst jetzt schon im Bereich des Kopfes übergeben, und dir den Total2- Bereich gleich ganz sparen. Im RLDC greifst du dann auf den Variablennamen von ShipToStr zu, und gibst ihn in einem Textfeld aus.

Gruß Fiddi

Re: Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 16:31

McClane hat geschrieben:Ich würde mir einen String mit Zeilenumbrüchen auf der NAV-Seite zusammenstellen.


habe es jetzt ausprobiert und es ist genau das, wonach ich gesucht habe! Besten Dank!

FG
Thomas

Re: Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 16:34

fiddi hat geschrieben:Hallo,

Bis jetzt hast du einen Integer- Block Total2. Das ShipToAddr hast du aber schon im Kopf gefüllt. dort kannst du auch den Übergabetext füllen.
Code:
ShipToStr:='';
for i:=ARRAYLEN(ShipToAddr) downto 1 DO BEGIN
 if ShipToStr <>'' then
   ShipToStr = ShipToAddr[i]+ '<br>'+ ShipToStr
 ELSE
   ShipToStr := ShipToAddr[i];
END;


ShipToStr kannst jetzt schon im Bereich des Kopfes übergeben, und dir den Total2- Bereich gleich ganz sparen. Im RLDC greifst du dann auf den Variablennamen von ShipToStr zu, und gibst ihn in einem Textfeld aus.

Gruß Fiddi


Ach so hast du das gemeint . Ich war jetzt gedanklich bei den GetData und SetData Controls im Layout. :wink:

Re: [gelöst] Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 16:36

Eigentlich ist das Tablix genau richtig dafür.

Normalerweise sollte das Tablix eine Gruppe haben! Diese Gruppe ist dann gruppiert nach der der Number von dem Integer Dataitem, in welchen sich deine ShipToAddr befindet.

In der Tablix setzt du zusätzlich den Filter CStr(Number) > ""

Zusäzlich dazu machst du in den Gruppeneigenschaften (unten in Visual Studio) den erweiterten Modus an und setzt das Kennzeichen "HideIfNoRows an allen Zeilen, die nicht teil deiner Gruppe sind. Das ist normalerweise eine Zeile außerhalb der Gruppe, die als Platzhalter dient, wenn es eine ShipToAddr gibt!

Pro Tablixzeile hinterlegst du nun noch ein HiddenValue mit iif(Fields!ShipToAddr1.Value > "", False, True).

Dann wird auch kein unnötiger Platz reserviert und das Druckbild entspricht dem Classic Client. Die Lösung mit HTML finde ich hier etwas übertrieben. Außerdem wird dadurch auch das DataSet vergrößert, weil der String dann auch für jede Zeile im Beleg übergeben wird. Besser ist es meiner Meinung nach, wenn Daten falls möglich nur einmal pro Beleg an das RDL Layout übergeben werden und das ist in dem Total DataItem so.

Die Logik lässt sich fast 1zu1 im RDLC abbilden und ist dann auch nahe an der Classic Lösung. Letzten endlich gibt es hier aber mehrere Wege nach Rom!

VG
Robert

Re: [gelöst] Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 16:52

Hallo,

Eigentlich ist das Tablix genau richtig dafür.


Das halte ich in diesem Fall für eher subobtimal, da durch die Aktion mit mit dem Total2 für jede Lieferadresszeile ein zusätzlicher RDLC- Datensatz erzeugt wird, was wiederum bei großen Belegdrucken( Sammeldruck ) richtig Ärger bereiten kann.

Das Textfeld in dem die Liefer-An- Adresse ausgegeben wird hat im RDLC- Layout genau 1 Zeile und steht auf CanGrow=yes. Die Lieferadresse wird so genauso groß gedruckt wie benötigt, und verschenkt keinen Platz.

Außerdem funktioniert das mit dem "iif(Fields!ShipToAddr1.Value > "", False, True)" im Hidden nicht, wenn zwischen Adresse und Ort eine Leerzeile in der Adresse enthalten ist. Deshalb arbeite ich die ShipToAddr auch rückwärts ab :wink:

Gruß Fiddi

Re: [gelöst] Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 18:49

Ich will jetzt nicht darüber streiten. Ich bin hier anderer Meinung.

Grundsätzlich ist das eine Frage vom grundsätzlich Aufbau deines Berichts. Ich halte es für besser, wenn ShipToAddr einmal übertragen wird und die die Datensätze pro Tabelle filtern kann. Das das im Stapeldrcuk Probleme macht, habe ich nie bemerkt. Normalerweise hat jeder Berichte eine große Liste, die alles umschließt und nach der gruppiert wird (Belegart/Belegnr/Kopienr.)

Die Verwendung von HTML in RDL berichten kann beispielsweise auch dazu führen, dass ein Drucker das nicht interpretieren kann. Druckst du das beispielsweise auf einem Nadeldrucker, dann wird der HTML Text pur auf das Blatt Papier gedruckt.

Die Variante dafür eine eigene Tabelle innerhalb meiner "Belegliste" zu erstellen, diese korrekt zu filtern und den Rest über die Sichtbarkeit der Zeilen zu steuern, ist meiner Meinung nach die Variante mit der höchsten Performance.

Das Aufblähen oder Übergeben solcher Information im Kopf und somit auch in allen Belegzeilen halte ich für unnötig.

Bevor wir jetzt aber zu sehr abdriften. Es ist eine Frage von Design Pattern und die Lösung per HTML ist eine Möglichkeit das zu lösen. Trotzdem würde ich nach meinen Erfahrungen davon abraten, da ein Total DataItem für solche separaten Tabellen am Ende des Beleges ideal sind. Aber das ist nur meine Meinung und die musst du ja nicht teilen :)

VG

Re: [gelöst] Reportlayout: Platzsparender Andruck von Arrays

15. März 2016 22:58

Das das im Stapeldrcuk Probleme macht, habe ich nie bemerkt. Normalerweise hat jeder Berichte eine große Liste, die alles umschließt und nach der gruppiert wird (Belegart/Belegnr/Kopienr.)


Das gruppieren ist nicht das Problem, bei einer 150seitigen Rechnung kämpfst du in NAV 2013 (2015 habe jetzt noch nicht getestet) um jeden Datensatz, der nicht erstellt wird,damit das ganze in den Speicher passt. :wink:
Daher erzeuge ich normalerweise für einem Beleg mit einer Position auch nur einen Datensatz für den gesamten Beleg, egal ob mit Liefer-Adresse, oder Belegtexten.

Gruß Fiddi

Re: [gelöst] Reportlayout: Platzsparender Andruck von Arrays

16. März 2016 00:21

Also die Limits kommen von 32 Bit und sind somit erst beim Verwenden des 64 Bit Clients kein Problem mehr (also mit 2016 64 Bit Client). Allerdings spielt dabei die Anzahl der Datensätze im Dataset nur eine geringe Rolle. Es geht hier eher um den Speicher den jedes Feld benötigt. Beispielsweise rennt man relativ schnell gegen eine OutOfMemoryException, wenn man das Logo für den Kopf in jedem Datensatz übergibt.

Nur mal als Beispiel:

DataItem Struktur:

Sales Header
- Feld Nr.
- Feld ShipToAddr als HTML
- Sales Line
-- Feld Zeilennr.

Belegnr, ShipToAddr als HTML, Belegzeilennr.
1000, Möbel Meller <Br> Hans Müller Straße <BR>, 10000
1000, Möbel Meller <Br> Hans Müller Straße <BR>, 20000
1000, Möbel Meller <Br> Hans Müller Straße <BR>, 30000
1000, Möbel Meller <Br> Hans Müller Straße <BR>, 40000
1000, Möbel Meller <Br> Hans Müller Straße <BR>, 50000
1000, Möbel Meller <Br> Hans Müller Straße <BR>, 60000

In diesem Fall übertrage ich die Information 6 mal, wenn ich 6 Belegzeilen habe!

Diese Methode benötigt wesentlich mehr Speicher als:

Sales Header
- Feld Nr.
- Sales Line
-- Feld Zeilennr.
- Total
-- Feld Number
-- Feld ShipToAdd1
-- Feld ShipToAdd2
-- ...

Belegnr, Zeilennr., Number_Total, ShipToAddr1, ShipToAddr2,
1000, 10000, <>, <>, <>
1000, 20000, <>, <>, <>
1000, 30000, <>, <>, <>
1000, 40000, <>, <>, <>
1000, 50000, <>, <>, <>
1000, 60000, <>, <>, <>
1000, <>, 1, Möbel Meller, Hans Müller Straße

In diesem Fall übertrage ich die Information einmal im Kopf und nicht pro Belegzeile zusätzlich.

Das hängt ja aber auch vom Aufbau des Beleges ab! Letzten endlich kann ich nicht beurteilen, was du da bisher für Probleme hattest, allerdings habe ich schon Berichte mit über 500 Seiten pro Aufruf (mit Firmenlogo, QS-Logo, mehreren Tabellen und Co) gedruckt.

Ich verstehe halt nicht, warum du glaubst, dass bei einer Beleg - Belegzeilenverknüpfung es besser ist, eine solche Information pro Belegkopf zu übergeben. Das kostet mehr Speicher, als der weitere Eintrag, es sei denn du überträgst in jedem Eintrag deines Datasets ein extrem großes Feld (wie zum Beispiel das Logo), was dann natürlich stark ins Gewicht fällt. Empty Values (<>) fallen nämlich überhaupt nicht ins Gewicht!

Kannst du mal ein Beispiel anhand eines Datasets geben, wann deine Methodik besser ist? Das kann ich aktuell nicht nachvollziehen.

VG
Robert

Re: [gelöst] Reportlayout: Platzsparender Andruck von Arrays

16. März 2016 13:00

Hallo,

generell gibt es da sicherlich unterschiedliche Vorgehensweisen. Fakt ist aber, das durch die zusätzliche Zeile die Kopfdaten einmal zusätzlich übertragen werden (sagt zumindest der XML-Export der Berichtsvorschau).
Außerdem ist, soviel ich weiß, der RDLC- Dataset ein XML-Datensatz, der auch wenn ein Feld keine Daten enthält, in seiner Sektion zumindest den Feldnamen überträgt. Außerdem verursacht jedes übergebene Feld i.d.r. etwa das dreifache an Platzbedarf (Blobs und lange Texte ausgenommen) durch die XML-Kodierung.

Wem der Text zu lang ist, kann Ihn auch nach der ersten Übergabe (also in der zweiten Belegzeile) löschen, dann ist das Feld auch leer. Und was dann noch mehr Platz verbraucht, hängt dann tatsächlich von der Anzahl der Belegzeilen ab. :wink:

Gruß Fiddi