TppRichText: Mail Merge does not work properly in RB Version 14.07
Hallo,
we are using RB Version 14.07 for Delphi XE2. Our users encounter the
following problem since we upgraded from V. 11.05 to 14.07: if the
property "Mail merge" is activated, the RichText component prints the
whole RTF context instead of the formatted text. The same feature worked
in V 11.05 perfectly.
Could You please check the issue.
Thanks and best regards
Leo Kaploun
we are using RB Version 14.07 for Delphi XE2. Our users encounter the
following problem since we upgraded from V. 11.05 to 14.07: if the
property "Mail merge" is activated, the RichText component prints the
whole RTF context instead of the formatted text. The same feature worked
in V 11.05 perfectly.
Could You please check the issue.
Thanks and best regards
Leo Kaploun
This discussion has been closed.
Comments
In my testing with the latest version of ReportBuilder, Mail Merge is
functioning as designed.
My first suggestion would be to upgrade your version to RB 14.08 and see
if that solves the issue. Contact info@digital-metaphors.com with your
serial number and purchasing email address for upgrade instructions.
If this does not fix the issue, please create a simple example I can run
here that demonstrates the problem and send it to
support@digital-metaphors.com in .zip format.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Hi,
we figured it out!
unit ppRichTx;
...
procedure TppCustomRichText.MergeTaggedDBFields;
var
lbSymbolFound: Boolean;
lsCode: String;
lsData: String;
liStartPos: Integer;
liEndPos: Integer;
liCharPos: Integer;
liFullLength: Integer;
liCodeLength: Integer;
lMergeInfo: TppMergeInfo;
begin
lbSymbolFound := True;
FRichEdit.SelectAll;
liFullLength := FRichEdit.SelLength;
liCharPos := 0;
while lbSymbolFound do
begin
liStartPos := FRichEdit.FindText('', liCharPos,
liFullLength, []);
if (liStartPos = -1) or (liEndPos = -1) then
lbSymbolFound := False
else
begin
liCodeLength := liEndPos - liStartPos + 9;
FRichEdit.SelStart := liStartPos;
FRichEdit.SelLength := liCodeLength;
lsCode := Copy(FRichEdit.SelText, 1, liCodeLength);
lMergeInfo := TppMergeInfo.Create;
try
ParseMergeCode(lsCode, lMergeInfo);
lsData := RetrieveMergeData(lMergeInfo);
//FRichEdit.SelText := lsData; // FIELDNAME instead of their content!
liCharPos := liStartPos + Length(lsData);
FRichEdit.SelectAll;
liFullLength := FRichEdit.SelLength;
end;
end;
end; {procedure, MergeTaggedDBFields}
------------------------------
Here an code of our own RTF to plain text convertion method used in the
code above
procedure ConvertRTFContextToPlainText(var aText : String);
const
cRTFSignature = '{\rtf';
var
lForm : TForm;
lRichedit : TRichedit;
lStream : TStringStream;
begin
if Pos(cRTFSignature, aText) = 1 then
begin
lStream := TStringStream.Create(AnsiString(aText));
lForm := TForm.Create(nil);
lRichedit := TRichedit.Create(nil);
try
lRichedit.Parent := lForm;
lRichedit.Visible := False;
lRichedit.Plaintext := False;
lRichedit.Lines.LoadFromStream(lStream);
aText := lRichedit.Text;
finally
lRichedit.Free;
lForm.Free;
lStream.Free;
end;
end;
end;
Please provide a simple example (support@digital-metaphors.com) or steps
I need to take to recreate the issue with the existing code. I will
need to see this issue in action before considering any changes to our
source.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Here is an improved version of RTF to plain text conversion routine.
The point is that RB in version 14.xx uses threading, whereby a form may
be instanciated only in the main application's thread. The code below
does not instanciate any form to be set as a parent for the Richedit.
This allows avoiding lots of uncontrolled situations where a RTF to
plain text conversion is called from a secondary thread.
procedure ConvertRTFContextToPlainText(var aText : String);
const
cRTFSignature = '{\rtf';
var
lRichedit : TRichedit;
lStream : TStringStream;
begin
if (aText = '') or (Copy(aText, 1, Length(cRTFSignature)) <>
cRTFSignature) then
Exit;
lStream := TStringStream.Create(AnsiString(aText));
lRichedit := TRichEdit.CreateParented(Application.Handle);
try
lRichedit.Lines.LoadFromStream(lStream);
aText := lRichedit.Text;
finally
lRichedit.Free;
lStream.Free;
end;
end;