Komplexe Berichte

Aus iDempiere de
Zur Navigation springen Zur Suche springen

Dieser Artikel soll besondere Probleme und Vorgehensweisen bei der Erstellung von komplexen Berichten mit dem internen Berichtsgenerator von iDempiere beschreiben. Dieser Artikel behandelt ausschließlich die Arbeit mit dem internen Berichtsgenerator. Die Vorgehensweise mit JasperReports soll hier nicht Thema sein.

Dieser Artikel ist von Thomas Bayen. Meine Artikel sind grundsätzlich nie "fertig", sondern immer eine Einladung, sie zu verbessern. Ich lade jeden gerne jederzeit ein, Verbesserungen hier direkt einzupflegen. Wer möchte, kann mich auch gerne kontaktieren.

Vorüberlegungen

Was ich hier unter einem komplexen Bericht verstehe ist die Anzeige eines Datensatzes als ein Formular (z.B. alle Kundendaten auf einer Seite). Diese Ausgabe enthält eine oder mehrere Unterlisten (wie z.B. Umsätze oder Preise eines Kunden).

Ein gut gemachter Bericht soll möglichst an mehreren Stellen benutzt werden können. Das heisst, es wäre schön, wenn man

  • Unterberichte in verschiedenen Hauptberichten verwendet
  • Unterberichte auch eigenständig funktionieren
  • Ein Bericht einen einzelnen Datensatz optimal ausdrucken kann (per Druck-Button in der Toolbar)
  • Ein Bericht mehrere Datensätze hintereinander ausdrucken kann (z.B. alle Kunden einer Kundengruppe, jeder einzelne mit allen wichtigen Daten auf einer Seite)

Diese "Wiederverwendung" von Berichten hat viele Vorteile. Spätere Änderungen müssen nicht überall nachgepflegt werden und der Benutzer verlässt sich darauf, das die Zusammenstellung der Daten an verschiedenen Stellen des Programms immer gleich ist.


Datenbankansichten benutzen

Um optimal alle Daten zu einem Datensatz in einer Tabelle zu haben, reicht es nicht, die Basistabelle zu benutzen. Da die Daten in der iDempiere-Datenbank weitgehend normalisiert sind, enthält ein Datensatz immer nur Referenzen auf andere Datensätze. So enthält ein Geschäftspartner keine Adresse, sondern nur eine Referenz auf einen Adress-Datensatz in der Tabelle C_Location, der dann die eigentlichen Adressfelder enthält. Selbst einfache Felder wie z.B. die Geschäftspartnergruppe, von der man vielleicht nur den Suchschlüssel ausgeben möchte, sind nicht direkt erreichbar.

Um dieses Problem zu lösen, sollte man für komplexe Berichte nicht die ursprüngliche Tabelle, sondern ein Datenbank-View benutzen. Diese Views haben durch SQL JOIN-Befehle die verschiedenen Tabellen verknüpft und hieraus dadurch eine virtuelle Tabelle erzeugt, die sehr breit ist (also viele Felder enthält). Viele Views sind bereits vordefiniert, man kann diese natürlich auch erweitern oder sogar selber ein neues View für Berichte anlegen. Die speziell für Berichte vordefinierten Views fangen im Namen mit "RV_" (Report View) an.

Damit man ein View als Druckbericht eines Registers benutzen kann, muss es eine ID-Spalte (als Kopie der ID der originalen, d.h. der im Register angezeigten Tabelle) enthalten. Das heisst, das ein View "RV_BPartner", mit dem ich Daten aus der Tabelle "C_BPartner" aufpeppen möchte, immer eine Spalte namens "RV_BPartner_ID" haben sollte, die den Primärschlüssel von C_BPartner enthält. Das kann man im View so definieren: "C_BPartner_ID AS RV_BPartner_ID".

Damit man ein View als Unterbericht benutzen kann, muss es übrigens die Sortierspalte (zumeist die Schlüsselspalte) der originalen Tabelle (der im Hauptbericht benutzten Tabelle) mit dem originalen Namen enthalten. Für ein allgemein verwendbares View bietet es sich daher an, diese Spalten entsprechend mit einzubinden.

Leider kann man diese View-Druckformate nicht ganz so einfach aufrufen. Wenn man in einem Eingabe-Fenster den Berichts-Button in der Toolbar drückt, kann man nur Druckformate auswählen, die als Basistabelle die im aktuellen Register benutzte Tabelle eingestellt haben (keine, die auf einem View basieren, das für iDempiere ja eine andere Tabelle ist).

Man kann basierend auf dem Druckformat jedoch einen oder mehrere Berichte im Fenster "Prozeß & Bericht" definieren.

Aufruf von Berichten

Hat man einen Bericht in "Prozeß & Bericht" definiert, so kann man ihn auf verschiedene Arten benutzen. Die Berichte erlauben im Gegensatz zum reinen Druckformat auch die Angabe von Parametern. Sind diese definiert, wird der Bericht automatisch eingeschränkt. So kann man z.B. nur Kunden einer bestimmten Kundengruppe oder mit einer Kundennummer von ... bis angeben.

Aufruf durch ein Programm-Hauptmenü

Man kann ganz einfach im Systemmandanten einen zusätzlichen Menüpunkt definieren, der dann im Hauptmenü erscheint und in dem man einen Bericht aufruft. Hier bietet es sich an, parametrisierte Berichte zu verwenden, damit man den Bericht vielfältiger einsetzen kann. Oftmals wird man auch mehrere Berichte definieren, die auf dem gleichen Druckformat basieren aber unterschiedliche Parameter benutzen.

Aufruf durch den "Druck"-Button

Ein Bericht kann im Fenster "Fenster, Register % Felder" einem Register zugeordnet werden, indem man es im Feld "Prozeß" angibt. Der Effekt dieser Einstellung ist, das in dem entsprechenden Register dann in der Toolbar die Buttons "Druckvorschau" und "Druck" aktiviert werden. Hier kann man dann einen Ausdruck des aktuellen Datensatzes erzeugen. Hier bietet es sich eher an, einen Bericht ohne Parameter zu verwenden.

Beim Druck-Button ist die Besonderheit, das der Ausdruck so gefiltert wird, das nur der aktuelle Datensatz gedruckt wird. Das funktioniert dergestalt, das die ausgegebene Tabelle (also die, die im Druckformat angegeben ist wie z.B. ein View) nach einem Feld selektiert wird, das der Konvention für SChlüsselfelder (Tabellenname + "_ID") entspricht. Dazu wird der Wert des Schlüsselfeldes des momentan angezeigten Datensatzes benutzt.

Beispiel: Ich bin in einem Register, das Daten der Tabelle C_BPartner anzeigt (also einen Geschäftspartner). Nun habe ich ein View "RV_BPartner", das ich für mein Druckformat benutze. Dann wird für den Ausdruck der Datensatz aus der Tabelle "RV_BPartner" ausgewählt, der im Feld "RV_BPartner_ID" denselben Wert besitzt, der im angezeigten Datensatz im Feld "C_BPartner_ID" steht. (siehe ReportEngine.java, Zeile 1201)

Aufruf durch einen Button in einem Eingabefenster

Man kann in einer beliebigen Tabelle eine Spalte vom Typ "Button" definieren. Wird ein entsprechendes Feld im Fenster "Renster, REgister & Felder" definiert, erscheint an der entsprechenden Stelle in diesem Register ein Knopf, der den Prozeß startet.

TODO: Inwiefern es hier möglich ist, den Bericht z.B. auf den aktuellen Datensatz zu limitieren, ist mir nicht klar. Das sollte man mal untersuchen.

Aufruf durch einen Toolbar-Button

Bei der Definition einer Button-Spalte kann man auch angeben, das der Button nicht im Eingabeformular, sondern in der Toolbar erscheint. Man drückt dazu auf den Button mit dem Zahnrad und kann den Prozeß aus einer heruasklappenden Liste auswählen.


Tips & Tricks