Donnerstag, 4. Dezember 2008

entwickler.com Magazine Konferenzen Akademie Entwickler-Forum Jobbörse Bücher
Software & Support Verlag




April 2006
aus Der Entwickler Ausgabe: 6.2001
Delphi-Rave
Reports mit Rave4 und Delphi / C++Builder
von Thomas Pfister

Die Entwicklungsumgebungen Delphi und C++-Builder bieten von Hause aus den Quick Report als Reporting-Tool fürDatenbankanwendungen an. Dieses Programm steht, wie der Nameschon sagt, für schnelle Reports zur Verfügung. Im professionellen Bereich hingegen stößt es sehr schnell an die Grenzen; ferner zeichnet es sich nicht durch eine besonders hohe Stabilität aus.


So haben es Drittanbieter nicht besonders
schwer, in diesem Bereich Fuß zu fassen. In
verschiedenen Beiträgen des Entwicklers
wurden in den vergangenen Jahren bereits
einige vorgestellt, die verschiedene Schwerpunkte
aufweisen. In diesem Beitrag soll es
Report Printer Pro von Nevrona gehen,
bzw. um Rave.

Die Versionen 1 und 2 von ReportPrinter
Pro waren rein codebasiert, d.h. sämtliche
Reports waren in reinem Pascal mit
neunzehn Komponenten und über fünfhundert
Methoden und Eigenschaften bzw.
Ereignissen realisiert.

In der Version 3 wurde 1997 der Rave-
Editor hinzugefügt. Damit war es möglich,
parallel zu den codebasierten Reports auch
visuell Reports zu erstellen. Dieses zweite
Standbein wurde kontinuierlich weiterentwickelt
und die Erfahrungen und Ergänzungen
wurden in die aktuelle Version 4
eingebracht. So wurde der klassische Bereich
unverändert übernommen und im visuellen
Rave-Bereich kamen einige neue
Features hinzu. Diese Version ist für Delphi
5 und 6 sowie für C++Builder 4 und 5 verfügbar.
Die Version 3 läuft auch noch auf älteren
Versionen von Delphi und C++Builder.
Auf www.nevrona.com befindet sich
eine Trialversion, mit dieser können sämtliche
folgenden Schritte nachvollzogen werden.
Nach Installation der Komponenten erhalten
wir ein Register mit einundzwanzig
Komponenten, die teils für den codebasierten,
teils den visuellen Part sowie für beide
nutzbar sind. Daneben wird auch eine ausführliche
Hilfe und eine Dokumentation
im PDF-Format mitgeliefert.

Im Folgenden soll die aktuelle Version
4.03b (4.04 wird in den nächsten Wochen
veröffentlicht) an einem Beispiel näher vorgestellt
werden. Das Delphi 6-Projekt hierzu
befindet sich auf der aktuellen Pro.-CD
und auf www.derentwickler.de.
In dem Rave-Projekt können sämtliche
Reports der Applikation in einer Datei verwaltet
werden. Diese Projekt-Datei kann

  • in die Applikation fest eingelinkt werden;
  • als externe Datei weitergegeben werden. Je nach Version kann ein kostenfreier sog. End-User-Reportgenerator (eine redistributed DLL bei einem unmodifizierten Rave, ansonsten eine kleine DLL und Packages) diese Reports ändern. Auch ein Update der Applikation oder nur der Reports ist hierdurch gewährleistet;
  • mit dem Rave-Server im Inter- bzw. Intranet zentral verwaltet werden.
Im nachfolgenden wollen wir aus einer Datenbank
heraus Rechnungen erstellen. Ich
habe bewusst als Datenbank die Tabellen
aus dem DBDEMOS-Verzeichnis gewählt.
Diese hat grundsätzlich jeder Delphi-Anwender
mit Datenbankkomponenten zur
Verfügung. Sicherlich sind TTable für den
Flat-File-Bereich und SQL-Abfragen eher
für die C/S-Architektur bestimmt, aber bei
der vorhandenen Datenmenge und der Verfügbarkeit
für alle Delphi-Inhaber ist aus
meiner Sicht der gewählte Weg für eine Einführung
in die Reporterstellung mit Rave4
vertretbar. Ferner habe ich mangels Komplexität
kein Datenmodul oder TClientdatasets
etc. in das Beispielprogramm integriert.

Es gibt zwei TTable-Komponenten mit
Zugriff auf die Tabellen Customer und
Orders, ferner eine Query mit der Data-
Source von Orders und folgendem SQLText:

SELECT Items.Qty, Parts.Description, Parts.ListPrice
FROM items.db Items
INNER JOIN parts.db Parts
ON (Items.PartNo = Parts.PartNo)
WHERE Items.OrderNo = :OrderNo

Und bei der TQuery einem berechneten
Feld CalcSummePart.Value:

QItemsCalcSummePart.Value := QItems.FieldByName(`Qty').
AsInteger * QItems.FieldByName(`ListPrice').AsFloat;

Im Gegensatz zu dem integrierten Quick
Report wird für den Report kein Formular
von Delphi genutzt. Nach dem Einfügen
der RPRave-Komponente und einem Doppelklick
auf diese Komponente wird die
Rave.exe als eigenständiges Programm geladen.
Die Weitergabe der Rave.exe ist
nicht notwendig bzw. erlaubt. Auch in Hinblick
auf den ReportBuilder ist der Bericht
nicht über die Delphi-Ereignisse zu steuern.
Vielmehr ist der Report derzeit vollkommen
von der Ereignisbehandlung von Delphi
getrennt. Ob der Weg von ReportBuilder
oder ReportPrinter besser ist, kann
schlecht beurteilt werden. Es erfordert auf
jeden Fall eine sauberes Reportdesign. Von
Vorteil ist meines Erachtens dabei die Offenheit
für viele Bereiche und letztendlich
auch für verschiedene Entwicklungsumgebungen.

Die Ansicht des Rave-Programmes
überzeugt durch einen durchdachten Aufbau.
Auf der linken Seite befinden sich die
Projekt-Übersicht und die Eigenschaftsfelder
der Komponenten. Rave wurde mit
Delphi erstellt (Source ist in der Vollversion
enthalten!) und zeigt auch gleich die Verwandtschaft.
Bei dem leeren Projekt ist der Report 1
mit Page1 standardmäßig erstellt worden.
Mit dem Markieren dieser Page1 werden
links sämtliche Eigenschaften dieser Seite
angezeigt. Hier wollen wir die Rechnung
definieren. Der Aufbau der Rechnung soll
wie folgt aussehen:
  • Kopf erste Seite mit Rechnungsinformationen (kd.-nr. rech-nr, datum)
  • Detailkopf mit Beschriftung
  • Einzelne Positionen bzw. Items mit Anzahl, Bezeichnung, Einzel- und Gesamtpreis
  • Gesamtsumme der Rechnung, Zahlungsinformationen
  • Variabler Werbetext
Der Aufbau der Reports sollte (wie bei einem
Datenbankmodell bekanntlich auch!)
vor Erstellung möglichst exakt festgelegt
werden.


Vor dem Schritt des eigentlichen Report-
Designs muss erst die Verbindung des
Rave-Reports mit den Datasets der Delphi-
Applikation erfolgen. In dem Delphi-Formular
muss für jedes Dataset eine RPData-
SetConnection eingefügt werden. Rave
bietet insgesamt drei unterschiedliche Varianten
an; es gibt sowohl Table- und Query-
Connection als auch Dataset-Connection.
Die ersten zwei Komponenten setzen auf
die BDE auf, letztere setzt auf allen TDataset-
Nachfahren auf. Beispielsweise seien
hier die folgenden genannt:
  • ADO-Datenzugriffsobjekte
  • IBX-Datenzugriffsobjekte
  • Client-Datasets
  • ODAC und DOA - Oracle Zugriffsobjekte
  • Advantage-Datenzugriffsobjekte
Hierdurch können quasi sämtliche Datenquellen
genutzt werden. Auch Datenbanken
wie Records, Arrays und Streams sind
möglich. Durch diese Möglichkeiten kann
sogar in einer kleinen Applikation ein Report
ohne Datenzugriffskomponenten und
DLLs etc. fest eingebunden werden.
In der Praxis setzt man meist die allgemeine
Dataset-Connection ein, da sie auch
mit der BDE TQuery und BDE TTable ohne
Probleme zusammenarbeitet. Wir fügen
daher insgesamt drei RPDatasetConnection-
Komponenten in das Delphi-Formular
ein und verbinden diese mit den zwei
Table-Objekten und der Query-Komponente.

Mittels ALT+TAB können wir in das
noch offene Raveprojekt wechseln. Hier
gibt es auf dem Register PROJECT die Komponente
View für die Verbindung zwischen
Delphi und dem Bericht. Nach dem Anklicken
erscheint ein Dialogfenster.
Rave bietet in der aktuellen Version
auch einen Direktzugriff auf diverse Datenbanken.
Wir wollen aber heute noch den
klassischen Weg gehen und wählen daher
die sog. DIRECTDATAVIEW aus. Nun erscheinen
in dem nächsten Dialogfenster unsere
drei RPDatasetConnections von dem
Delphiformular.

Mit der Shift-Taste können wir alle drei
auswählen. Dies erscheinen danach in dem
Rave-Projekt unter dem Bereich Data-
ViewDictionary. Hier werden auch alle
Felder angezeigt. An der jeweiligen Grafik
erkennt man auch den Datentyp sehr
schnell. Analog den allgemeinen Empfehlungen
unter Delphi sollten auch hier die
DataViews einen aussagekräftigen Namen
erhalten. Jetzt sind die grundsätzlichen
Vorarbeiten in Bezug auf die Datenbankverbindungen
erledigt.

Rave 4 ist grundsätzlich bandorientiert
aufgebaut. Doch vor dem Einfügen von
Bändern muss erst eine sogenannte Region,
die für die noch zu bestimmenden
Bänder quasi als Container auftritt, definiert werden. Hierdurch kann z. B. bei
Briefbögen, die farblich vorgedruckt sind,
der mögliche Druckbereich exakt definiert
werden. Daneben gibt es unter Rave 4 die
Möglichkeit, verschiedene, auch globale
Seiten zu nutzen.
Als erstes ist daher auf der Seite eine Region
aus dem Register REPORT auf die festgelegte
Druckgröße einzufügen. Wir wollen
in unserem Beispiel fast den gesamten
Bereich nutzen.


<table width="100%" border="0">
<tr bgcolor="#000000">
<td>
<table width="100%" border="0" cellpadding="2">
<tr bgcolor="#FFFFFF">
<td><div class="vpfliess">Rave 4.0 Editionen



Nevrona Design bietet derzeit folgende Version an:

  • Rave 4.0 Standard bzw. Office Edition: Hiermit ist es möglich, mit dem sog. Single User Rave Server
auf verschiedene Datenbanken zuzugreifen. Diese Version geht in Richtung Crystal Reports.
  • Rave 4.0 Developer Edition: Damit wird es seit neuestem ermöglicht, dass VB- und VC++- Entwickler
den Rave4-Berichtgenerator in ihren Applikation nutzen können.
  • Rave 4.0 Borland Edition: Diese Version enthält sowohl die codebasierte Reportkomponente wie
auch den Rave4-Berichtsgenerator für Borland Delphi und C++Builder.


Eine Kylix-Version ist derzeit in der Planung. Der später erwähnte Rave-Server ist auf Linux bereits im
Betatest.

</td>
</tr>
</table>
</td>
</tr>
</table>


Nunmehr geht es in den eigentlichen
Kernbereich, die Bänder. Rave unterscheidet
hier zwischen den normalen und den
Datenbändern. Diese Komponenten findet
man ebenfalls in dem Register REPORTS des
Rave-Programmes. Die Datenbänder sind
als Detail- und Sub-Detailbänder, die anderen
für den Kopf- und Fußbereich etc. gedacht.
Aufgrund unserer Vorüberlegungen fügen
wir zwei Textbänder, ein Datenband
und noch mal zwei Textbänder ein .
Die bisherige Ansicht ist noch nicht in
Bezug auf Höhe und Inhalt der jeweiligen
Bänder individualisiert. Das Band mit dem
Namen Band1 soll nur auf der ersten Seite
erscheinen und die Rechnungsanschrift,
Ort und Datum etc. beinhalten. Wir müssen
diesem Band daher folgenden Eigenschaften
zuordnen:

ControllerBand = DataBand1
GroupDataView = DVCustomer
GroupKey = CustNo
BandStyle [...] = BodyHeader

Bei Band2 sollen lediglich die Spaltenbezeichnungen
für die einzelnen Artikel gedruckt
werden. Die Eigenschaften lauten
daher wie folgt:

ControllerBand = DataBand1
GroupDataView = DVOrders
GroupKey = OrderNo
BandStyle [...] = GroupHeader und NewPage bei Print
Occurence auch New Page

Damit bei einer größeren Rechnung, die
sich über mehrere Seiten erstreckt, auch auf
jeder Seite diese Spaltenbeschreibung oben
gedruckt wird.

Bei dem DataBand1 müssen wir lediglich
diese mit der DatenView DVItems verknüpfen.
Bei Band3 müssen folgende Eigenschaften
definiert werden:

ControllerBand = DataBand1
GroupDataView = DVOrders
GroupKey = CustNo
BandStyle [...] = BodyFooter

Bei Band4 müssen folgende Eigenschaften
definiert werden:

ControllerBand = DataBand1
GroupDataView = DVOrders
GroupKey = CustNo
BandStyle [...] = BodyFooter

Dieses Band könnte rein theoretisch in dem
Band3 enthalten sein, aber aus Übersichtlichkeitsgründen
sollte es separat gepflegt
werden.

Bei jeder Veränderung der Eigenschaften
von BandStyle ändert sich auch ggf.
das Vorschaufenster. Die jeweilige Bandhöhe
kann entweder über das Eigenschaftsfeld
links oder mit der Maus eingestellt
werden.
Jedes Band kann selbstverständlich mit
einem aussagekräftigen Namen versehen
werden. Für die einzelnen Bänder gibt es
noch viele Eigenschaften, die bei der Berichtgenerierung
vollautomatisch abgearbeitet
werden. Beispielsweise sei hier die Eigenschaft
StartNewPage genannt. Durch
das Setzen von True wird ein Seitenwechsel
vor dem Drucken durchgeführt. Bei der Eigenschaft
FinishNewPage entsprechend
nach dem Drucken des Bandes.
Die einzelnen (Daten-) Felder können
über das Register REPORT bzw. STANDARD
auf das jeweiligen Band Delphi-like übernommen
werden. Sämtliche datensensitiven
Komponenten erscheinen bei den Registern
mit einem roten Punkt in dem Icon
rechts oben.
Selbstverständlich können auch die
entsprechenden Datenfelder der DataView
mit der STRG-Taste auf das Band übernommen
werden. Die Rechnungsgesamtsumme
wird mit der Komponente CalcText errechnet. Nach Festlegen von
DataField und DataView wird die Summe
errechnet, da der Standwert bei CalcTyp
ctSum ist; weitere Typen sind ctAverage,
ctMax, ctMin, ctCount.

Bei Feldern mit Systeminformationen
(z. B. Seitenzahl, Datum etc.) wird von
dem Reportregister die DataText-Komponente
auf das Band übernommen. Statt
einer Zuordnung zu einem Dataview-Feld
wird bei der Eigenschaft Datafield der Datatext-
Editor mit dem Anklicken des drei
Punkte-Buttons aufgerufen. Hier können
einige mächtige Operationen durchgeführt
werden. Es soll die aktuelle Seitenanzahl
und die Gesamtseitenanzahl gedruckt
werden.
Die Informationen ergeben sich aus den
sog. Reportvariablen. Ein Verketten erfolgt
durch das normale Addieren von Strings
bzw. Variablen. Neben den Reportvariablen
sind natürlich auch Datenbankfelder
und Parameter (direkt aus Delphi bzw.
C++Builder heraus) nutzbar. Nachfolgend
ist die Postleitzahl und der Ort aus der Dataview
DVCustomer addiert. Die Probleme
bei Adressen innerhalb und außerhalb
Deutschland mit vorangestellten Länderkennzeichen
etc. gehören damit der Vergangenheit
an.

Die Übergabe von Parametern aus Delphi
heraus ist ebenfalls absolut unproblematisch.
Bevor der Report ausgeführt wird
(siehe weiter unten) müssen die jeweiligen
Parameter an den Report übergeben werden.
Dies erfolgt in Delphi bzw. C++Builder
wie folgt:

RaveProject1.SetParam(`Parameter-
Name_Rave', Wert);
RaveProject1->SetParam(`Parameter-
Name_Rave', Wert);

Die Deklaration der Parameter innerhalb
von Rave entweder auf Projekt-Ebene,
d.h. für alle Reports oder rein auf Report-
Ebene. Hier gibt es jeweils die
Eigenschaft Parameters; hier müssen lediglich
die Parameternamen eingetragen werden.
Die Speicherung erfolgt intern in einer
TStringList.
In dem Datatext-Editor können dann
sämtliche Parameter sowohl auf Projektwie
auch auf Report-Ebene übernommen
werden. Eine Nutzung für GroupKey etc.
ist damit ebenfalls möglich.
Nach den Abschlussarbeiten kann das
Rave-Projekt gespeichert werden. Dieses
File beinhaltet die Reportdaten als Stream.
In der RaveProject-Komponente auf dem
Delphi-Formular kann nun die Eigenschaft
ProjectFile dahingehend geändert werden,
dass hier der Name der Reportdatei eingetragen
wird. Bei der Übernahme aus dem
Browse-Fenster wird die Datei inklusive
(Entwickler-)Verzeichnis übernommen!
Selbstverständlich kann diese Eigenschaft
auch während der Programmausführung
definiert werden.

Soll die Reportdatei direkt in die Applikation,
d.h. in die EXE, gelinkt werden, so
ist die Datei in der Eigenschaft StoreRav zu
übernehmen. Hier gibt es aber etwas Wichtigen
zu beachten: Dieses Delphi-Formular
darf nicht als Text-DFM gespeichert
werden. Die Rave-Komponente speichert
die Report-Informationen im Streamformat
innerhalb des Delphi-Formulares und
erfordert die binäre Speicherung.
In die Beispielanwendung habe ich zwei
Buttons eingefügt, welche die Tabelle Orders
filtert:

TOrders.Filter := (`OrderNo = ` + Orders.FieldByName
(`OrderNo').AsString);
TOrders.Filtered := True;

bzw. mit Orders.Filtered := False; wieder
aufhebt. Nach dem Filtern der Tabelle wird
der Bericht wie folgt gestartet:

RaveProject1.Execute;
RaveProject1->Execute();

Damit wird bei einer Reportdatei mit nur
einem Report dieser gestartet. Bei mehreren
Reports erfolgt zuvor die Auswahl des
richtigen Reports:

RaveProject1.SelectReport(`Reportname', False);
RaveProject1->SelectReport(`Reportname', False);

Der zweite Wert ist für den Bereich Fullname
bzw. Shortname wichtig.
Standardwert ist das Anzeigen des sog.
Setup-Menüs, in welchem der Anwender
auswählen kann, ob er die Voransicht sehen
oder direkt ausdrucken will. Selbstverständlich
kann diese Auswahlmöglichkeit
auch im Delphi-Programm gesteuert werden
und ggf. überhaupt nicht angezeigt
werden. Hierzu ist eine weitere Rave-
Komponente im Delphi-Formular notwendig:
TReportSystem Diese Komponente
steuert mit über hundert Eigenschaften
sämtliche Systemoptionen der
Reports.

Die RaveProject-Komponente muss
über die Eigenschaft Engine mit der TReportSystem1
- Komponente verbunden
werden. Danach können hier (manuell
bzw. programmgesteuert) bei der Eigenschaft
SystemSetups z. B. das Anzeigen des
Auswahlmenüs bei dem Ausdrucken komplett
unterdrückt werden. Bei der Eigenschaft
DefaultDest wird rdPreview eingetragen
und damit wird direkt in die
Voransicht gewechselt. Oder entsprechend
mit rdPrint auf dem Standarddrucker
ausgedruckt.


    Hat Ihnen dieser Artikel gefallen? Dann abonnieren Sie das Entwickler Magazin direkt über unser Online-Formular.



zur vorherigen Seite
zurück
an den Anfang der Seite
nach oben
Diesen Artikel drucken
drucken
Diesen Artikel weiterempfehlen
empfehlen
Software & Support Verlag GmbH