Beliebige Datenbank-Abfragen in FastReport

Aus GEVITAS
Version vom 8. Juli 2025, 14:28 Uhr von Gevitas (Diskussion | Beiträge) (Abfrage von Daten anhand von Positionen)
Wechseln zu: Navigation, Suche

1 Allgemeines

Das Druck-Modul "GevitasFormPrint" stellt dem Report-Editor alle Daten zur Verfügung, die für das jeweilige Formular gerade sinnvoll sind, z.B.

  • bei einem Angebot die Auftragskopf-Daten, Auftragspositionen usw.
  • bei einem Werkstatt-Auftrag die Reparatur-Daten, Kunden-Daten, Auftrags-Daten usw.
Datenbank-Kenntnisse sind hierfür nicht erforderlich!

Manchmal will man jedoch weitere Daten im Report haben, die das Druck-Modul nicht berücksichtigt. Für diesen Fall kann man einen Report um weitere, beliebige Datenbank-Abfragen erweitern.

Dieser Artikel zeigt, wie einfach das geht.

Allerdings muss man sagen, dass man hierfür Datenbank-Kenntnisse haben sollte und die SQL-Sprache kennen sollte!

2 Die Seite Data im Report

in jedem Report gibt es eine Seite "Data" in dem Register links oben.

FastReport Data 01 RegisterSeite.png

Hier kann man zusätzliche Datenquellen unterbringen, die auf Tabellen der Datenbank zugreifen:

ADO-Table
Greift direkt auf eine Tabelle der Datenbank zu. Man kann/muss den Namen der Tabelle angeben und kann die Daten filtern, z.B. die Auftragsdaten nach der Auftragsnummer.
ADO-Query
Greift über eine SQL-Abfrage auf beliebige Tabellen der Datenbank zu. Man kann/muss die SQL-Abfrage angeben und kann die Daten über eine "Where"-Klausel mit einem Parameter filtern, z.B. die Auftragsdaten nach der Auftragsnummer. Diese Methode ist sehr flexibel, erfordert aber Datenbank- und SQL-Kenntnisse!
Dieser Artikel beschreibt diese Methode.

3 Einfügen einer Query in die Data-Seite

Dazu zieht man einfach das Query-Objekt aus der Leiste links auf die Data-Seite.

Die Query hat nun folgende wichtige Eigenschaften:


4 Eigenschaften der Query

Die wichtigsten Eigenschaften einer Query sind:

Eigenschaft Beschreibung
Database Legt die Verbindung zur Datenbank fest. Standardmäßig wird die Verbindung der Standard-Tabellen des Reports verwendet. Alternativ dazu könnte man auch ein Connection-Objekt aus der Leiste links auf die Seite "Data" ziehen und dort eine eigene Datenbank-Verbindung aufbauen.
FieldAliases Hier könnte man den Datenbank-Felder einen ausführlichen Alias-Namen vergeben, um sie besser zu verstehen.
Filter Wird bei einer Query normalerweise nicht benötigt, weil die SQL-Abfrage ein "where" beinhaltet. Bei einem Table-Objekt kann man den Filter jedoch verwenden, um nur bestimmte Daten aus den Tabelle zu ziehen.
Master Optional eine Möglichkeit, eine 1:n-Beziehung zu einer Master-Tabelle herzustellen.
Params Gibt die Möglichkeit, Parameter aus der SQL-Abfrage mit einem Wert oder einem Feld zu verknüpfen. Sehr wichtige Funktion!.

Parameter im SQL-Text beginnen mit einem Doppelpunkt, dahinter wird ein eindeutiger Parameter-Name eingegeben. Mit dem ... Button in dieser Zeile kann man die Parameter mit einem Wert oder einem beliebigen Feld des Reports verknüpfen, z.B. mit dem Feld "Auftragsnummer". Damit bezieht sich das Abfrage -Ergebnis auf Daten mit dieser Auftragsnummer!

SQL Hier wird der SQL-Text für die Datenabfrage angegeben. Er legt fest, welchen Daten aus der Datenbank abgerufen werden sollen. Sinnvollerweise enthält der SQL-Text eine "Where"-Klausel mit einem Parameter-Feld (":ParamName").

5 SQL-Text

Der SQL-Text bestimmt, welche Daten aus der Datenbank abgerufen werden sollen. Das kann ein einfaches "select * from xxx" sein oder eine komplexe Abfrage mit mehreren verbundenen Tabellen.

Entscheidend ist, dass in der "Where"-Klausel ein Parameter enthalten ist! Diesen Parameter kann man dann mit einem Datenfeld verbinden, z.B. mit der Auftragsnummer.

5.1 Beispiel 1

In einem Werkstatt-Auftrag-Report sollen Daten aus einem verbundenen Transport-Auftrag stehen. Also zieht man eine Query auf die Seite "Data" und füllt den SQL-Text so (abgekürzt):

select MAUFKO.AUFTRNR,MAUFKO.STATUSNR,MAUFKO.STATUSTEXT,MAUFKO.DRUCKDAT,MAUFKO.DRUCKZEIT,MAUFKO.DRUCKUSER,
MAUFKO.ADRKURZNAME,MAUFKO.ADRESSE,MAUFKO.STR, MAUFKO.LANDKENNZ,MAUFKO.PLZ,MAUFKO.ORT,MAUFKO.LAND,MAUFKO.SPRACHE,MAUFKO.AUFTRAGSART,
MAUFKO.VERANSTNAME,MAUFKO.VERANSTORT,MAUFKO.VERANSTRAUM,

MAUFPO.POSNR, MAUFPO.UNTPOSNR, MAUFPO.STATUSNR, MAUFPO.STATUSTEXT, MAUFPO.ARTNR, 
MAUFPO.TYP,MAUFPO.BEZEICHNUNG,MAUFPO.KISTE,MAUFPO.STLISTE,MAUFPO.ARTIKELART,MAUFPO.ARTIKELHERKUNFT,MAUFPO.KENNZMIETEVERKAUF,
MAUFPO.AUFTRMENGE,MAUFPO.EINHEIT,MAUFPO.EKPREIS,MAUFPO.DATVON,MAUFPO.ZEITVON,MAUFPO.DATBIS,MAUFPO.ZEITBIS,MAUFPO.BEREINHEIT,
AUFPO.ADRPoints
from MAUFPO MAUFPO 
left outer join MAUFKO MAUFKO on MAUFKO.AUFTRNR=MAUFPO.AUFTRNR
where MAUFPO.REPNr=:REPAUF_REPNR

5.2 Beispiel 2

In einer Rechnung (Sammelrechnung aus Projekt) sollen Daten aus dem Projekt stehen. Also zieht man eine Query auf die Seite "Data" und füllt den SQL-Text so (abgekürzt):

select * from KOTR where KOTRNR=:ProjNr

Hier muss man wissen, dass die Projekt-Tabelle intern "Kostenträger" heißt und der Tabellenname "KOTR" lautet!

Der Paramater dazu heißt hier ":ProjNr". Er könnte auch ":KoTrNr" lauten oder ":Meier" oder wie auch immer! Wichtig ist nur, dass der Parameter mit Doppelpunkt beginnt. Nur so kann man im einen Wert bzw. ein Datenbankfeld zuweisen.

5.3 Parameter definieren

Der Text-Ausdruck

:REPAUF_REPNR

oder

:ProjNr

mit dem Doppelpunkt ist ein sog. Parameterfeld. Beim Ausführen des Reports wird der festgelegte Wert eingesetzt, z.B. das Datenbankfeld mit der Auftragsnummer.

Mit dem Button Params ... kann man den Wert des Parameters festlegen.

Beispiel:

FastReport Data 02 Paramfeld.png

In diesem Beispiel wird das Datenbankfeld

<Werkstattauftrag."WerkstattAuftrNr"> 

für den Parameter festgelegt:

FastReport Data 03 Paramfeld.png

Somit bezieht sich die SQL-Abfrage auf den Werkstattauftrag ("REPAUF") mit der Werkstatt-Auftr.Nr. ("REPAUF.RepNr"), die im Report verwendet wird!

Im zweiten Beispiel wäre es das Feld

<RechnungsKopf."ProjektNr">

6 Im Report

sieht das so aus:

FastReport Data 04 Tabelle.png

Die SQL-Abfrage der Query mit dem Namen "TransportAuftrag" wird jetzt als Tabelle im Daten-Register angezeigt. Alle Felder der Abfrage können nun im Report verwendet werden.


7 Abfrage von Daten anhand von Positionen

Standardmäßig führt FastReport© eine Data-Abfrage einer Query beim Starten des Reports aus. Zu diesem Zeitpunkt sind die Kopfdaten (z.B. eines Auftrags) und alle damit verknüpften Tabellen eingelesen worden.

REFLEX Datenbank Auftragsverwaltung.png

Das heißt aber auch, dass die erste Position des Auftrags oder der Rechnung eingelesen wurde.

Soll sich nun eine Query-Abfrage auf Daten aus den Positionen beziehen, muss man manuell eingreifen.


7.1 Beispiel Auftragstermine einer Sammelrechnung aus Projekt

Bei einer Sammelrechnung aus einem Projekt gibt es mehrere Kapitel und Positionen aus mehreren Aufträgen. Will man nun auf der Rechnung die Termine aus den zugehörigen Aufträgen in den Positionen drucken, kann man die SQL-Abfrage so einfügen:

select MAUFJOB.*,
GEVPARAM.PARAMTEXT1 as TerminartText,
MAUFKO.VERANSTNAME Auftrag_VAName, MAUFKO.VERANSTORT Auftrag_VAOrt, MAUFKO.VERANSTRAUM Auftrag_VARaum, MAUFKO.VORTKURZNAME Auftrag_VAKurzname, MAUFKO.VERSANDTEXT Auftrag_VersandText, MAUFKO.BEMERKUNG Auftrag_Bemerkung,
MaufJob_Adr.ID Adr_ID, MaufJob_Adr.ID_STRING Adr_ID_STRING, MaufJob_Adr.MaufJob_LfdNr Adr_MaufJob_LfdNr,
MaufJob_Adr.Ladezone Adr_Ladezone,
MaufJob_Adr.Adresse Adr_Adresse,
MaufJob_Adr.Str Adr_Str, MaufJob_Adr.LandKennz Adr_LandKennz,
MaufJob_Adr.PLZ Adr_PLZ, MaufJob_Adr.Ort Adr_Ort,
MaufJob_Adr.Land Adr_Land, MaufJob_Adr.AnsprPartner Adr_AnsprPartner,
MaufJob_Adr.Sprache Adr_Sprache,
MaufJob_Adr.AnsprPartnerMail Adr_AnsprPartnerMail,MaufJob_Adr.AnsprPartnerTel Adr_AnsprPartnerTel
from MAUFJOB MAUFJOB
left outer join MAUFJOB_ADR MaufJob_Adr on MaufJob_Adr.MaufJob_LfdNr=MAUFJOB.LFDNR
left outer join GEVPARAM GEVPARAM on GEVPARAM.PARAMNAME = 'TERMINART' and GEVPARAM.PARAMVARIANTE = MAUFJOB.TERMINART
left outer join MAUFKO MAUFKO on MAUFKO.AUFTRNR=MAUFJOB.AUFTRNR
where MAUFJOB.AUFTRNR=:RechPoAusAuftrNr  
and TERMINART > 0 and ( DRUCKEN_ANG = 1 or DRUCKEN_AUFTR = 1 )
order by MAUFJOB.AUFTRNR, MAUFJOB.DATUM, MAUFJOB.UHRZEITVON, MAUFJOB.UHRZEITBIS

Diese Abfrage holt die Termine zu der Auftragsnummer, die aus den Rechnungspositionen (bei Sammelrechnungen) kommt. Zusätzlich wir die Terminart-Bezeichnung, einige Auftragsdaten und die Adressen der Termine geholt.

Siehe auch:

7.2 Unterbericht einfügen

Um die Termine zu einer Rechnungsposition einzufügen, erstellt man ein Child-Band und fügt einen Unterbericht ein. Dort verlinkt man ein Master-Band mit der Abfrage oben, z.B. mit dem Namen "Auftragstermine".

Die Termine sollen aber nur unter der Überschrift (des Kapitels) erscheinen, also wird das Band ein Child-Band der Gruppe für die Kapitel-Überschriften:

FastReport Data 05 ChildAuftragstermine.png


Der Unterbericht enthält ein MasterData-Band mit den Feldern aus der Abfrage der Auftragstermine:

FastReport Data 05 ChildAuftragstermineUnterbericht.png

7.3 Abfrage neu starten, Band ausblenden per Code

Um die Abfrage auf die Position zu beziehen und das Band nur an der gewünschten Stelle einzublenden, kann man folgenden Code verwenden:

procedure ChildAuftragstermineOnBeforePrint(Sender: TfrxComponent);
begin
  qryAuftragstermine.Close;             // Abfrage schließen. Darin stehen bis jetzt alle Termine zum Auftrag der ERSTEN Rechnungsposition!

  // Nur Termine drucken, wenn die Kapitelposition die Überschrift ist und kein Kapitel aus einem Auftrag:
  // Erkannt wird das über die Felder
  //      <Positionen."AusAuftrKapitel"> entspricht in der Datenbank "AUS_POSNR > 0" (Kapitel aus Auftrag)
  // oder "AUS_UNTPOSNR=0" (Position)
  if <Positionen."AusAuftrKapitel"> > 0 then
    ChildAuftragstermine.Visible := False
  else
  begin
    ChildAuftragstermine.Visible := True;
    qryAuftragstermine.Open;            // Abfrage neu öffnen. Darin stehen jetzt alle Termine zum Auftrag der AKTUELLEN Rechnungsposition!
  end;
end;