[ 1 ] [ 2 ]
[ 3 ] [ 4 ] [ 5 ] [
6 ]
Hier ist nun das Ergebnis zu sehen:
Kombinieren mehrerer "REPORT FORM"-Befehle
Aufbauen von Reports mit höherer Komplexität
Was tut man im folgenden Fall:
- Ein Report über den Artikelstamm hat eine Gruppierung nach Artikelgruppen.
- Der Wunsch des Anwenders ist es nun, die einzelnen Zusammenfassungszeilen
für jede Artikelgruppe noch einmal komprimiert im Summary Band aufzulisten.
Lösungsansatz:
- Man erstellt den Report wie gewünscht, aber ohne das Summary Band.
- Nun verwendet man den folgenden fragmentarischen Quellcode, um das Problem
zu lösen:
REPORT FORM xyz
REPORT FORM xyz SUMMARY
- Ggf. kann es notwendig sein, zwei verschiedene Report-Definitionsdateien zu
verwenden. In diesem Fall ist es aber durchaus möglich, die eine
Definitionsdatei mit Hilfe geeigneter FoxPro-Befehle programmatisch aus der
anderen Definitionsdatei zu erzeugen.
Muß man nun noch das Problem lösen, die Seiten des zweiten REPORT-Befehls
fortlaufend zum ersten Report weiter zu numerieren, kann man wie folgt vorgehen:
REPORT FORM xyz
nPageNo = _PageNo
&& Seitenanzahl der ersten Runde speichern
REPORT FORM xyz1 SUMMARY
Damit diese Mechanismus funktioniert, muß man im Bericht xyz1 für die Anzeige
der Seitennummer statt der Systemvariablen"_PageNo" lediglich die Expression
"m.nPageNo -1 + _PageNo" verwenden!
Wenn man diesen Mechanismus etwas ausbaut, kann man Ausdrucke beliebiger
Komplexität bzgl. Verschachtelungen erzeugen.
Zu beachten ist allerdings, daß diese Technologie bestimmten Einschränkungen
unterliegt:
- Solcherart aufgesplittete Reports haben beim Wechsel von einem REPORT-Befehl
zum nächsten zwangsläufig einen Seitenwechsel. Damit ist diese Verfahrensweise
wiederum gut für Formulare geeignet, bei denen ein Detailbereich genau eine
Druckseite umfaßt.
- Außerdem kann man einen solchen Report nicht komplett in einem Preview
anschauen, denn die Preview-Option des Report-Befehls wirkt natürlich nur
auf die aktuell verwendete FRX-Datei.
Drucken bestimmter Seiten auf bestimmte Papier-Arten
Wenn man erreichen will, daß bestimmte Teile eines Reports auf verschiedenen
Papiersorten ausgedruckt werden, kann man wie folgt vorgehen:
- Voraussetzung ist ein Drucker mit mehreren Papierkassetten, welche die
verschiedenen Papiersorten beinhalten.
-
- Auf Betriebssystem-Ebene muß für diesen Drucker für jede Papierkassette ein
Treiber installiert werden, der für die Papierzufuhr jeweils auf eine spezielle
Kassette eingestellt ist.
- Soll nun die erste Seite einer Rechnung auf Kopfbogen und der Rest auf glatt
weißes Papier gedruckt werden, sieht der Quellcode ungefähr so aus:
SET PRINTER TO MyHP4_Tray1
REPORT FORM xyz TO PRINTER RANGE 1,1
SET PRINTER TO MyHP4_Tray2
REPORT FORM xyz TO PRINTER RANGE 2
- In einen solchen Mechanismus kann man zusätzlich oder an Stelle von RANGE
auch die REPORT-Klauseln "[Scope]", "[FOR lExpression1]" und "[WHILE lExpression2]"
mit einbeziehen.
Zweck und Zweckentfremdung der Report Bands
Eigentlicher Zweck der einzelnen Report Bands
Der eigentliche Zweck der einzelnen Report-Bands ist relativ klar definiert:
- Page Header und Page Header für Seitenkopf und -fuß
- Detail Band für die Wiederholung je existierendem Datensatz
- Group Header und Group Footer für Gruppenkopf und -fuß
- Title und Summary für Berichtskopf und Zusammenfassung
Im vorhergehenden Abschnitt wurde beschrieben, wie man eine Report-Ausgabe
auf mehrere REPORT-Befehle aufteilen kann. Mit einer gewissen Vorarbeit in der
Datenaufbereitung in Zusammenhang mit einer bestimmten Zweckentfremdung der
Report Bands ist es allerdings auch möglich, verschiedene Detailbereiche
innerhalb eines Reports zu kombinieren.
Nutzung von Print When für differenzierte Detailbereiche
Das prinzipielle Potential der Print When-Konstruktionen wurde weiter
oben schon erläutert. Wenn man damit allerdings mehrere komplette Detailbereiche
erzeugen und später auch noch pflegen will, muß man einige zusätzliche Aspekte
beachten:
- Ausgangspunkt sei ein Rechnungs-Report, bei dem mit 3 verschiedenen Arten
von Rechnungspositionen operiert werden muß (normale Positionen,
Rabattpositionen, Gutschriften).
- Zu diesem Zweck erzeugt man eine Report-Definition mit einem Detailbereich,
der so hoch ist wie die benötigte Summe der Höhen der 3 verschiedenen
Bereichs-Varianten.
- Dann teilt man den Detailbereich horizontal in die drei entsprechend hohen
Schichten ein und plaziert die zugehörigen Controls in der jeweiligen Schicht.
- Wie weiter oben schon beschrieben, werden alle Controls mit einer Print
When-Expression ausgestattet, die dafür sorgt, das je nach Satzart
immer nur die zu genau einer Schicht gehörenden Controls angezeigt werden.
- Voraussetzung dafür ist natürlich eine entsprechende Kennzeichnung der
einzelnen Datensätze.
- Damit nun die Bereiche der gerade nicht genutzten Controls nicht als weiße
Flecken unberechtigt Platz auf dem Papier beanspruchen, werden alle Controls
außerdem mit der Einstellung "Remove line if blank" versehen. Dadurch
werden die nicht benutzten Teile des Detailbereichs beim Ausdrucken eliminiert.
Datensatzanzahl-abhängiger Gruppenfuß
In der Lösung des weiter oben beschriebenen Problems einer Rechnungsliste mit
rabattsatz-spezifischen Zusammenfassungen wird bzgl. der Rabattsätze von einer
bekannten Anzahl von Rabattsätzen ausgegangen.
Ist die Anzahl der Rabattvarianten allerdings unbestimmt, dann ergibt sich
der Inhalt und die Anzahl der Rabattsatz-Zeilen im Gruppenfuß ausschließlich aus
dem Dateninhalt der Tabelle und kann nicht hartcodiert in der Reportdefinition
hinterlegt werden.
Zur Lösung dieser Aufgabe benötigt man eine gewisse Datenvorbereitung:
SELECT ;
Cust_Id, ;
Order_Dsc AS Rab_Dsc, ;
SUM(
Order_Amt * Order_Dsc / 100) AS Rab_Sum ;
FROM ;
Orders ;
HAVING ;
Rab_Sum > 0
;
GROUP BY ;
Cust_Id, ;
Rab_Dsc ;
INTO ;
CURSOR Rab
SELECT ;
Cust_Id, ;
"1" AS xSort, ;
Order_Id, ;
Order_Amt, ;
Order_Dsc, ;
000 AS Rab_Dsc, ;
NTOM( 0 ) AS Rab_Sum ;
FROM ;
Orders ;
UNION SELECT ;
Cust_Id, ;
"2"
AS xSort, ;
"
" AS Order_Id, ;
NTOM( 0 )
AS Order_Amt, ;
000 AS Order_Dsc,
;
Rab_Dsc, ;
Rab_Sum ;
FROM ;
Rab ;
ORDER BY ;
1, ;
2, ;
6 ;
INTO ;
CURSOR Order_Rab
BROWSE LAST NOWAIT
Die Datenaufbereitung führt dann zu diesem Ergebnis:
[ 1 ] [
2 ] [ 3 ] [
4 ] [ 5 ] [ 6 ]
|