AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein mORMot: Mediator zur Anbindung von FastReport mit Vorschau und/oder Designer
Thema durchsuchen
Ansicht
Themen-Optionen

mORMot: Mediator zur Anbindung von FastReport mit Vorschau und/oder Designer

Ein Thema von mytbo · begonnen am 15. Sep 2022 · letzter Beitrag vom 30. Mär 2023
Antwort Antwort
mytbo

Registriert seit: 8. Jan 2007
472 Beiträge
 
#1

mORMot: Mediator zur Anbindung von FastReport mit Vorschau und/oder Designer

  Alt 15. Sep 2022, 23:24
Im sechsten Artikel der mORMot Vorstellungsreihe wird gezeigt, wie mittels eines Mediators Daten im JSON-Format für die Anzeige in FastReport aufbereitet werden. Mediatoren sind eine elegante Möglichkeit Funktionalität zu kapseln und die einfache und sichere Anwendung zu erreichen. Wieder mit dabei ist die eierlegende Wollmilchsau DocVariant. Die Beispiel-Anwendung beinhaltet den Endbenutzer-Bericht-Designer von FastReport. Für alle Leser, die nur die eingeschränkte Embarcadero Edition kennen, eine Möglichkeit die Vollversion in Augenschein zu nehmen. Nicht alle Funktionen sind freigeschaltet! Die enthaltenen Verweise zur Dokumentation verlinken zur aktuell verfügbaren mORMot1 Hilfe. Für das Beispiel wird mORMot2 verwendet. Die Namen für Klassen und Funktionen können sich leicht unterscheiden.

Eins, zwei, drei, fertig ist die Bericht-Einbinderei
Zumindest dann, wenn man sich Unterstützung holt. Schon die Gang of Four (GoF) hat in ihrem Buch Design Patterns von 1994 das Muster Vermittler beschrieben. Vermittler/Mediator ist im wörtlichen Sinne zutreffend. Wer schon einige Artikel von mir gelesen hat, weiß, der Mediator hat einen festen Platz im Repertoire. Oft ist das Problem, dass die gezeigten Anwendungsbeispiele unterkomplex sind. Heute zeige ich mehr Möglichkeiten am Beispiel eines Inhouse Tools. Das Beschleunigungspotenzial für die Anwendungsentwicklung lässt sich an einem ReportMediator gut darstellen. Viele sich wiederholende Schritte werden automatisch erledigt und der Objektinspektor ist außen vor. Anmerkung: Der Begriff Mediator wird im Text allgemeiner verwendet, als es der Kontext des gleichnamigen Design-Patterns vorgibt.

Im Anhang befindet sich der Sourcecode und das ausführbare Programm. Der Sourcecode der Beispiel-Anwendung kann nicht kompiliert werden. Der Mediator hat die Fähigkeit, verschiedene Datenquellen anzubinden. Dazu zählen die generischen Typen der mORMot und Spring4D Collections. Aber auch proprietäre Libraries von FastReport, DevExpress usw. werden verwendet. Den Mediator ausschließlich auf freie Bibliotheken umzuschreiben, sprengt den Rahmen eines Artikels. Die besprochenen Auszüge vermitteln aber einen guten Überblick über die grundsätzliche Herangehensweise. Disclaimer: Der Sourcecode ist weder getestet noch optimiert. Die Benutzung der zur Verfügung gestellten Materialien erfolgt auf eigene Gefahr.

Vier Schritte ins Glück
Grundsätzlich sind nur wenige Schritte notwendig, einen Bericht einzubinden:
  • Für jeden Bericht einen eigenen ReportMediator instanttieren.
  • Provider für die Layout-Daten instanttieren und zuweisen.
  • DataSet(s) und Variablen hinzufügen.
  • Vorschau oder Designer ausführen.
Delphi-Quellcode:
var
  data: TDocVariantData;
begin
  FReportMediator := TReportMediator.Create(Self);
  FReportMediator.ReportFileProvider := TReportFileFR3Provider.Create(FReportFileName);

  // Add DataSet
  data.InitJsonFromFile(dataSetFileName, JSON_FAST_FLOAT);
  FReportMediator.AddDocVariantDataSet(GetFileNameWithoutExt(ExtractFileName(dataSetFileName)), Variant(data), []);
  
  // Add variables
  data.InitJsonFromFile(dataVarsFileName, JSON_FAST_FLOAT);
  FReportMediator.AddDocVariantVariables('ReportVars', data);
  
  FReportMediator.ShowReport(0, {IsEditable=} True);
Den Weg über die universelle DocVariant Ladefunktion bin ich nur gegangen, um überhaupt ein wenig Sourcecode für die weiteren Erläuterungen zeigen zu können. Die spezialisierten Funktionen erledigen das in einem Aufwasch. Das Gleiche gilt für das direkte Hinzufügen von Objekten, Listen, Arrays und was man sonst noch verarbeiten kann.

Die DocVariant Ladefunktion
Auch alle Add*-Funktionen des Mediators realisieren sich aus wenigen Zeilen Sourcecode. Der Grund ist die sehr einfache Methode, wie FastReport Daten rekrutiert. Die Daten werden über eine Event-Funktion zugeführt. Mehr dazu im nächsten Abschnitt. Erst einmal die AddDocVariantDataSet Funktion:
Delphi-Quellcode:
function TReportMediator.AddDocVariantDataSet(const pmcName: String; const pmcDataVariant: Variant;
  const pmcFilterFields: array of RawUtf8): TCustomReportDataSet;
var
  dataSet: TDocVariantReportDataSet;
begin
  dataSet := TDocVariantReportDataSet.Create(FDataSetRoot, pmcName);
  dataSet.GetFieldNames(pmcDataVariant, pmcFilterFields);
  dataSet.PrepareData(pmcDataVariant);
  Result := dataSet;
end;
Die Angabe Name wird im Bericht für die Bezeichnung der Datenquelle verwendet. FilterFields bietet die Möglichkeit, unerwünschte Felder der Datenquelle auszublenden.

Der DocVariant DataSet
Um einen eigenen DataSet zu verwenden, gibt es in FastReport die Klasse TfrxUserDataSet. Die Klasse ist minimalistisch. Sie enthält nur wenige Eigenschaften zur Steuerung der Datenzulieferung. Die zwei wichtigsten sind: Fields, was nichts anderes ist als eine Stringliste zur Definition der Feldnamen, und das Ereignis OnGetValue. Der Prototyp ist in der Unit frxClass wie folgt definiert: TfrxGetValueEvent = procedure(const VarName: String; var Value: Variant) of object; Als Alternative gibt es das Ereignis OnNewGetValue, das wie folgt aussieht: TfrxNewGetValueEvent = procedure(Sender: TObject; const VarName: String; var Value: Variant) of object; Die Definition für den DataSet beschränkt sich auf wenige Zeilen:
Delphi-Quellcode:
TDocVariantReportDataSet = class(TCustomReportDataSet)
private
  FDataVariant: TDocVariantData;
  procedure DoDataGetValue(const pmcName: String; var pmvValue: Variant);
public
  procedure GetFieldNames(const pmcData: Variant; const pmcFilterFields: array of RawUtf8); reintroduce;
  procedure PrepareData(const pmcData; pmOnOwnGetValue: TReportDataSetGetValueEvent = Nil); override;
end;
Die Klasse TCustomReportDataSet ist ein direkter Nachfahre von TfrxUserDataSet. Die Implementation erklärt sich von selbst:
Delphi-Quellcode:
procedure TDocVariantReportDataSet.DoDataGetValue(const pmcName: String; var pmvValue: Variant);
begin
  case FDataVariant.Kind of
    dvObject:
      pmvValue := FDataVariant.Value[pmcName];
    dvArray:
      pmvValue := FDataVariant.Values[RecNo].Value[pmcName];
  end;
end;

procedure TDocVariantReportDataSet.GetFieldNames(const pmcData: Variant; const pmcFilterFields: array of RawUtf8);
var
  i: Integer;
  run: PDocVariantData;
  fieldName: RawUtf8;
begin
  Fields.Clear;
  run := _Safe(pmcData);
  case run.Kind of
    dvObject:
      ;
    dvArray:
      run := _Safe(run.Value[0]);
    else
      Exit; //=> dvUndefined
  end;

  for i := 0 to High(run.Names) do
  begin
    fieldName := run.Names[i];
    if FindPropName(pmcFilterFields, fieldName) < 0 then
      Fields.Add(Utf8ToString(fieldName));
  end;
end;

procedure TDocVariantReportDataSet.PrepareData(const pmcData);
begin
  OnGetValue := DoDataGetValue;

  FDataVariant := _Safe(Variant(pmcData))^;
  case FDataVariant.Kind of
    dvObject:
      RangeEndCount := 1;
    dvArray:
      RangeEndCount := FDataVariant.Count;
    else
      RangeEndCount := 0;
  end;

  RangeBegin := rbFirst;
  RangeEnd := reCount;
  First;
end;
Wie man sieht, spielt es keine Rolle, ob die Datenquelle vom Typ Objekt oder Array ist. Einschränkend ist, dass nur die erste Ebene unterstützt wird. Zur Erinnerung: DocVariant ist eine beliebig komplexe Datenstruktur aus Objekt(en) und/oder Arrays oder aus Kombinationen von beiden. Die Funktion _Safe stellt sicher, dass es immer einen DocVariant gibt. Notfalls einen leeren Fake DocVariant.

Die Beispiel-Anwendung: kurz und bündig
Das Programm ist eine Spielumgebung für mORMot und FastReport. Es stehen fünf Funktionen zur Verfügung: Neues Projekt, Projekt öffnen und schließen, Berichtvorschau oder Berichtdesigner anzeigen. Um gleich loslegen zu können, ist ein Projekt "Test01" fertig erstellt. Grundsätzliches zur Bedienung:
  • Jedes Projekt hat seinen eigenen Ordner. Das voreingestellte Projects Verzeichnis befindet sich unterhalb des Programm-Verzeichnisses.
  • Der Name der FastReport Layout-Datei ist der Verzeichnisname plus Erweiterung .fr3. Sie wird durch das Speichern eines Berichts im Designer erstellt.
  • Der Name der Variablendatei im JSON Objekt Format ist der Verzeichnisname plus Erweiterung .variables. Beim Anlegen eines neuen Projekts wird eine leere Datei erstellt.
  • Alle Dateien mit der Endung *.json werden als DataSets eingebunden. Der Name des DataSets ist der Dateiname. Es wird das JSON Objekt und Array Format unterstützt. Ein DataSet wird durch Hinzufügen der JSON-Datendatei in das Projektverzeichnis in den Bericht eingebunden. Drag-and-drop in/aus der Dateiansicht wird unterstützt.
Viel Spaß beim Spielen. Ich hoffe, ich habe am Anfang nicht zu viel versprochen und das Weiterlesen hat sich gelohnt.

Zusammenfassung
Die Möglichkeiten zum Einsatz eines Mediators enden hier nicht. Konsequent setzt es sich bei der Anbindung an die GUI fort. Ob ein Button die Vorschau und/oder den Designer aufruft, warum die Eigenschaft Caption, Image oder ein OnClick Ereignis im Objektinspektor zuweisen. Die Registrierung mit BindButton(btnPrintPreview, TReportMediator.BuildReportID(2008)); reicht aus, egal ob 10x oder 100x in einer Anwendung. Auch der heutige Artikel war vor allem durch die Notwendigkeit zum radikalen Kürzen eine besondere Herausforderung. Bei dieser Aktion besteht immer die Gefahr, dass der rote Faden zum Verständnis verloren geht. Ich hoffe, die Ausführungen blieben nachvollziehbar.

mORMot ist gut dokumentiert. Die Hilfe umfasst mehr als 2500 Seiten. Davon enthalten die ersten ca. 650 Seiten einen sehr lesenswerten allgemeinen Teil, der Rest ist API Dokumentation. mORMot muss nicht in der IDE installierten werden! Es reicht aus, die entsprechenden Bibliothekspfade einzufügen. Es stehen viele Beispiele und ein freundliches Forum zur Verfügung.

In der mORMot Reihe bisher veröffentlicht:
  1. ORM und DocVariant kurz vorgestellt
  2. ZIP-Datei als Datenspeicher mit verschlüsseltem Inhalt
  3. Einführung in methodenbasierte Services - Server und Client
  4. Einführung in Interface-based Services - Server und Client
  5. Mustache Editor mit integriertem HTTP-Server zum Anzeigen von HTML Seiten
Bis bald...
Thomas
Angehängte Dateien
Dateityp: zip TestFastReportMediator.zip (3,64 MB, 45x aufgerufen)

Geändert von mytbo (16. Sep 2022 um 14:53 Uhr) Grund: Kopierfehler korrigiert
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: mORMot: Mediator zur Anbindung von FastReport mit Vorschau und/oder Designer

  Alt 23. Sep 2022, 12:22
Vielen Dank!!!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
charly52

Registriert seit: 2. Sep 2018
Ort: Salem, Baden
102 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: mORMot: Mediator zur Anbindung von FastReport mit Vorschau und/oder Designer

  Alt 30. Mär 2023, 17:49
Hi Thomas,

erstmal vielen Dank für die diversen Artikel zu mORMot.
Habe mir jetzt Version 2 herunter geladen und versuche einen Einstieg.
Dazu habe ich mir auch TestFastReportMediator.zip geholt.

Betrift die gelb markierte Bemerkung
Zitat:
Der Sourcecode der Beispiel-Anwendung kann nicht kompiliert werden.
die Komponenten von DevExpress und oder auch die Klasse
Code:
TReportMediator
Ist TReportMediator ein Bestandteil von mORMot?

Charly
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
472 Beiträge
 
#4

AW: mORMot: Mediator zur Anbindung von FastReport mit Vorschau und/oder Designer

  Alt 30. Mär 2023, 19:54
Ist TReportMediator ein Bestandteil von mORMot?
Der ReportMediator ist eine In-House Komponente und nicht Bestandteil von mORMot. Das Thema Mediator wurde von mir in mehreren Beiträgen behandelt. Das Problem einfacher Beispiele ist, dass sie die Mächtigkeit dieses(r) Pattern nicht adäquat verdeutlichen. Von Zeit zu Zeit werden im DP Forum Fragen zu FastReport gestellt. Nicht immer gelingt es dem Fragesteller, das Problem nachvollziehbar zu beschreiben. Abhilfe wäre, das Berichtsdesign ohne Kopplung an Programmcode offenzulegen. Die Idee war, mit wenigen Zeilen Quelltext ein Programm zu erstellen, das die Arbeit eines Mediators im Zusammenspiel mit mORMot in der Praxis zeigt und zusätzlich einen gewissen Nutzen hat. Ein Beispiel mit Quelltext für einen ReportDataSet findest du in diesem Beitrag. Wie ein mORMot DocVariant mit gleicher Technik angebunden wird, ist im Artikel oben vollständig beschrieben.

Bis bald...
Thomas
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz