This is originally posted in junblogs under the title:
This is an old posting of mine and I will simply copy paste things here. No time to rework or reword things. This is actually about the way to combine/merge two or more RTF files into one, or insert words in an existing RTF file via way of codes. Enjoy reading!
====
====
I would like to treat this as a continuation of my journey with RTF and Automation which I originally have posted in weblogs.foxite.com. Since this is my new home, you will see future playings with RTF and Automation here onwards and nowhere else. You will find below the previous journeys with the links so you can read those back if you are interested:
- Part VII – This post
- Part VI – Confining cell contents of a table from word to RTFhttp://weblogs.foxite.com/sandstorm36/archive/2009/11/28/9495.aspx
- Part V – Spell and Grammar Checking in an RTFhttp://weblogs.foxite.com/sandstorm36/archive/2009/11/26/9476.aspx
- Part IV – RTF memo combined with other fields of a Table – into Word Reporthttp://weblogs.foxite.com/sandstorm36/archive/2009/11/24/9441.aspx
- Part III – Enhanced RTF Tool Revealedhttp://weblogs.foxite.com/sandstorm36/archive/2009/11/21/9403.aspx
- Part II – Going Beyond Copy and Paste IIhttp://weblogs.foxite.com/sandstorm36/archive/2009/11/19/9362.aspx
- Part I – Going Beyond Copy and Pastehttp://weblogs.foxite.com/sandstorm36/archive/2009/11/18/9346.aspx
This Post
Last night, I read a question inside foxite regarding a problem of using STRTOFILE()with the “append at end of the file” switches used represented by lAdditive or nFlag switches on an RTF failing. That works well in a normal text file but fails with an RTF. Why? I will explain later in this blog but first allow me to show how we can add an rtf file to the end of an existing rtf file. Here is my post inside foxite and the way on how to append another rtf file at the end of an already existing rtf file:
With automation, the trick is to check if that c:\temp\rtftemp.rtf already exists or not yet. If not, it can be easily saved via FILETOSTR(). But if that file already exists where you have to add another content of memo field, then you can’t simply use FILETOSTR() anymore as what you need to do now is open that one first via automation then go to the end of that rtf document and paste the content of the memo field (additional). Here is how I believe it can be done:
Set Safety Off
Declare Integer ShellExecute In shell32.Dll ;
INTEGER hndWin, ;
STRING cAction, ;
STRING cFileName, ;
STRING cParams, ;
STRING cDir, ;
INTEGER nShowWin
#Define wdStory 6
#Define wdPasteDefault 0
Local lcTempNewRTF, lcTargetTemp
lcTargetTemp = "c:\temp\rtftemp.rtf"
Create Cursor junk (myMemo M)
Insert Into junk Values (Filetostr(Getfile("rtf")))
* Now we have one record inside a memo field, content is of rtf format. Next step is to extract it back
Local lortf As Word.Application
lortf = Createobject(“Word.Application”)
With lortf
* check first if there is already a previous file, if there is open it, if not create a new one
If !File(m.lcTargetTemp)
* Does not exist yet, use FILETOSTR() being the simplest way
Strtofile(junk.myMemo,m.lcTargetTemp)
Else
* Create a temporary file to write down contents of the memo field
lcTempNewRTF = Addbs(Getenv(“TMP”))+”temp.rtf”
Strtofile(junk.myMemo,m.lcTempNewRTF)
* Open the previous rtftemp
.Documents.Open(m.lcTargetTemp)
.Selection.EndKey(wdStory)
.Selection.TypeParagraph
* open the newly created temp file from memo, select all and copy
.Documents.Open(m.lcTempNewRTF)
.Selection.WholeStory
.Selection.Copy
.ActiveDocument.Close
* paste content of clipboard
.Selection.PasteAndFormat(wdPasteDefault)
* Save changes and close, ensure it is really in an RTF format
.ActiveDocument.SaveAs(m.lcTargetTemp,6)
.ActiveDocument.Close
.Quit
Endif
Endwith
ShellExecute(0,”Open”,m.lcTargetTemp,”",”",1)
The reason behind why FILETOSTR() with lAdditive/nFlag on an RTF fails
And here is my initial observation last night which is also on the very same post:
I am not so sure about this but my initial observation is because an rtf files starts with “{\rtf1\” code. And so I believe that is the delimeter which signifies the start of an RTF file. My guess is that the next set of RTF codes that will have have “\rtf1\” will then be ignored, thus you are always seeing only the previous content when opened in msword as the newly added ones are ignored in the final output. As I have told you, I have read this just now and I have not done intensive playings with this so maybe I am wrong.
Now we will prove my last night’s theory and you can play along with me. Here goes:
a. Copy these codes, open notepad and paste these there:
{\rtf1\Ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Calibri;}{\f1\fnil\fcharset0 Arial;}}
\viewkind4\uc1\pard\f0\fs20 This is a sample\f1\fs18
\par }
b. Save it as test.rtf, close notepad.
c. Double-click that test.rtf so it will open into its default reader, in mine it is MSWord.
d. So you see, MSWord will transform those rtf codes into formatted text. Now close MSWord (or any other software that is the default reader of rtf on your end).
e. Right-click that test.rtf file again and choose “open with” then select notepad. You will be back seeing the rtf codes again. Now replace the whole content with what is shown below (all colored blue):
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Calibri;}{\f1\fnil\fcharset0 Arial;}}
\viewkind4\uc1\pard\f0\fs20 This is a sample\f1\fs18
\par }
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Calibri;}{\f1\fnil\fcharset0 Arial;}}
\viewkind4\uc1\pard\f0\fs20 This is a sample\f1\fs18
\par }
Now we have a two sets of rtf document in one file (the new set is appended at the end very much like using STRTOFILE() with lAdditive/nFlag switch). Save changes and close notepad. We are now expecting when it is opened inside its default reader two lines with the words: “This is a sample“. But hey, it does not show the other one which is the newly appended rtf document?
Back to my theory last night, an rtf file starts with “{\rtf1” and is terminated with “}“. So the default reader reads it from {\rtf1 and terminates it immediately when it reached the closing bracket “}”. Any other entries after that whether another set of RTF codes or plain text like this will be ignored after that:
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Calibri;}{\f1\fnil\fcharset0 Arial;}}
\viewkind4\uc1\pard\f0\fs20 This is a sample\f1\fs18
\par }
anything beyond the end bracket above is ignored including this line
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Calibri;}{\f1\fnil\fcharset0 Arial;}}
\viewkind4\uc1\pard\f0\fs20 This is a sample\f1\fs18
\par }
So like what I have said last night, an STRTOFILE() has performed well what it is supposed to do. The fault is not with that function but with the rtf codes and the only way, as far as I can see right now, is to use automation combining two or more rtfs inside MSWord as I have shown above.
Why does automation succeeds then where STRTOFILE() seem to fail?
Because when we combine two or more rtf files inside MSWord, when it is saved, the old RTF content plus the newly added RTF codes will be combined and treated as one. Meaning the codes will be adjusted leaving only one instance of {\rtf1 which is terminated with }.
I hope this post has helped you understand the mystery why inserting words or combining two or more rtf files fail in most cases. Cheers!