Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Werkzeuge (https://www.delphipraxis.net/63-sonstige-werkzeuge/)
-   -   FastReport: RFT Länge ermitteln (https://www.delphipraxis.net/212430-fastreport-rft-laenge-ermitteln.html)

haentschman 9. Feb 2023 09:18

FastReport: RFT Länge ermitteln
 
Hallöle...:zwinker:

SOLL:
Ich will ein Child Band entsprechend dem INHALT (Textzeichen = 0) eines RTF Feldes ausblenden.

Das Datenfeld ist gefüllt. Auch bei leerer Anzahl von Zeichen sind ja Steuerzeichen drin...normal.

Bei den fixen RTF Feldern habe ich mir im Delphi procedure gemacht die über die .Lines die Zeichen emittelt, und die eine "VisibleChild" Variable Tue oder False einstellt. Im Report werte ich dann die Variable aus.

Nun habe ich aber RTF Felder in den Detaildaten...da kann ich mit der Variable nix anfangen. :roll:

Problem:
Egal welches Event z.B. procedure RichPositionOnAfterData(Sender: TfrxComponent); ich nehme, die RichPosition.RichEdit.Lines sind immer leer. :shock: Das Feld hat zu diesem Zeitpunkt den RTF Text zur Verfügung.

Frage:
Wie komme ich an die Lines? :gruebel:

PS: Fastreport Forum ist dürftig und hat keine Antwort.

Danke

himitsu 9. Feb 2023 09:45

AW: FastReport: RFT Länge ermitteln
 
Hat das RichText-Control des FastReport auch sowas, wie ein Delphi-Referenz durchsuchenTRichEdit.PlainText,
womit man steuern kann, wie das Streaming arbeitet?


Bzw. eigentlich .Lines.PlainText, was im Lines.SaveToStream/LoadFromStream steuert, ob beim EM_STREAMIN/EM_STREAMOUT ein SF_TEXT+SFUNICODE oder SF_RTF verwendet wird.
Alles Andere verwendet z.B. EM_GETLINE, WM_GETTEXT und Dergleichen, welches nur auf Text und nicht auf den PlainText (RTF) zugreift.

haentschman 9. Feb 2023 10:00

AW: FastReport: RFT Länge ermitteln
 
Danke...

Zitat:

Hat das RichText-Control des FastReport auch sowas, wie ein Delphi-Referenz durchsuchenTRichEdit.PlainText,
JA. Aber das nützt mir nix, weil ich das RTF als RTF mit Formartierungen anzeige. Ich brauche nur die Anzahl der Zeichen für das Aus/Einblenden des Childs bei leerem Text.

Wie macht man aus einem Feld einen Stream? Meine Versuche die Lines über einen Stream einzulesen...:?
Delphi-Quellcode:
var
  Stream: TMemoryStream;                                                    
begin
  Stream := TMemoryStream.Create;
  try
   (<DataPosition."PositionRtf">).SaveToStream(Stream); // falsch                                                  
   RichPositions.RichEdit.Lines.LoadFromStream(Stream);
...
...wann werden die RichEdit.Lines von FR eingelesen?

Frickler 9. Feb 2023 11:38

AW: FastReport: RFT Länge ermitteln
 
Zitat:

Zitat von haentschman (Beitrag 1518467)
Nun habe ich aber RTF Felder in den Detaildaten...da kann ich mit der Variable nix anfangen.

Statt ner Reportvariablen ne Reportfunktion?

Code:
IsEmpty(<DataPosition."PositionRtf">)

haentschman 9. Feb 2023 12:24

AW: FastReport: RFT Länge ermitteln
 
:zwinker: IsEmpty kennt FR nicht. Selbst dann...im Datenfeld (leerer Text = 0 Zeichen) steht "{\rtf1\ansi\ansicpg1252\deff0\nouicompat{\fonttbl{ \f0\fnil\fcharset0 Arial;}} {\*\generator Riched20 10.0.19041}\viewkind4\uc1 \pard\fs18\lang1031\par }" drin.

alex517 9. Feb 2023 13:01

AW: FastReport: RFT Länge ermitteln
 
Hi,
diese Links sollten dir weiterhelfen:

RTF to plain text:
https://www.delphipraxis.net/767804-post12.html

Using Custom Functions in a Report:
https://www.fast-report.com/document..._to_report.htm

Alex

haentschman 9. Feb 2023 16:09

AW: FastReport: RFT Länge ermitteln
 
Danke...:P

Das Erste kommt mir bekannt vor. So ähnlich habe ich das mit den Variablen gemacht. :wink: Custom Functions ... fürs nächste Mal. 8-)

Inzwischen habe ich eine FastReport Lösung:

Dummy TfrxRichView im Detail Band
Delphi-Quellcode:
procedure DetailDataOnBeforePrint(Sender: TfrxComponent);
begin
  Dummy.RichEdit.Lines.Clear;
  Dummy.RichEdit.Lines.Add(<DataPosition."TEILRtf">);
  // Achtung! Lines.Text funktioniert nicht! Da wird der RTF string in die Lines geschrieben. Mit Lines.Add wird der RTF Text als PlainText ausgegeben.
  Child.Visible := Length(Dummy.RichEdit.Lines.Text) > 2; // Offset für immer einen LineFeed ... warum auch immer.
end;
:warn: Fehlinformation :oops:

mytbo 9. Feb 2023 19:13

AW: FastReport: RFT Länge ermitteln
 
Zitat:

Zitat von haentschman (Beitrag 1518467)
Ich will ein Child Band entsprechend dem INHALT (Textzeichen = 0) eines RTF Feldes ausblenden.

Delphi-Quellcode:
procedure DetailDataOnBeforePrint(Sender: TfrxComponent);
begin
  Child.Visible := (Dummy.RichEdit.Lines.Count > 0);
end;
Bis bald...
Thomas

haentschman 10. Feb 2023 05:36

AW: FastReport: RFT Länge ermitteln
 
Liste der Anhänge anzeigen (Anzahl: 3)
Danke...8-)

Delphi-Quellcode:
(Dummy.RichEdit.Lines.Count > 0);
Funktioniert nicht. Weil 5 Lines keinen Inhalt haben können...sondern nur LineFeeds. :zwinker: Ich will aber die Zeile ausgeblendet haben bei leerem -> Text = '' Lines.

PS:
Meine Variante von gestern funktioniert nicht, weil Fastreport selbst im "FastScript" Bugs hat! Oder kann mir das jemand logisch erklären? Siehe Bilder!

Erklärung:
...der Block soll entscheiden ob das Child2 ausgeblendet wird. Der Code soll in der letzten Zeile, was auch die erste Zeile ist, wenn kein Text drin ist sondern nur LineFeeds, die Zeile entfernen. Dann ist Lines.Count = 0.
1. Breakpoints rot
2. die gelbe Linie ist die aktuelle Zeile
3. Bild 1 vor Ausführung, Bild nach der Ausführung :evil: Er darf die Bedingung nicht auführen weil Bedingung = False ist!

Fehler im Debugger FastReport:
1. niemals im Debugger RichEdit.Lines.Text (habe ich gestern kurzzeitig gesehen...daher mein übereiltes Statement von gestern :oops:)
2. Ablaufsteuerung funktioniert nicht :shock:

...so kann ich nicht arbeiten. :? Oder was habe ich übersehen? :gruebel:

PS: Mail an FastReport Support ist raus.

Delphi.Narium 10. Feb 2023 12:52

AW: FastReport: RTF Länge ermitteln
 
Zitat:

Zitat von haentschman (Beitrag 1518492)
Delphi-Quellcode:
  Child.Visible := Length(Dummy.RichEdit.Lines.Text) > 2; // Offset für immer einen LineFeed ... warum auch immer.

Für die Ausgabe von Text werden bei TStrings-Nachfolgern die einzelnen Zeilen "zusammengedaddelt" und am Ende wird immer ein Zeilenumbruch drangepappt, deshalb ist die Länge von Lines.Text (unter Windows) immer mindestens = 2.

Alternative:
Delphi-Quellcode:
  Child.Visible := Length(Trim(Dummy.RichEdit.Lines.Text)) = 0;

haentschman 10. Feb 2023 13:16

AW: FastReport: RFT Länge ermitteln
 
Danke...:P

Diese Varianten habe ich alle durch. :? Ich bin nie zu einem stabilen Ergebnis gekommen. Erst Recht nicht mit dem Bug in if/then. :cry:

TRIM hat bei mir alle Zeichen, auch die benötigten, entfernt -> Lenght = 0 :?
Zitat:

Lines.Text (unter Windows) immer mindestens = 2
...nicht ganz. Wenn du imho auf ein NULL Feld triffst ist, Lines.Count = 0 und Länge = 0 :wink:

Ich habe jetzt eine CustomerFunction eingebaut, die mir im Delphi Quelltext das Datenfeld in das Dummy RichEdit einliest und mir den Text ohne Steuerzeichen emittelt und einen Boolean zurückgibt. :wink: Damit funktioniert es stabil...:thumb:
Delphi-Quellcode:
function TdmReport.frxReport1UserFunction(const MethodName: string; var Params: Variant): Variant;
begin
  if MethodName = 'CANSHOWCHILD' then
  begin
    Result := CanShowChild(Params[0], Params[1]);
  end;
end;
...
function TdmReport.CanShowChild(DataSetName, FieldName: string): Boolean;
var
  Data: TDataSet;
begin
  Result := False;

  if FCurrentPrint.ReportDictionaryDataSets.ContainsKey('frx' + DataSetName) then
  begin
    Data := FCurrentPrint.ReportDictionaryDataSets['frx' + DataSetName];
    if Assigned(Data) then
    begin
      Stream.Clear;
      TBlobField(Data.FieldByName(Fieldname)).SaveToStream(Stream);
      Stream.Position := 0;
      Rich.Lines.LoadFromStream(Stream);

      Result := (Trim(Rich.Lines.Text) > '');
    end;
  end;
end;

mytbo 10. Feb 2023 16:41

AW: FastReport: RFT Länge ermitteln
 
Zitat:

Zitat von haentschman (Beitrag 1518509)
Delphi-Quellcode:
(Dummy.RichEdit.Lines.Count > 0);
Funktioniert nicht. Weil 5 Lines keinen Inhalt haben können...sondern nur LineFeeds. :zwinker:

Delphi-Quellcode:
procedure DetailDataOnBeforePrint(Sender: TfrxComponent);
var
  i: Integer;
  isVisible: Boolean;
begin
  isVisible := False;
  for i := 0 to Dummy.RichEdit.Lines.Count - 1 do
  begin
    isVisible := (Dummy.RichEdit.Lines[i] <> '');
    if isVisible then Break;
  end;

  Child.Visible := isVisible;
end;
Optimieren darfst du selbst.

Bis bald...
Thomas

mytbo 13. Feb 2023 00:19

AW: FastReport: RFT Länge ermitteln
 
Zitat:

Zitat von haentschman (Beitrag 1518531)
Ich habe jetzt eine CustomerFunction eingebaut, die mir im Delphi Quelltext das Datenfeld in das Dummy RichEdit einliest und mir den Text ohne Steuerzeichen emittelt und einen Boolean zurückgibt.

Wenn immer möglich, sollte eine Bericht-Funktion ohne interne Abhängigkeiten geschrieben werden. Das bietet die Möglichkeit, mit der Zeit eine eigene Sammlung nützlicher Helfer zu erstellen, die nur durch Einbindung einer Unit zur Verfügung gestellt werden. Im konkreten Fall könnte es zum Beispiel so aussehen:
Delphi-Quellcode:
unit u_ReportFunctions;

interface

uses
  Windows, Messages, SysUtils, Classes, Variants,
  fs_iinterpreter;

type
  TReportFunctions = class(TfsRTTIModule)
  private
    function CallMethod(pmInstance: TObject; pmClassType: TClass;
      const pmcMethodName: String; pmCaller: TfsMethodHelper): Variant;
  public
    constructor Create(pmScript: TfsScript); override;
  end;

implementation

uses
  frxClass, frxVariables, frxRichEdit;

const
  OWN_FUNCTIONS = 'Own functions';

function RTFTextCharCount(const pmcRTFText: String): Integer;
var
  richEdit: TRxRichEdit;
  loadStream: TStringStream;
begin
  Result := 0;
  if pmcRTFText = '' then Exit; //=>

  richEdit := TRxRichEdit.CreateParented(HWND(HWND_MESSAGE));
  try
    loadStream := TStringStream.Create(pmcRTFText);
    try
      richEdit.Lines.LoadFromStream(loadStream);
    finally
      loadStream.Free;
    end;

    Result := richEdit.GetTextLen;
    if Result > 0 then
      Result := Result - (richEdit.Perform(EM_GETLINECOUNT, 0, 0) - 1);
  finally
    richEdit.Free;
  end;
end;

function IsRTFTextEmpty(const pmcRTFText: String): Boolean;
begin
  if pmcRTFText <> '' then
    Result := (RTFTextCharCount(pmcRTFText) = 0)
  else
    Result := True;
end;

//=== TReportFunctions =========================================================

constructor TReportFunctions.Create(pmScript: TfsScript);
begin
  inherited Create(pmScript);
  pmScript.AddMethod('function IsRTFTextEmpty(const pmcRTFText: String): Boolean',
    CallMethod, OWN_FUNCTIONS, 'IsRTFTextEmpty() returns if chars are present');
  pmScript.AddMethod('function RTFTextCharCount(const pmcRTFText: String): Integer;',
    CallMethod, OWN_FUNCTIONS, 'RTFTextCharCount() returns the number of chars');
end;

function TReportFunctions.CallMethod(pmInstance: TObject; pmClassType: TClass;
  const pmcMethodName: String; pmCaller: TfsMethodHelper): Variant;
begin
  if SameText(pmcMethodName, 'IsRTFTextEmpty') then
    Result := IsRTFTextEmpty(pmCaller.Params[0])
  else if SameText(pmcMethodName, 'RTFTextCharCount') then
    Result := RTFTextCharCount(pmCaller.Params[0]);
end;

initialization
  fsRTTIModules.Add(TReportFunctions);

end.
Und so im Bericht eingesetzt werden:
Delphi-Quellcode:
procedure DetailDataOnBeforePrint(Sender: TfrxComponent);
begin
  Child.Visible := not IsRTFTextEmpty(<data."RTFData">);
end;
Bis bald...
Thomas


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:31 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-2025 by Thomas Breitkreuz