Home End User
New Blog Posts: Merging Reports - Part 1 and Part 2

TppRichText: Mail Merge does not work properly in RB Version 14.07

edited October 2013 in End User
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

Comments

  • edited October 2013
    Hi Leo,

    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.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2013
    Am 18.10.2013 15:22, schrieb Nico Cizik (Digital Metaphors):


    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;
  • edited October 2013
    Hi Leo,

    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.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2013
    Am 22.10.2013 12:53, schrieb Leo Kaploun:




    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;
This discussion has been closed.