Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Werkzeuge (https://www.delphipraxis.net/63-sonstige-werkzeuge/)
-   -   FastReport TfrxUserDataSet Summe ziehen (https://www.delphipraxis.net/216722-fastreport-tfrxuserdataset-summe-ziehen.html)

Ykcim 17. Feb 2025 16:49


FastReport TfrxUserDataSet Summe ziehen
 
Hallo Zusammen,

ich breche mir gerade die Ohren, in einem FastReport, der mit einer TfrxUserDataSet befüllt wird, eine Summe zu erzeugen. Aktuell habe ich ein Übungsprogramm mit ganz einfachen Daten, die ich aus einem JSONArray heraushole:
Delphi-Quellcode:
procedure TForm1.btnCreateLabel1Click(Sender: TObject);
var  Rprt: TfrxReport;
      frxData: TfrxComponent;
      fUDataSet: TfrxUserDataSet;
begin
   Rprt:= TfrxReport.Create(nil);
   JsDataProforma:= TJSONArray.Create;
   Try
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"Name": "Müller","Vorname": "Eugen", "Alter": 93}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"Name": "Schmidt","Vorname": "Hans", "Alter": 97}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"Name": "Schulz","Vorname": "Günter", "Alter": 94}') as TJSONObject);
      frxDataSet.RangeEnd := reCount;
      frxDataSet.RangeEndCount:= JsDataProforma.Count;
      Rprt.OnGetValue:= frxRprtProformaOnGetValue;
      Rprt.LoadFromFile(extractfilepath(paramstr(0)) + '.\Res\Test.fr3');

      frxData:= Rprt.FindObject('DataItems');
      (frxData as Tfrxmasterdata).DataSet:= frxDataSet;

      Rprt.ShowReport(True);
   Finally
      //Muss noch befüllt werden!
   End;
end;
In dem OnGetValue Event des Report lasse ich die Werte in das frxDataSet laden:
Delphi-Quellcode:
procedure TForm1.frxRprtProformaOnGetValue(const VarName: string; var Value: Variant);
var  JsData: TJSONObject;
      WertAlter: integer;
begin
   JsData:= TJSONObject.Create;
   Try
      if JsDataProforma.Items[frxDataSet.RecNo] is TJSONObject then begin
         JsData:= TJSONObject.ParseJSONValue(TJSONObject(JsDataProforma.Items[frxDataSet.RecNo]).ToString) as TJSONObject;
         Value:= JsData.GetValue<string>(VarName);
      end;
   Finally
      JsData.Free;
   End;
end;
Soweit klappt auch alles. Jetzt möchte ich aber die Summe des Alters (ist nur eine Übung) unter der Tabelle ausgeben. Dazu habe ich ein Band "ReportSummary" unterhalb des MasterData eingefügt und eine TextObject.

In das TextObject habe ich folgendes gesetzt:
Code:
[Sum(<frxDataSet."Alter">.DataItems)]
//Fehlermeldung: Wert <"Alter">.DataItems nicht gefunden (auch ohne Gänsefüßchen)

Code:
[Sum(Alter)]
//Fehlermeldung: Wert Sum(Alter) nicht gefunden

Code:
[sum(DataItems.Alter)]
//Fehlermeldung: Wert DataItems.Alter nicht gefunden

Code:
[Sum(frxDataSet.Alter)]
//Fehlermeldung: Wert frxDataSet.Alter nicht gefunden

Code:
[Sum([frxDataSet."Alter"])]
//Fehlermeldung: Ungültiger Index für Array: frxDataSet."Alter"

DataItems ist der Name des MasterData Bands.
frxDataSet ist der Name des TfrxUserDataSets.

Kann mir jemand sagen, wie ich das Alter summieren kann?

Vielen Dank
Patrick

mytbo 17. Feb 2025 22:29

AW: FastReport TfrxUserDataSet Summe ziehen
 
Zitat:

Zitat von Ykcim (Beitrag 1546305)
Kann mir jemand sagen, wie ich das Alter summieren kann?

Code:
[SUM(<data."Alter">)]
Mit "data" ist der Name (UserName) des DataSets. Siehe auch Artikel Mediator zur Anbindung von FastReport mit Vorschau und/oder Designer.

Bis bald...
Thomas

Ykcim 18. Feb 2025 08:40

AW: FastReport TfrxUserDataSet Summe ziehen
 
Hallo Thomas,

vielen Dank für Deine Antwort. Leider habe ich damit keinen Erfolg. Ich bekommen nach wie vor die Fehlermedeldung: Wert <frxDataSetUName."Alter"> nicht gefunden.
Ich habe bewusste den UserNamen des DataSets geändert, weil dort der DataSet-Name eingetragen war und ich einen Unterschied haben wollte.

Ich habe mir Deinen Artikel durchgelesen und auch das Beispiel heruntergeladen. Leider habe Deinen Hinweis auf eine Beschreibung, wie man mit eine TfrxUserDataSet eine Summe zieht dort nicht gefunden.

Hast Du noch eine Idee, was ich falsch mache? Das muss doch möglich sein. Leider habe ich in der Dokumentation keinen Hinweis auf die Vorgehensweise mit einem TfrxUserDataSet gefunden und die beschriebene Vorgehensweise mit einem TfrxDataSet scheint nicht zu funktionieren - oder ich stelle mich gerade nicht gut an...

Vielen Dank
Patrick

Ykcim 18. Feb 2025 17:56

AW: FastReport TfrxUserDataSet Summe ziehen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Zusammen,

ist die Frage schlecht erklärt oder so einfach?

Ich habe leider kein Beispiel im Internet oder im Handbuch für TfrxUserDataSet gefunden...

Ich habe es, damit ich weiterkomme, jetzt so gelöst, aber schön ist etwas anderes...

Delphi-Quellcode:
procedure TForm1.btnCreateLabel1Click(Sender: TObject);
var  Rprt: TfrxReport;
      frxData: TfrxComponent;
begin
   Rprt:= TfrxReport.Create(nil);
   JsDataProforma:= TJSONArray.Create;
   Try
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "1","description": "Paket englisch", "price": "20,50", "mwst": "0,19"}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "1","description": "Paket französisch", "price": "25,50", "mwst": "0,19"}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "1","description": "Paket deutsch", "price": "30,50", "mwst": "0,19"}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      JsDataProforma.AddElement(TJSONObject.ParseJSONValue('{"qty": "","description": "", "price": "", "mwst": ""}') as TJSONObject);
      frxDataSet.RangeBegin:= rbFirst;
      frxDataSet.RangeEnd:= reCount;
      frxDataSet.RangeEndCount:= JsDataProforma.Count;
      Rprt.OnGetValue:= frxRprtProformaOnGetValue;
      Rprt.LoadFromFile(extractfilepath(paramstr(0)) + '.\Res\Test.fr3');

      frxData:= Rprt.FindObject('DataItems');
      (frxData as Tfrxmasterdata).DataSet:= frxDataSet;

      Rprt.ShowReport(True);
   Finally
      Rprt.Free;
   End;
end;
Und im OnGetValue dann wild herumgestrikt...

Delphi-Quellcode:
procedure TForm1.frxRprtProformaOnGetValue(const VarName: string; var Value: Variant);
var  JsData, JsPrewData: TJSONObject;
      qtyValue, totalValue, priceValue, nettoKum, mwstKum, bruttoKum, mwst: string;
begin
   if JsDataProforma.Items[frxDataSet.RecNo] is TJSONObject then begin
      JsData:= TJSONObject(JsDataProforma.Items[frxDataSet.RecNo]);
      if frxDataSet.RecNo = 0 then begin
         nettoKum:= '0';
         bruttoKum:= '0';    //Immer nettoKum * mitgeliefertem MwSt-Satz
         mwstKum:= '0';
      end
      else begin
         JsPrewData:= TJSONObject(JsDataProforma.Items[frxDataSet.RecNo -1]);
         JsPrewData.TryGetValue<string>('netto', nettoKum);
         nettoKum:= StringReplace(nettoKum,' €','',[]);
         nettoKum:= StringReplace(nettoKum,'.','',[rfReplaceAll]);
         JsPrewData.TryGetValue<string>('mwstKum', mwstKum);
         mwstKum:= StringReplace(mwstKum,' €','',[]);
         mwstKum:= StringReplace(mwstKum,'.','',[rfReplaceAll]);
         JsPrewData.TryGetValue<string>('brutto', bruttoKum);
         bruttoKum:= StringReplace(bruttoKum,' €','',[]);
         bruttoKum:= StringReplace(bruttoKum,'.','',[rfReplaceAll]);
      end;

      Value:= JsData.GetValue<string>(VarName);
      if VarName = 'price' then begin
         Try
            if   (JsData.TryGetValue<string>('price', priceValue)) and
                  (JsData.TryGetValue<string>('qty', qtyValue)) and
                  (StringReplace(priceValue,' ','',[rfReplaceAll]) <> '') and
                  (StringReplace(qtyValue,' ','',[rfReplaceAll]) <> '') then begin
               totalValue:= FloatToStr(StrToFloat(priceValue) * StrToInt(qtyValue));
               nettoKum:= FloatToStr(StrToFloat(nettoKum) + StrToFloat(totalValue));
               JsData.AddPair('total', Format('%2n',[StrToFloat(totalValue)]) + ' €');
               if (JsData.TryGetValue<string>('mwst', mwst)) and
                  (StringReplace(mwst,' ','',[rfReplaceAll]) <> '') then begin
                  mwstkum:= FloatToStr(StrToFloat(nettoKum) * StrToFloat(mwst));
                  bruttoKum:= FloatToStr(StrToFloat(nettoKum) * (1 + StrToFloat(mwst)));
               end;
            end
            else begin
               JsData.AddPair('total', '');
            end;
            if StringReplace(Value,' ','',[rfIgnoreCase, rfReplaceAll]) <> '' then begin
               Value:= Value + ' €';
            end;
            JsData.AddPair('netto', Format('%2n',[StrToFloat(nettoKum)]) + ' €');
            JsData.AddPair('brutto', Format('%2n',[StrToFloat(bruttoKum)]) + ' €');
            JsData.AddPair('mwstKum', Format('%2n',[StrToFloat(mwstKum)]) + ' €');
            if (StringReplace(mwst,' ','',[rfReplaceAll]) = '') then begin   //Nur zum Anzeigen unterhalb der Tabelle
               JsPrewData.TryGetValue<string>('mwst', mwst);
               JsData.RemovePair('mwst');
               JsData.AddPair('mwst', mwst);
            end;
         Except
            Value:= '';
         End;
      end;

   end;
end;
Was dann rauskommt sieht so aus, wie in dem Bild.

Vielen Dank
Patrick

mytbo 18. Feb 2025 21:07

AW: FastReport TfrxUserDataSet Summe ziehen
 
Zitat:

Zitat von Ykcim (Beitrag 1546341)
Was dann rauskommt sieht so aus, wie in dem Bild.

Die Mehrwertsteuer könnte für jeden Posten unterschiedlich sein. Daher verwendet man am besten zwei DataSets: eines für die Posten in der Liste und eines für die Zusammenfassung (MwSt-Satz, Betrag) der Liste. Über diesen kann man dann die Gesamtsumme berechnen. Allgemein erledigt man die Berechnungen im Programm-Quelltext und übergibt die Ergebnisse als mundgerechte Häppchen an den FastReport. Für einfache Lösungen findest du Anregungen in meinen Beiträgen hier im Forum.

Bis bald...
Thomas

Ykcim 19. Feb 2025 09:59

AW: FastReport TfrxUserDataSet Summe ziehen
 
An unterschiedliche MwSt-Sätze hatte ich auch schon gedacht, war aber nicht auf die Lösung mit dem zweiten TfrxUserDataSet gekommen. Muss ich mir mal zusammenbasteln.

Aber grundsätzlich fühlt sich meine Lösung nach Gefrickel an. Ist das auch so oder muss man das Thema mit der Summierung so lösen?
Ich würde halt viel lieber die vorhandenen Summen-Funktionen nutzen...

Hat jemand vielleicht ein Beispiel, wo eine Summenfunktion mit einem TfrxUserDataSet umgesetzt wurde?

Vielen Dank
Patrick

Frickler 20. Feb 2025 09:11

AW: FastReport TfrxUserDataSet Summe ziehen
 
Gibts nen besonderen Grund, warum Du nicht einfach Memory DataSets (z.B. TClientDataSet) verwendest, und dann mit den "normalen" Summationsfunktionen innerhalb des Reports arbeitest?

Ykcim 21. Feb 2025 09:09

AW: FastReport TfrxUserDataSet Summe ziehen
 
Guten Morgen,

nein, die gibt es nicht. Ich habe noch nicht viel mit FastReport gemacht, daher fehlt es mir an Erfahrung und Wissen über die verschiedenen Möglichkeiten. Ich habe Google und das Manual bemüht und hatte den Eindruck, dass ein TfrxUserDataSet eine saubere Lösung wäre. Daher bin ich den Weg gegangen.

Wenn die Verwendung eines anderen DataSets funktioniert und ich mehr Möglichkeiten damit habe, bin ich dafür absolut offen.

Hättest Du einen Schnipsel für mich?

Vielen Dank
Patrick

Frickler 21. Feb 2025 12:11

AW: FastReport TfrxUserDataSet Summe ziehen
 
Leg Dir pro Tabelle ein TClientDataSet an. Felder anlegen z.B. per Feldeditor. Für das Reporting musst Du dann die Daten aus JSON "umfüllen" ins ClientDataSet mit den üblichen Standard Datenbankoperationen:
Delphi-Quellcode:
cds.Append;
cds.FieldByName('price').AsFloat := xxxx;
[...]
cds.Post;
usw.

Du brauchst dann pro ClientDataSet eine TfrxDBDataSet Komponente. In DataSet verbindest Du das ClientDataSet, in "Username" gibst Du an, wie die Tabelle im Report heißen soll.

Ein Tipp: Das ClientDataSet hat eine Methode "SaveToFile", damit kannst Du die eingespeicherten Daten abspeichern. Mach das ein Mal für alle ClientDataSets und dann kommentierst Du das aus. Für das Design des Reports gehst Du dann hin, klickst die ClientDataSets mit Rechts an und gehst auf "aus MyBase Tabelle laden" und gibst als Datei die zuvor per SaveToFile gespeicherten Daten an. Die werden dann ins ClientDataSet geladen und, wenn Du Dein Programm startest und den Reportdesigner aufrufst, direkt angezeigt, so dass Du mit "echten Daten" den Report designen kannst, einschließlich aller Summen.
Die ClientDataSets wieder leeren kannst Du mit Rechtsklick und "Daten löschen".


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:22 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz