3

I am using OLE Search Replace to replace "placeholder tags" with content stored in db fields into a Word docuemnt. I use a technique similar to what disussed here.

THis works but of course it doesn't for rtf fields. I have db fields containing rtf data and if a do search replace I will get the full rtf code, so instead of seeing

Hello World

I see something like

{\rtf1\ansi\ansicpg1252\deff0\deflang1040 \viewkind4\uc1\pard\sa200\sl276\slmult1\lang16\b\f0\fs22 Hello \i World\b0\i0\par }

Did anyone already solved the problem? Searching on StackOverflow I found a trick that uses the clipboard. Note: I don't use bookmarks, this example uses bookmarks, I simply have my tags defined as plain text like '' and when I find '' in my search and replace loop I replace the text.

UPDATE: Do you see any prolem in this clipboard trick?

Do you have other ideas and can suggest other solutions?

Community
  • 1
  • 1
UnDiUdin
  • 14,924
  • 39
  • 151
  • 249
  • So use the example with the clipboard trick, but where it uses the bookmark, find and select your tag the way you already do and replace the tag by using something like pastespecial on the selected text as in the example with the clipboard trick. – Marjan Venema Nov 16 '11 at 09:03
  • Yes I realize I didn't express my self well, let me update the question. I "implicitly" wrote there (and now I am going to write it explxitly) a comment on that trick. – UnDiUdin Nov 16 '11 at 09:16
  • 2
    Yes, using the clipboard for this kind of thing is generally considered "bad/impolite app behaviour" as you are interfering (deleting/overwriting) whatever the user has put there... – Marjan Venema Nov 16 '11 at 10:21
  • Are you calling the [Selection.Find.ClearFormatting](http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.find.clearformatting.aspx) as in the example from Torry.net ? It might cause this problem. But I can't prove it because of two facts, I don't have your code and I have no Office :) – TLama Nov 16 '11 at 14:45
  • I imagine you could do any number of things with OLE Automation, but since you haven't shown any actual OLE Automation code, I don't see what to suggest doing differently. I doubt you need to fall back to the clipboard, to do something that Word itself allows via OLE automation. If an word doc form field is ole automation wrapped, and I'm sure it must be, you can surely experiment and find out yourself. Post what you got. – Warren P Nov 16 '11 at 21:53

2 Answers2

1

I would suggest to use the Selection.InsertFile instead. Here is an example that shoud do what you want, it finds "placeholder" and inserts a rtf file. Save your rtf to a temp-file before...

 procedure TForm1.Button1Click(Sender: TObject);
var
  Fword,FDocument,FFindObject:OleVariant;
  Filename:String;

begin
   Filename := 'C:\temp\test.doc';
   Fword := CreateOleObject('Word.Application');
   FDocument := Fword.Documents.Add(Filename);
   FFindObject := FDocument.ActiveWindow.Selection.Find;
   Fword.visible := true;
   FFindObject.ClearFormatting;
   FFindObject.Replacement.ClearFormatting;
   FFindObject.Text := 'placeholder';
   FFindObject.Forward := True;
   FFindObject.Replacement.Text := '';
   FFindObject.Wrap := 1;
   FFindObject.MatchCase := False;
   FFindObject.MatchWholeWord := False;
   FFindObject.MatchWildcards := False;
   FFindObject.MatchSoundsLike := False;
   FFindObject.MatchAllWordForms := False;

   if FFindObject.Execute() then Fword.selection.InsertFile('C:\temp\test.rtf')   
end; 
Andreas
  • 1,334
  • 1
  • 10
  • 21
0

Here's a post I saved from ages ago. It was posted by Dr. Peter Below of TeamB to the old Borland Delphi newsgroups, but it's still applicable today. It shows how to use the EM_STREAMIN and EM_STREAMOUT messages and related callback to put RTF text into and copy out of a TRichEdit.

Uses RichEdit;

Type
  TEditStreamCallBack = function (dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;

  TEditStream = record
    dwCookie: Longint;
    dwError: Longint;
    pfnCallback: TEditStreamCallBack;
  end;

function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte;
 cb: Longint; var pcb: Longint): DWORD; Stdcall;
var
  theStream: TStream;
  dataAvail: LongInt;
begin
  theStream := TStream(dwCookie);
  with theStream do begin
    dataAvail := Size - Position;
    Result := 0; {assume everything is ok}
    if dataAvail <= cb then begin 
      pcb := Read(pbBuff^, dataAvail); 
      if pcb <> dataAvail then  //couldn't read req. amount of bytes
        result := E_FAIL; 
    end 
    else begin
      pcb := Read(pbBuff^, cb); 
      if pcb <> cb then 
        result := E_FAIL; 
    end;
  end;
end;


Function EditStreamOutCallback(dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;
 var
   theStream: TStream;
 begin
   theStream := TStream(dwCookie);

   with theStream do begin
     If cb > 0 Then 
       pcb := Write(pbBuff^, cb);
     Result := 0;
   end;
 end;

Procedure GetRTFSelection( aRichEdit: TRichEdit; intoStream: TStream );
Var
  editstream: TEditStream;
Begin
  With editstream Do Begin
    dwCookie:= Longint(intoStream);
    dwError:= 0;
    pfnCallback:= EditStreamOutCallBack;
  end;
  aRichedit.Perform( EM_STREAMOUT, SF_RTF or SFF_SELECTION, longint(@editstream));
End;

Procedure PutRTFSelection( aRichEdit: TRichEdit; sourceStream: TStream );
Var
  editstream: TEditStream;
Begin
  With editstream Do Begin
    dwCookie:= Longint(sourceStream);
    dwError:= 0;
    pfnCallback:= EditStreamInCallBack;
  end;
  aRichedit.Perform( EM_STREAMIN, SF_RTF or SFF_SELECTION, longint(@editstream));
End;
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • Just to indicate how old the code is, Peter's signature address was `Peter Below (TeamB) 100113.1101@compuserve.com` :) – Ken White Nov 17 '11 at 14:39