Fastreport 4 Beispiel für eine Rechnung das Prinzip n. verst
Hallo Zusammen,
Gibt es ein Beispiel für einen Rechnungs-Report? Irgendwie hab ich das Prinzip nicht verstanden. Wie wird bitte ein Report für eine Rechnung erstellt wenn ich zwei DataSets habe. Das MasterDataset enthält alle Rechnungskopfdaten und das DetailDataset die Rechnungspositionen. Eine Rechnung kann über mehrere Seiten gehen und es werden immer mehr wie eine Rechnung in einem Druckjob gedruckt. Auf welches Band werden die Rechnungskopfdaten platziert und wo die Rechnungspositionen. Ich habe ein Report dafür erzeugt. Die Rechnung wird richtig gedruckt wenn nur ein Datensatz zu drucken ist oder wenn ich TfrxIBODataset.RangeBegin:=rbCurrent und TfrxIBODataset.RangeEnd:=rbCurrent einstelle. Ich habe auf dem PageHeaderBand die Kopfdaten der Rechnung abgelegt wie Adresse, Datum u.s.w. Auf das MasterDataBand die Rechnungsnummer und auf das DetailDataBand die PositionNr, ArtikelNr, Bezeichnung,Preis u.s.w. Wenn das DataSet mehr wie einen Datensatz enthält, wird auf der ersten Seite im PageHeaderBand die Adresse des letzen Datensatzes angezeigt. Ich hatte neulich ein ähnliches Problem und habe es lösen können indem ich Gruppiert habe. Gefühlsmäßig ist dieser Weg nicht richtig. Da gibt es sicherlich einen besseren Weg. Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Liste der Anhänge anzeigen (Anzahl: 1)
Wenn es mit nur einer Rechnung funktioniert mach es Dir doch einfach und "Prepare" alle Einzelrechnungen. Dann zeigst Du den kompletten Report an oder druckst ihn aus (in dem Beispiel habe ich sogar 3 Datasets, Belegkopfdaten, Positionsdaten und Summendaten mit mehreren Mehrwert-Steuersätzen):
Delphi-Quellcode:
Die statischen Werte aus BKopf landen im TFrxPageHeader sowie TfrxReportSummary. Die Positionsdaten und Summendaten befinden sich in zwei TFrxMasterData.with TPrintModule.Create(Application) do begin // BelegIds ist ein dynamisches Array mit den IDs der Belege ;) for i := 0 to High(BelegIds) do begin qryBKopf.ParamByName('Id').AsFloat := BelegIds[i]; qryBKopf.Open; qryBPos.Open; qrySummen.Open; if Length(BelegIds) > 1 then frxReport1.ReportOptions.Name := Format('%s - %s',['Sammeldruck', qryBelegart.FieldByName('Beleg_text').AsString]) else frxReport1.ReportOptions.Name := Format('%1:s %0:s',[qryBKopf.FieldByName('Bnr').AsString, qryBelegart.FieldByName('Beleg_text').AsString]); frxReport1.PrepareReport(False); qryBKopf.Close; end; frxReport1.ShowPreparedReport; Free; end; |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Hallo Union,
ja so ähnlich mache ich es derzeit auch. Ein Select auf jede einzelne Rechnung und danach drucken. Du machst es noch besser indem Du alle Rechnungen in ein File zusammen fast. Coole Idee werde ich übernehmen. Aber ich finde das muss doch auch so gehen. Eigentlich ist Rechnung drucken doch das Prinzip des Master/Detail-Reports. Das Problem ist nur, dass das PageHeaderBand mit dem MasterBand nicht synchronisiert. Interessant ist, dass die erste Rechnung die Kopfdaten der letzen Rechnung druckt. Ab der zweiten Rechnung jedoch funkt alles wie es soll. Das ist ein refresh Problem, möglicherweise ist das auch ein Bug. Oder ist der Reporter wirklich so Designed wie Du es gemacht hast? Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Ich habe die Funktion mal umgeschrieben, so dass sie mit nur einem Open auskommt (durch ersetzen der where-Klausel):
Delphi-Quellcode:
Die Rechnungen werden alle gedruckt wie im Einzeldruck. Nur die #Page Variablen stimmen natürlich nicht mehr, deshalb drucke ich die ja (wie im letzen Psoting) normalerweise einzen. Dann brauche ich mir die Seiten nicht selber zu numerieren.
procedure TfrmBelegKopf.PrintSelectedBeleg;
var i : integer; BelegId : extended; BelegIds : array of extended; BelegIDString : string; begin for i := 0 to cxGridBelegeDBTableView1.Controller.SelectedRowCount -1 do begin if cxGridBelegeDBTableView1.Controller.SelectedRows[i] is TcxGridDataRow then begin BelegId := cxGridBelegeDBTableView1.Controller.SelectedRows[i].Values[0]; SetLength(BelegIds, Length(BelegIds)+1); BelegIds[High(BelegIds)] := BelegId; end; end; if Length(BelegIds) > 0 then begin // IN(...) String zusammensetzen for i := 0 to High(BelegIds) do begin BelegIDString := BelegIDString+IntToStr(trunc(BelegIDs[i]))+','; end; // letztes Komma abschneiden BelegIDString := copy(BelegIDString,1,length(BelegIDString)-1); with TPrintModule.Create(Application) do begin // Where ersetzen qryBKopf.SQL.Strings[qryBKopf.SQL.Count-1] := 'where bkopf.id in ('+BelegIDString+')'; qryBKopf.Open; qryBPos.Open; qrySummen.Open; if Length(BelegIds) > 1 then frxReport1.ReportOptions.Name := Format('%s - %s',['Sammeldruck', qryBelegart.FieldByName('Beleg_text').AsString]) else frxReport1.ReportOptions.Name := Format('%1:s %0:s',[qryBKopf.FieldByName('Bnr').AsString, qryBelegart.FieldByName('Beleg_text').AsString]); frxReport1.PrepareReport(False); qryBKopf.Close; frxReport1.ShowPreparedReport; Free; end; end; end; Kopf und Fussdaten sind die richtigen, da wird nichts vermischt. Wie hast Du denn Deine Datasets verbunden? Ich habe eine ganz normale Verbindung über DataSource der Kopfdaten in die DataSourcen der Positions- und Summendaten gemacht. Ich verwende hier keine speziellen TFrx...DataSet Komponenten. Vielleicht steckt ja auch da der Fehler drin. |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Hallo Union,
würde mich nicht wundern, wenn es sich um einen Bug handelt. Ich selbst habe schon mehrere sollcher seltsamen "Phänomene" in der aktuellen Version von Fastreport gefunden. Gruß Micha |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Ich hab das jetzt mal mit TFrxDataSet Komponenten im Designer probiert. Der Trick ist, dass man nicht nur die TFrxParams setzen muß, sondern auch das Feld Master auf die Kopfdatenmenge:
Code:
Läßt man das Setzen des Master weg, so gibt es tatsächlich ziemliches Durcheinander. Der dazugehörige (scheußliches Design) Testreport:
Rgkopf : TFrx...DataSet
SQL: Select * from Rgkopf Rgpos : Tfrx...DataSet SQL: Select * from RgPos where rgkopf_id = :id Params.Name : id Params.Datatype: ftFloat Params.Value: <RgKopf."ID"> Master: RGKopf
XML-Code:
<?xml version="1.0" encoding="utf-8"?>
<TfrxReport Version="4.5" DotMatrixReport="False" IniFile="\Software\Fast Reports" PreviewOptions.Buttons="4095" PreviewOptions.Zoom="1" PrintOptions.Printer="Default" PrintOptions.PrintOnSheet="0" ReportOptions.Compressed="True" ReportOptions.CreateDate="39490,6341565972" ReportOptions.Description.Text="" ReportOptions.LastChange="39617,448543287" ScriptLanguage="PascalScript" ScriptText.Text="begin end." StoreInDFM="False" PropData="044C656674021003546F70020808446174617365747301010C2600000020446174615365743D2252674B6F70662220446174615365744E616D653D2252674B6F70662200010C2400000020446174615365743D225267504F732220446174615365744E616D653D225267506F73220000095661726961626C65730100055374796C650100"> <TfrxDataPage Name="Data" Height="1000" Left="0" Top="0" Width="1000"> <TfrxADSQuery Name="RgKopf" UserName="RgKopf" CloseDataSource="True" FieldAliases.Text="" IgnoreDupParams="False" SQL.Text="select top 3 * from rgkopf " DatabaseName="AdsConnection" PropData="05704C65667402640470546F7002540A506172616D65746572730100"/> <TfrxADSQuery Name="RgPOs" UserName="RgPos" CloseDataSource="True" FieldAliases.Text="" Master="RgKopf" IgnoreDupParams="False" SQL.Text="select * from rgpos where rgkopf_id = :id " DatabaseName="AdsConnection" PropData="05704C656674039C000470546F7002540A506172616D657465727301010C48000000204E616D653D226964222044617461547970653D226674466C6F6174222045787072657373696F6E3D22262336303B52674B6F70662E262333343B4944262333343B262336323B220000"/> </TfrxDataPage> <TfrxReportPage Name="Page1" PaperWidth="210" PaperHeight="297" PaperSize="9" LeftMargin="0" RightMargin="0" TopMargin="0" BottomMargin="0" ColumnWidth="0" ColumnPositions.Text="" HGuides.Text="" VGuides.Text=""> <TfrxMasterData Name="MasterData1" Height="22,67718" Left="0" Top="16" Width="793,7013" ColumnWidth="0" ColumnGap="0" DataSet="RgKopf" DataSetName="RgKopf" RowCount="0"> <TfrxMemoView Name="RgKopfRGNR" Left="0" Top="0" Width="158,74026" Height="18,89765" DataField="RGNR" DataSet="RgKopf" DataSetName="RgKopf" Font.Charset="1" Font.Color="-16777208" Font.Height="-13" Font.Name="Arial" Font.Style="1" ParentFont="False" Text="[RgKopf."RGNR"]"/> <TfrxMemoView Name="RgKopfID" Left="166,29932" Top="0" Width="79,37013" Height="18,89765" DataField="ID" DataSet="RgKopf" DataSetName="RgKopf" Font.Charset="1" Font.Color="-16777208" Font.Height="-13" Font.Name="Arial" Font.Style="0" ParentFont="False" Text="[RgKopf."ID"]"/> </TfrxMasterData> <TfrxDetailData Name="DetailData1" Height="22,67718" Left="0" Top="60" Width="793,7013" ColumnWidth="0" ColumnGap="0" DataSet="RgPOs" DataSetName="RgPos" RowCount="0"> <TfrxMemoView Name="RgPosRGKOPF_ID" Left="166,29932" Top="0" Width="79,37013" Height="18,89765" DataField="RGKOPF_ID" DataSet="RgPOs" DataSetName="RgPos" Font.Charset="1" Font.Color="-16777208" Font.Height="-13" Font.Name="Arial" Font.Style="0" ParentFont="False" Text="[RgPos."RGKOPF_ID"]"/> <TfrxMemoView Name="RgPosPOS_NR" Left="264,5671" Top="0" Width="79,37013" Height="18,89765" DataField="POS_NR" DataSet="RgPOs" DataSetName="RgPos" Font.Charset="1" Font.Color="-16777208" Font.Height="-13" Font.Name="Arial" Font.Style="0" ParentFont="False" Text="[RgPos."POS_NR"]"/> <TfrxMemoView Name="RgPosMENGE_SOLL" Left="359,05535" Top="0" Width="79,37013" Height="18,89765" DataField="MENGE_SOLL" DataSet="RgPOs" DataSetName="RgPos" Font.Charset="1" Font.Color="-16777208" Font.Height="-13" Font.Name="Arial" Font.Style="0" ParentFont="False" Text="[RgPos."MENGE_SOLL"]"/> <TfrxMemoView Name="RgPosMENGE_IST" Left="461,10266" Top="0" Width="79,37013" Height="18,89765" DataField="MENGE_IST" DataSet="RgPOs" DataSetName="RgPos" Font.Charset="1" Font.Color="-16777208" Font.Height="-13" Font.Name="Arial" Font.Style="0" ParentFont="False" Text="[RgPos."MENGE_IST"]"/> </TfrxDetailData> </TfrxReportPage> </TfrxReport> |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Hallo Union,
einen Moment bitte. Du schreibst man muss die TFrxParams setzen, habe ich noch nie gemacht! Kann ich auch nicht finden. Wie komme ich da bitte ran? Ebenfalls für mich sehr interessant, das „Feld Master muss auf die Kopfdatenmenge zeigen“. Habe ich auch nicht gemacht und finde nirgends eine Eigenschaft. Wo ist bitte das Zeug versteckt. Das wird vermutlich die Lösung sein. Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Wenn Deine Komponenten das nicht unterstützen, sind sie nicht vollständig implementiert. Sie müssen von TfrxCustomQuery bzw. TfrxCustomTable abgeleitet sein und dann die Properties Master und Params (bei der Query) unterstützen.
|
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Zitat:
In Designer gibt eine unter dem Tab Data eine Komponentenpalette unter anderem auch eine TfrxIB_Query und eine TfrxIB_Table die haben die Propertys Master und Params. Du arbeitest also mit diesen Komponenten. Ich verwende die TfrxIBODataset Komponente die auf ein Form platziert wird! Die Komponente hat keine master und Params. Das ist der Unterschied. Dann habe ich wohl ein Problem. Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
So arbeite ich aber meistens auch. TDataSet Komponente(n) auf Formular, alles verknüpfen und dem Report bekanntmachen mittels TFrxDBDataSet(s). Aber auch bei Deiner TfrxIBODataset-Komponente muß es ja eine Möglichkeit geben, Master-Detail-Verknüpfungen zu machen. Du musst nur rausfinden wie. Die TfrxKomponenten die im Designer benutzt werden verwende ich nur, wenn ich einen User-Designer zur Verfügung stelle. Dann kann / muß sich der Benutzer um alles selber kümmern.
|
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Hallo Union,
um die Verwirrung noch etwas zu verschärfen ;-) habe ich eine Select erzeugt der in einem Record die Adresse, ReNr, und Datum der Rechnung enthält, und zusätzlich NUR ein Artikel aus der Rechnung. Also eine Query, ein Artikel pro Record daraus eine Rechnung erzeugen. Der Report sieht so aus: -------------PageHeaderBand--------- <<< ist das Richtig zweifel zweifel!!! Adresse, RechnungsNr, Datum. -------------MasterDataBand--------- ArtikelNr, Bezeichnung, Preis -------------ChildBand-------------- Rechnungssumme berechnen. -------------PageFooterBand--------- Bankverbindungen bla bla bla Das MasterDataBand verbunden mit der einzigen TfrxIBODataset und MasterDataBand.StartNewPage:=true; sonst nix. Und schon wieder wird NUR bei der ersten Rechnung die Daten der letzen Rechnung für den PageHeader verwendet. MasterData und ChildBand sind richtig. Das Problem ist immer nur bei PageHeaderBand! Sobald die erste Rechnung gedruckt ist, werden alle folgenden Rechnungen richtig gedruckt. Würdest Du mir bitte nochmal bestätigen das in diesem Testreport die Bänder richtig sind. Ich vermute ich darf das PageHeaderBand nicht verwenden. Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Mal ne ganz dumme Frage: Nach dem Open der Query machst Du da ein First? Die Struktur laut Deiner Aufstellung ist ok - ich verwende auch ein PageHeaderband. Ich vermute wirklich einen Knall in den entsprechenden IB-Komponenten in Verbindung mit FR. Ansonsten könntest Du Dich auch mal in news://fasr-reports.public.fastreport.4 umschauen.
|
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Zitat:
Um das herauszufinden, werde ich den gleichen Report mit ADO versuchen. Ein herzliches Dankeschün und eine schöne Zeit. Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Ich weis jetzt woran es liegt.
Es liegt anPrepareReport.
Delphi-Quellcode:
Wenn PrepareReport vor ShowReport ausgeführt wird, dann verhält sich der Reporter so ich beschrieben habe.frxReport1.PrepareReport; frxReport1.ShowReport; PrepareReport geht also alle Datensätze durch und der Datensatzzeiger ist auf dem letzten Record. Würde Du das bitte mal bei Dir testen. Dankeschön. Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Das hat damit nichts zu tun, denn ShowPreparedReport zeigt nur ein fertig erzeugtes WMF an. In meiner auf den BelegIDString umgestellten Funktion von oben wird ja genau dies gemacht und da kommen keine Kopfdaten durcheinander:
Delphi-Quellcode:
Und mit der FR Version kann es auch nichts zu tun haben. Das produktive Druckmodul mit dem ich hier teste wurde am 1.7.2005 mit FR 3.15 erstellt und läuft mittlerweile unter 4.5 - bisher hatte ich das noch nicht. Dann würden schon mal unsere Rechnungen nicht bei der richtigen Adresse ankommen ;)
frxReport1.PrepareReport(False);
qryBKopf.Close; frxReport1.ShowPreparedReport; |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Liste der Anhänge anzeigen (Anzahl: 3)
Hallo Union,
ich fürchte doch. Ich habe ein mini TestProgramm erstellt in Anhang. Wenn Du es testen möchtest, musst Du nur den Path auf die Demo DB der Main-Demo von Fastreport umstellen. Beim ersten Button mache ich das:
Delphi-Quellcode:
Der Report zeigt das richtige Ergebnis.
if not ADOTable1.Active then ADOTable1.open;
ADOTable1.first; frxReport1.ShowReport; Danach das:
Delphi-Quellcode:
Der Report ist falsch.
if not ADOTable1.Active then ADOTable1.open;
ADOTable1.first; frxReport1.PrepareReport; frxReport1.ShowReport; Gerade habe ich in der Docu gelesen das PrepareReport den Report komplett erzeugt. Das ist dan auch die Erklerung. procedure ShowReport(ClearLastReport: Boolean = True); Starts a report and displays the result in the preview window. If the “ClearLastReport” parameter is equal to “False,” then the report will be added to the previously constructed one, otherwise the previously constructed report will be cleared (by default). function PrepareReport(ClearLastReport: Boolean = True): Boolean; Starts a report, without opening the preview window. The parameter assignment is the same as in the “ShowReport” method. If a report was constructed successfully, it returns “True.” |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Original:
Code:
Und Fälschung:
object frxDBDataset1: TfrxDBDataset
UserName = 'frxDBDataset1' CloseDataSource = False DataSet = ADOTable1 Left = 72 Top = 68 end
Code:
So geht's dann, OpenDataSource = False -> DataSource NICHT selber öffnen (das hast Du ja schon gemacht). So tritt der reproduzierbare Fehler beim zeweiten Button nicht mehr auf. Interessant war auch, dass es beim ersten Mal "Preview" im Designer korrekt funktioniert, danach nicht mehr. Dadurch bin ich drauf gekommen das es etwas mit dem state des Datasets zu tun haben muß.
object frxDBDataset1: TfrxDBDataset
UserName = 'frxDBDataset1' CloseDataSource = True OpenDataSource = False DataSet = ADOTable1 Left = 72 Top = 68 end |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Liste der Anhänge anzeigen (Anzahl: 2)
Hi Union,
sehr interessant, bei mir funkt es immer noch nicht siehe ScreenShot. Wenn ich CloseDataSource aktiviere bekomme ich Ergen mit den ADO-Komponenten, fehlermeldung und der Report ist leere, Stack-Überlauf u.s.w. Könnte auch an den ADO-Komponenten liegen von Delphi5. Eigentlich benötige ich ja frxReport1.PrepareReport nicht. Ich würde es jetzt einfach weglassen. Als ich es einbaute, hatte ich die Doku nicht gelesen und meinte das ist wie bei SQL einfach den Report vorbereiten für das Drucken. Das ist nach Doku ja nicht so. Oder siehst Du das anders? Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Zitat:
Mit dem PrepareReport hast Du natürlich Recht. Der ist allerdings sehr schön wenn man verschiedene Reports in einem Job zusammenfassen möchte oder muß. So kann man damit z.B. eine Mahnung erzeugen und die Rechnungen hinten dran hängen und das Ganze dann z.b. in ein PDF exportieren. Aber schau Dir mal Folgendes an, da siehst Du dass FR auch intern immer mit PrepareReport arbeitet:
Delphi-Quellcode:
Es könnte tatsächlich an D5 ADO liegen. Verushcs doch mal mit BetterAdo (falls es das für D5 gibt).
procedure TfrxReport.ShowReport(ClearLastReport: Boolean = True);
begin if ClearLastReport then PreviewPages.Clear; if FOldStyleProgress then begin if PrepareReport(False) then ShowPreparedReport; end else begin FTimer.Enabled := True; ShowPreparedReport; end; end; procedure TfrxReport.OnTimer(Sender: TObject); begin FTimer.Enabled := False; PrepareReport(False); end; |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Hi Union,
ich kannte BetterADO nicht, habs gefunden un nachinstalliert. Die Felhermeldung und das Verhalten ist exakt gleich. Wenn ich nach Prepare first mache, funkt der Report einwandfrei. Im Grid ist mir aufgefallen das die Datenmenge wirklich zwei mal durchlaufen wird.
Delphi-Quellcode:
BetterADODataSet1.first;
frxReport1.PrepareReport; BetterADODataSet1.first; frxReport1.ShowReport; Ich habe gerade Schrittweise ab ShowReport die Ausführung verfolgt und bei mir ist FOldStyleProgress=false. Interessant ist, das der interne Timer1 PrepareReport nach 50ms ausführt. Ich werde jetzt mal das PrepareReport herausnehmen. Ich habe auch den Support von FR kontakiert mal sehen was Dir mir antworten werden. Gruß Kostas |
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
In Deinem Report habe ich gesehen, dass Du Version 4.6.55 einsetzt. Meine Version ist die 4.5 stable. Vielleicht solltest Du auch mal versuchen, lieber eine stable (z.b. 4.6) zu verwenden.
|
Re: Fastreport 4 Beispiel für eine Rechnung das Prinzip n. v
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:00 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