Gruppensumme im Gruppenheader drucken
Gruppensumme im Gruppenheader drucken
Diese Methode wird recht häufig verwendet und erfordert die Verwendung eines Skripts, da der Wert einer Gruppensumme erst bekannt ist, nachdem alle Datensätze in der Gruppe verarbeitet wurden. Um die Summe im Gruppenheader anzuzeigen (d.h. bevor die Gruppe im Bericht ausgegeben wird), wird der folgende Algorithmus verwendet:
- Aktivieren Sie die Zwei-Durchläufe-Bericht-Option (“Bericht > Optionen...” Menüpunkt)
- Im ersten Durchlauf die Summen für jede Gruppe berechnen und in einem Array speichern
- Im zweiten Durchlauf die Werte aus dem Array extrahieren und im Gruppenheader anzeigen
Zeigen wir zwei Methoden zur Durchführung dieser Aufgabe. Zuerst erstellen Sie einen Klon des Berichts '147 - Bestand zum Datum nach Lagern und Artikeln' der im Programmmenü 'Waren | Bestandsberichte | Aktueller Bestand' zu finden ist.
Aktivieren Sie den Doppelpass in den Berichtseinstellungen (“Bericht > Optionen...” Menüpunkt). Im Editor der “GroupHeader”-Band, geben Sie die tbIzpisTrenZaloga."acWarehouse" Datenfeld ein. Verbinden Sie das Datenband mit der “Gruppe” Datenquelle und arrangieren Sie einige Objekte wie folgt:

Um die Summe anzuzeigen, verwenden wir die farbigen Objekte im Design. Wir haben sie "Sum1" und "Sum2" genannt.
Im Objekt mit dem Namen "Sum1" wird das Ergebnis der ersten Methode angezeigt und imObjekt mit dem Namen "Sum2" wird das Ergebnis der zweiten Methode angezeigt.
Die erste Methode.
Wir verwenden die Klasse "TStringList" als Array zur Speicherung der Summen - wir speichern die numerischen Werte als Strings. Der erste Eintrag in der StringList entspricht der Summe der ersten Gruppe, und so weiter. Eine Ganzzahlvariable (die wir nach dem Drucken jeder Gruppe inkrementieren) wird verwendet, um die Indexnummer der Gruppe zu berechnen.
Unser Skript sieht also folgendermaßen aus:
var
Liste: TStringList;
i: Integer;
procedure OnStartReport(Sender: TfrxComponent);
begin
Liste := TStringList.Create;
end;
procedure OnStopReport(Sender: TfrxComponent);
begin
Liste.Free;
end;
procedure Page1OnBeforePrint(Sender: TfrxComponent);
begin
i := 0;
end;
procedure hSkladOnBeforePrint(Sender: TfrxComponent);
begin
if Engine.FinalPass then
Sum1.Text := 'Summe: ' + Liste[i];
end;
procedure fSkladOnBeforePrint(Sender: TfrxComponent);
begin
if not Engine.FinalPass then
Liste.Add(FormatFloat('#,##0.00',SUM(<tbIzpisTrenZaloga."ZALVREDNOST">, Detail)));
Inc(i);
end;
begin
end.
Die Prozedurnamen im Skript zeigen, welche Ereignisse wir verwendet haben. Sie sind: “Bericht.OnStartReport”, “Bericht.OnStopReport”, "Page1.OnBeforePrint", "hSkladHeader1.OnBeforePrint" und "fSklad.OnBeforePrint". Die ersten beiden Ereignisse werden zu Beginn und am Ende des Berichts aufgerufen. Um Handler für diese beiden Ereignisse zu erstellen, wählen Sie das “Bericht”-Objekt in der Dropdown-Liste des Objektinspektors aus, und seine Eigenschaften erscheinen im Objektinspektor. Wechseln Sie dann zur Registerkarte “Ereignisse” des Objektinspektors und erstellen Sie die Handler.
Warum haben wir die “Liste”-Variable nicht in der Hauptprozedur des Skripts erstellt? Wir haben sie im "OnStartReport"-Ereignis erstellt, da dynamisch erstellte Variablen nach Abschluss des Berichts zerstört werden sollten. Es ist logisch, dynamische Variablen im “OnStartReport”-Ereignis zu erstellen und sie im “OnStopReport”-Ereignis zu zerstören. In anderen Fällen (wenn der Speicher nach Abschluss des Skripts nicht freigegeben werden muss) kann man die Hauptprozedur des Skripts zur Initialisierung von Variablen verwenden.
Die Erstellung und Zerstörung der “Liste”-Variable ist unkompliziert. Jetzt sehen wir, wie das Skript funktioniert. Zu Beginn der Seite wird der Zähler für die aktuelle Gruppe (die Variable “i”) auf null zurückgesetzt und nach dem Drucken jeder Gruppe inkrementiert (im “GroupFooter1.OnBeforePrint”-Ereignis). Die berechnete Summe wird in diesem Ereignis zur “Liste” hinzugefügt, bevor der Zähler inkrementiert wird. Das “GroupHeader1.OnBeforePrint”-Ereignis tut während des ersten Durchlaufs nichts (Wenn “Engine.FinalPass” Bedingung), aber während des zweiten Durchlaufs (wenn “Liste” mit Werten gefüllt ist) wird die Summe, die der aktuellen Gruppe entspricht, aus der “Liste” abgerufen und im "Sum1"-Objekt ausgegeben, um die Summe im Gruppenheader anzuzeigen. Im fertigen Bericht erscheint es wie folgt:
Dieser Algorithmus ist recht unkompliziert. Er kann jedoch vereinfacht werden.
Die zweite Methode.
Wir verwenden die Sammlung von Berichtvariablen als Array zur Speicherung der Gruppensummen. Denken Sie daran, dass Berichtvariablen über die Funktionen “Get” und “Set” zugegriffen werden. Die Verwendung dieser Funktionen erspart uns auch, diese Variablen explizit zu erstellen und zu zerstören. Unser Skript sieht folgendermaßen aus:
procedure hSkladOnBeforePrint(Sender: TfrxComponent);
begin
if Engine.FinalPass then
Sum2.Text := 'Summe: ' + FormatFloat('#,##0.00', Get(<tbIzpisTrenZaloga."acWarehouse">));
end;
procedure GroupFooter1OnBeforePrint(Sender: TfrxComponent);
begin
Set(<tbIzpisTrenZaloga."acWarehouse">, SUM(<tbIzpisTrenZaloga."ZALVREDNOST">, Detail));
end;
begin
end.
Wie Sie sehen können, ist dieses Skript etwas einfacher. Der Code im “fSklad.OnBeforePrint”-Handler setzt den Wert einer Variablen, deren Name vom Kundennummer abgeleitet ist (oder ein anderer Identifikator, der den Kunden eindeutig identifiziert, könnte verwendet werden, zum Beispiel <tbIzpisTrenZaloga."acWarehouse">). Wenn es keine Variable mit diesem Namen bereits gibt, erstellt das Skript sie automatisch; andernfalls, wenn sie existiert, wird ihr Wert aktualisiert. Im “hSklad.OnBeforePrint”-Handler wird der Wert der entsprechenden Variablen abgerufen.
Der fertige Bericht erscheint wie folgt:

Die zweite Methode funktioniert nicht für mehrere Gruppierungen und für die Anzeige mehrerer Summen von Feldern im Gruppenheader.
Ein Beispiel für mehrere Summen von Feldern im Header der Gruppe ist im Bericht '32A - Späte Zahlungen - Nach verknüpften Dokumenten', der im Programmmenü 'Finanzen | Berichte | Späte Zahlungen' zu finden ist.