Scripting Zwischensumme am Ende einer Seite und Übertrag auf nächste Seite
Siehe JavaScript und FormCalc Scripting im LiveCycle Designer.
Ein häufig geäußerter Wunsch an die Formularentwickler ist es, wenn die Zwischensumme einer Tabelle am Ende einer Ausgabeseite aufgeführt werden soll.
Das ist technisch nicht einfach zu realisieren, da im Druckprogramm und Kontext diese Information noch nicht zur Verfügung stehen kann. Sie entscheidet sich erst zur Laufzeit der Formularausgabe, bzw. wenn das Formular gerendert ist und daher muss für diese Aufgabenstellung Scripting (JavaScript oder FormCalc) verwendet werden.
Siehe Masterseite, Inhaltsbereich, Inhaltsseite, Ausgabeseite und Paginierung.
Anwendung mit Zwischensumme und Übertrag
In der nachfolgenden Projektanwendung war die Aufgabenstellung am Ende einer Ausgabeseite eine Zwischensumme auszugeben und am Anfang der nächsten Seite ein Übertrag (identisch mit der Zwischensumme der Vorseite).
Für diese Anwendung wurden verschiedene Scriptingtechniken und Funktionen des LiveCycle Designers bezüglich der Tabellenausgabe kombiniert. Es lohnt sich, dieses Zusammenspiel zu verstehen. Dieses Verständnis kann in vielen späteren Aufgabenstellungen bei der Formularentwicklung nützlich sein.
- Darstellung einer Kopfzeile nur auf der ersten Tabellenseite.
- Darstellung einer (anderen) Kopfzeile auf allen Tabellenausgabeseiten mit Ausnahme der ersten Tabellenseite.
- Darstellung einer Fußzeile auf allen Tabellenausgabeseiten mit Ausnahme der letzten Tabellenseite, zur Ausgabe der Zwischensummen der Tabelle.
- Darstellung einer (anderen) Fußzeile nur auf der letzten Tabellenausgabeseite, mit Ausgabe u. a. des Gesamtbetrags der Tabelle nur auf der letzten Tabellenausgabeseite.
- Auslesen in einer Scriptingschleife alle Felder einer Seite und Summierung der Werte einer Spalte mit der Speicherung in einer lokalen Variable, um sie in das Zwischensummenfeld der Tabelle zu übertragen.
- Nutzung einer globalen Variable zur Zwischenspeicherung Zwischensumme und Übertrag auf lokale Variablen/Felder.
Formularausgabe
Auf der ersten Tabellenausgabeseite gibt es noch keinen "Übertrag", aber die "Zwischensumme".
Auf der zweiten Seite und allen nachfolgenden Seiten, auf der die Tabelle ausgegeben wird, wird die Zwischensumme der vorherigen Seite im Kopfbereich der Tabelle als „Übertrag“ angezeigt.
...
Ausnahme die letzte Seite der Tabellendarstellung. Da gibt es zwar noch den Übertrag, aber keine Zwischensumme mehr, sondern die Gesamtsumme der Tabelle.
Globale Variable definieren
Es wird eine globale Variable definiert, mit denen man sehr einfach Werte formularweit speichern kann.
In diesem Fall speichert die Variable den aufsummierten Übertragswert. Während ein Feld den Feldwert in der Eigenschaft „rawValue“ speichert, speichert eine globale Variable den Wert in der Eigenschaft „value“.
Im Menü des LiveCycle Designers „Bearbeiten - Formulareigenschaften“ und hier auf dem Reiter „Variablen“ wird die globale Variable "TransferSum" angelegt. Sie ist initial leer oder könnte den Wert „0“ haben.
Im Hierarchiebaum des LiveCycle Designers wird sie unter „Variablen“ mit dem Namen „TransferSum“ angezeigt.
Kopfzeilen Tabelle definieren (Überschrift und Übertrag)
Hier gibt es 2 Kopfzeilen der Tabelle DOC_AMOUNTS vom Typ Kopfzeile. Einmal "Kopfzeile" und dann "Kopfzeile_ff".
Die zweite Kopfzeile "Kopfzeile_ff" unterscheidet sich von "Kopfzeile" durch die Überschrift „Übertrag“ und den Übertragswert. Dieser Übertrag soll nur auf nachfolgenden Seiten dargestellt werden und nicht auf der ersten Ausgabeseite der Tabelle.
Die Kopfzeilen haben auf der Palette "Objekt" die Registerkarte "Paginierung".
Bei der Kopfzeile „Kopfzeile“ wird nun "Kopfzeile in erster Seite einschließen" markiert, aber nicht "Kopfzeile in aufeinander folgenden Seiten". Diese Kopfzeile wird also nur einmalig auf der Seite ausgegeben, an der die Tabellendarstellung beginnt.
Bei der Kopfzeile "Kopfzeile_ff" ist es genau umgekehrt.
Hier wird "Kopfzeile in erster Seite einschließen" nicht markiert, aber dafür "Kopfzeile in aufeinander folgenden Seiten".
Fußzeilen Tabelle definieren (Zwischensumme und Endbetrag)
Hier gibt es 2 Fußzeilen der Tabelle DOC_AMOUNTS vom Typ Fußzeile. Einmal "Zwischensumme" und dann "Fußzeile".
Diese beiden Fußzeilen werden sehr ähnlich zu den 2 Kopfzeilen entweder am Ende jeder Tabellenseite (mit Ausnahme der letzten Tabellenseite) oder nur auf der letzten Tabellenausgabeseite dargestellt.
Fußzeile "Zwischensumme". Hier wird die Checkbox „Fußzeile in aufeinander folgenden Seiten“ aktiviert.
Fußzeile "Fußzeile" mit Endbeträgen. Nun ist die Checkbox „Fußzeile in letzte Seite einschließen“ aktiviert.
Bei den Endbeträgen ist es nicht nötig mit Scripting zu arbeiten. Diese Daten können bereits im Druckprogramm bestimmt werden und die Felder binden daher auf entsprechende Objekte im Kontext.
$.TEXTE.TXT_TOTAL_AMOUNT $.GS_SUMNET.SUMNET $.GS_SUMNET.SUMBTR $.GS_SUMNET.SUMSKT
Zwischensumme berechnen und ausgeben (Schleife Inhalte Vorseite)
Es wird eine neue Zeile "Zwischensumme" zur Tabelle hinzugefügt vom Typ "Fußzeile".
Entscheidend ist hier v. a. das Feld "Subtotal_NETTOEUR", in dem der Zwischensummenwert dargestellt wird.
In der Zeile gibt es nur einen Text "Zwischensumme" und den Zwischensummenwert.
Im Data-Knoten von DOC_AMOUNTS wird die Tabelle durchlaufen, inklusive dem Feld „WNETT“ (Nettowert von Lastschriften).
Coding
Beim Feld der Zwischensumme „Subtotal_NETTOEUR“ wird nun beim Event "calculate" der Zwischensummenwert mit JavaScript berechnet. Wichtig ist hier nicht das Event „initialize“ zu verwenden, da zu diesem Zeitpunkt die Formularseite noch nicht gerendert wurde und somit nicht bekannt ist, welche Data-Zeilen auf einer Seite ausgegeben werden. Beim Event „calculate“ ist die Formularseite bereits gerendert.
Es werden im Scripting alle Felder der Seite durchlaufen. Aber nur die Feldwerte vom Feld „WNETT“ werden in einer lokalen Variable „total“ summiert durch die If-Bedingung „if (fields.item(i).name == "WNETT")“, und schließlich im eigenen Feld ausgegeben, sowie der globalen Variablen „TransferSum“ zugewiesen.
data.MAIN.BODY.AMOUNTS_TAB.DOC_AMOUNTS.Zwischensumme.Subtotal_NETTOEUR::calculate - (JavaScript, client) //Beim Ereignis Calculate können Werte in Abhängigkeit von anderen Variablen des Formulars gefüllt werden. Das Formular ist fertig gerendert und die Seitenumbrüche sind somit bekannt, bzw. welche Inhalte auf welcher Seite sind. //Der Seiteninhalt der Felder der Vorseite wird einer Variablen „fields“ zugewiesen var fields = xfa.layout.pageContent(xfa.layout.page(this)-1, "field", 0); //Initialisierung der Berechnungsvariablen für die Summe eines Feldes der Seite var total = 0; //Addition der Werte vom Feld WNETT der aktuellen Seite //Schleife über alle Felder der Seite for (var i=0; i <= fields.length-1; i++) { //Abfrage auf das Tabellenfeld WNETT if (fields.item(i).name == "WNETT") { //Die Summe aller Werte vom Tabellenfeld WNETT wird gebildet total = total + fields.item(i).rawValue; } } //Die berechnete Summe der Seite wird addiert mit dem vorhergehenden Übertragswert in der globalen Variablen „TransferSum“. Dessen Wert wird mit „value“ angesprochen this.rawValue = parseFloat(total) + parseFloat(TransferSum.value); //Die ermittelte Summe wird wieder der globalen Variable zugewiesen TransferSum.value = this.rawValue;
Übertrag füllen aus der Zwischensumme
Im Event "calculate" des Übertragfeldes in der Überschrift (bei nachfolgenden Tabellenseiten) wird das Ergebnis der Zwischensumme übernommen.
Das Coding:
data.MAIN.BODY.AMOUNTS_TAB.DOC_AMOUNTS.Kopfzeile_ff.NETTOEUR::calculate - (FormCalc, client) data.MAIN.BODY.AMOUNTS_TAB.DOC_AMOUNTS.Kopfzeile_ff.NETTOEUR = data.MAIN.BODY.AMOUNTS_TAB.DOC_AMOUNTS.Zwischensumme.Subtotal_NETTOEUR
sollte identisch sein mit:
data.MAIN.BODY.AMOUNTS_TAB.DOC_AMOUNTS.Kopfzeile_ff.NETTOEUR::calculate - (FormCalc, client) $.rawValue = data.MAIN.BODY.AMOUNTS_TAB.DOC_AMOUNTS.Zwischensumme.Subtotal_NETTOEUR.rawValue
Funktion parseFloat
Mit der globalen Funktion "parseFloat" wird eine Zeichenkette als Zahl interpretiert, damit die Addition explizit Zahlen addiert und nicht Zeichenketten aneinander fügt.
Siehe https://www.mediaevent.de/javascript/string-zu-zahl.html.
Siehe Scripting String-Operationen.
Zugriff auf andere Seiten als aktuelle Seite
Es kann nicht nur auf die aktuelle Seite zugegriffen werden im Coding, sondern z. B. auch auf die Vorseite (in Bezug zur aktuell ausgegebenen Seite).
Dies ist häufig sinnvoll, da man sich nach einem Seitenwechsel für die Inhalte der Vorseite interessiert.
xfa.layout.page(this)-1
Zwei und mehr Übertragsfelder im Event „calculate“
- In einem anderen Kundenformular war die Anforderung 3 Übertragssummen am Ende einer Seite anzuzeigen. Bruttobetrag, Nettobetrag und Steuerbetrag.
- Dies hat sich als schwieriger herausgestellt als gedacht. Sofern die Übertragsfelder auf jeder Übertragsseite erneut den kompletten Inhalt des Formulars (bis zur Vorseite) einlesen, hat das Coding die korrekten Ergebnisse gebracht, aber bei großen Ausgabedateien wurde die Geschwindigkeit der Formularausgabe massiv beeinträchtigt - bis hin zum Abbruch der Formularausgabe aufgrund eines Timeouts im ADS bei über 1000 Rechnungspositionen, bzw. ab ca. 35 Ausgabeseiten des Formulars.
- Wenn die Übertragungsfelder globale Variablen nutzen, hatte es den Effekt, das das Coding des einen Übertragfeldes eine Rückwirkung auf das Ergebnis der anderen Übertragfelder hatte. Alle Übertragsfelder auf der ersten Übertragsseite wiesen einen zu hohen Wert aus. Die Folgeseiten rechneten (unter Beibehaltung des Folgefehlers) korrekt, aber konnten aufgrund der fehlenhaften Werte auf der ersten Übertragsseite nicht genutzt werden.
- Offensichtlich wurde durch das erneute Einlesen des Seiteninhaltes von jedem Scripting-Code zu oft das Ereignis „calculate“ (auch bei anderen Knoten) ausgelöst.
- Nach hartem Kampf konnte das Problem gelöst werden, indem das JavaScript-Coding nur in einem Übertragsfeld berechnet wurde. Aber es wurden lokale Variablen gefüllt, die in Abhängigkeit von einer der 3 Tabellenwerte (Bruttobetrag, Nettobetrag, Steuerbetrag) abfragen. Zur Addition über mehrere Ausgabeseiten hinweg wurden nun statt globaler Variablen Funktionen genutzt. Die Berechnung der 3 Übertragsfelder erfolgt lediglich in einem Scriptingcode und 3 Funktionen.
- Siehe help.adobe.com: calculate event (EN) und help.adobe.com: Sum in calculation event.
Hier gibt es 3 Übertragsfelder zur Anzeige der Summe vom Nettobetrag (NETWR), vom Mehrwertstseuerbetrag (MWSBK) und vom Bruttobetrag (GROSS).
Bei einem Seitenumbruch, der durch die Ausgabe der Tabelle ausgelöst wird, wird das Teilformular "scr_Item_Fuss" ausgegeben.
Dieses Teilformular "scr_Item_Fuss" wird aber nicht auf der letzten Seiten ausgegeben.
data.BODY.scr_Item_Fuss::ready:form - (JavaScript, both) if (xfa.layout.page(this) == xfa.layout.pageCount()) { this.presence = "hidden"; }
Das Scripting zur Berechnung der Übertragsfelder befindet sich im Feld scr_UebNETWR.
data.BODY.scr_Item_Fuss.Uebertrag.scr_UebNETWR::calculate - (JavaScript, both) var lo_fields = xfa.layout.pageContent(xfa.layout.page(this)-1, "field", 0); var lv_wert_netwr = 0; var lv_wert_mwsbk = 0; var lv_wert_gross = 0; //Addition der Werte vom Feld "NETWR" der aktuellen Seite for (var s=0; s <= lo_fields.length-1; s++) //Schleife über alle Felder der Seite { if (lo_fields.item(s).name == "NETWR") //Abfrage auf Feld für den Nettowert { lv_wert_netwr = lv_wert_netwr + lo_fields.item(s).rawValue; //Summe Werte Feld } if (lo_fields.item(s).name == "MWSBK") //Abfrage auf Feld für den Mehrwertsteuerbetrag { lv_wert_mwsbk = lv_wert_mwsbk + lo_fields.item(s).rawValue; //Summe Werte Feld } if (lo_fields.item(s).name == "GROSS") //Abfrage auf Feld für den Bruttobetrag { lv_wert_gross = lv_wert_gross + lo_fields.item(s).rawValue; //Summe Werte Feld } } //Zuweisung Rückgabewert Funktion an Übertragsfelder Steuerbetrag und Bruttobetrag. scr_UebGROSS.rawValue = Main.FunktionGROSSAdd(lv_wert_gross); scr_UebMWSBK.rawValue = Main.FunktionMWSBKAdd(lv_wert_mwsbk); //Zuweisung Rückgabewert Funktion an Übertragsfeld Nettobetrag. this.rawValue = Main.FunktionNETWRAdd(lv_wert_netwr);
Die Funktionen zur Addition der vorhergehenden Werte vom Nettobetrag, dem Mehrwertsteuerbetrag und dem Bruttobetrag sind im Skriptobjekt "Main", mit den Funktionnamen "FunktionNETWRAdd", "FunktionMWSBKAdd" und "FunktionGROSSAdd".
data.#variables[0].Main - (JavaScript, client) function FunktionNETWRAdd(Parameter1) { //Wenn statische Variable noch nicht definiert ist, initialisiere sie //s. a. https://stackoverflow.com/questions/27509/detecting-an-undefined-object-property if ( typeof counter_netwr == 'undefined' ) { counter_netwr = 0; } //Erhöhe den Gesamtwert um den Wert der jeweiligen Ausgabeseite counter_netwr = counter_netwr + Parameter1; return counter_netwr; //Rückgabeparameter mit Gesamtwert inklusive jeweils letzter Ausgabeseite } function FunktionMWSBKAdd(Parameter1) { //Wenn statische Variable noch nicht definiert ist, initialisiere sie if ( typeof counter_mwsbk == 'undefined' ) { counter_mwsbk = 0; } //Erhöhe den Gesamtwert um den Wert der jeweiligen Ausgabeseite counter_mwsbk = counter_mwsbk + Parameter1; return counter_mwsbk; //Rückgabeparameter mit Gesamtwert inklusive jeweils letzter Ausgabeseite } function FunktionGROSSAdd(Parameter1) { //Wenn statische Variable noch nicht definiert ist, initialisiere sie if ( typeof counter_gross == 'undefined' ) { counter_gross = 0; } //Erhöhe den Gesamtwert um den Wert der jeweiligen Ausgabeseite counter_gross = counter_gross + Parameter1; return counter_gross; //Rückgabeparameter mit Gesamtwert inklusive jeweils letzter Ausgabeseite }