Insert RichText into RichText with LotusScript – Chapter 2

In an earlier post I wrote about how to insert richtext from another document into a specific position in an exiting richtext item using DXL. This solution works fine but has a few limitations. One of this limitations is the handling of attachments and embedded objects.

So I was looking for another solution. I tried to use LotusScript but due to some missing methods there is no way to achive the goal.

Then I searched the C++ API and found

LNSTATUS Insert( const LNRichText &richtext, LNRTCursor *cursor )

This was exactly what I was looking for. I wrote a small console application to test this method. The function did exactly what it is supposed to do.

Using the

LNSTATUS GotoFirst( const LNString &searchstring )

method, it is possible, to insert the richtext at a specific position that can be defined by a placeholder. The placeholder can be of any name.

Insert Richtext - the placeholder

To delete the placeholder before inserting the replacing content, I use

rtTarget.Delete( &cursor, sizeof( InsertionPoint ));

I guess this is what IBM does when you use the FindAndReplace method of the NotesRichTextRange class. But with this metod you can replace text only. Replacing a string with richtext is not supported. I wonder, why IBM does not enhance this method. In my oppinion this is not very hard to do; as I stated before, the Notes API already has this functionality.

After a few more tests with attachments and embedded objects, I put all this stuff into an DLL. Now the function can be used from inside LotusScript. I decided to provide this new functionality as an DLL because all of my attempts to create an LSX ( using the LSX toolkit ) constantly crashes my client. Even with some help from Bill Buchan and Benjamin Langhinrich I was not able to build a stable function. Maybe i will succeed some day …

To use the InsertRichTextItem function from LotusScript, you have to copy “rt.dll” to your notes executable directory. Since the function uses the C++ API, you have to copy “lcppn70.dll”, too. I have created and tested the function with Notes 7.0.1, but it should work in former versions of Notes as well.

In the Declaration section of your Lotus Script put the following lines

Declare Function InsertRichTextItem Lib "rt" (_
Byval dbServer As String,_
Byval dbPath As String,_
Byval lngSourceNoteID As Long,_
Byval strSourceRTField As String,_
Byval lngTargetNoteID As Long,_
Byval strTargetRTField As String,_
Byval InsertionPoint As String) As String

The function is called as follows

strRet = InsertRichTextItem ( DB_SERVER, DB_FILE,  SourceNOTEID, "Body", TargetNOTEID, "Body","")

The function returns “OK” when completed successfully, otherwise it throws an error.

Sub Click(Source As Button)

	Dim s As New NotesSession
	Dim db As NotesDatabase
	Dim col As NotesDocumentCollection
	Dim doc As NotesDocument

	Dim SourceDoc As NotesDocument ' contains the richtext to be inserted
	Dim TargetDoc As NotesDocument ' insert RT here

	Dim rtItem As NotesRichTextItem
	Dim retval As Integer

	Set db = s.GetDatabase( DB_SERVER, DB_FILE)
	Set col = db.AllDocuments
	Set SourceDoc = col.GetNthDocument(2) ' SecondDocument
	Set TargetDoc = col.GetNthDocument(1) ' FirstDocument

	Dim SourceNOTEID As Long
	Dim TargetNOTEID As Long

	' Convert NOTEID from HEX to Long
	TargetNOTEID = Val("&H" + TargetDoc.NoteID)
	SourceNOTEID = Val("&H" + SourceDoc.NoteID)

	Msgbox InsertRichTextItem ( DB_SERVER, DB_FILE,  SourceNOTEID, "Body", TargetNOTEID, "Body","")

End Sub

Attached you’ll find a sample database. The necessary files are included in the “first document” – doc.

If you find this function useful, pls. let me know.

Technorati:

7 thoughts on “Insert RichText into RichText with LotusScript – Chapter 2

  1. hallo eknori,

    vielen lieben dank für deine lösung (auch wenn du es gerne nur teillösung nennst). habe das selber vor 1em jahr versucht und erfolglos niedergelegt. werde das mal aufleben lassen. sobald ich ergebnisse habe bzw. deinen code erweitern sollte, gebe ich dir bescheid.

    ayhan

  2. As a side note to your … how to insert RTF into another RTF document …

    I had run across your post while trying to do a very typical thing in an application….give the user the ability to put RTF comments into a field and then have it saved as read only and displayed as read only in a second RT Item / Field.
    In this case it is a history field with both user entered comments and workflow comments which shouldn’t be erased by users.

    So I created my two NotesRTItems, History and tmpHistory. tmpHistory was in a table to make it pretty and the table was set to be only viewable when in edit mode.
    The History item was a computed NotesRTitem, always visible with a formula of History.
    Then the trouble began …
    It seemed no matter how hard I tried it was impossible to get the History field to show its contents when the document was in read mode. However when in Edit mode the comments showed.
    To cut a long story short it turns out that Rich Text, entered in an RT item which is set to only show in edit mode, inherits the hide when formulas of its parent item and carries these hide when formulas to the new RT field. The text in the History RT item would not show the RTF enetered in tmpHistry until the document was placed in edit mode.
    Funnily enough, text / RTF placed in the history field programatically would show in both Edit and read mode. It took me several hours and my extensive command of English swear words to resolve the quirk and figure out what was happening.

    A side effect of this is I developered a short piece of code which does allow me to save my tmpHistry field into the history field when the UIDoc is closing.

    Sub Queryclose(Source As Notesuidocument, Continue As Variant)
    Dim doc As NotesDocument
    Dim rt1 As NotesRichTextItem
    Dim rt2 As NotesRichTextItem

    Set doc = source.Document

    Set rt1 = doc.GetFirstitem( “tmpHistory”)
    If Not ( rt1 Is Nothing ) Then
    Set rt2 = doc.GetFirstItem( “History”)
    Call rt2.AppendRTItem( rt1 )
    Call doc.Save( True, False )
    Call doc.RemoveItem( “tmpHistory”)
    Call doc.Save( True, False )
    End If
    TheEnd:
    Continue = True
    Exit Sub

    errHandle:
    Resume TheEnd
    End Sub

    Thanks for your code by the way. Very helpful. If the piece of code I am writing was not going into a secure environment which doesn’t allow dlls to be installed I would be looking at implementing it (with appropriate references back to your authorship of course).

    HTH
    Shane

  3. I can’t wait to test the dll.
    I also created the easier version (there is some resemblance between mine and Shane’s code), but, unfortunately, it does not usually work as expected when richtext item contains attachments.

    After hardly trying to figure out what it’s happening, I found an IBM technote:

    Attachments copied using one of the LotusScript CopyItem methods either do not display an attachment icon or produce an error when you attempt to access the attachment. This behavior has been observed with only certain source attachments copied using the LotusScript methods RenderToRTitem, FormatDocument, AppendRTItem, CopyItem, CopyAllItems or CopyItemToDocument. In cases where the attachment icon is present, the following error occurs when you attempt to use the attachment:

    “Note item not found”

    If you examine the document properties, you see that it does not contain a $File field item.

    Solution
    For the CopyItem methods this issue was reported to Quality Engineering as SPR# MBEN67URB7 and fixed in Notes/Domino 6.5.5 and 7.0.

    The following issues are fixed in Domino 7.0.2 and a fix is pending for Domino 6.5.x releases:

    * For the AppendRTITem method, the issue was reported to Quality Engineering as SPR# FHEN6KXJRK.
    * For the FormatDocument method, the issue was reported to Quality Engineering in SPR# FHEN6LCM7H.
    * For the RenderToRTItem method, the issue was reported to Quality Engineering in SPR# FHEN6LKFEF.

  4. Thanks for the info.
    I’m afraid that i can not use the dll, but i think the article was very interesting, throwing light on issues i’ve been working on for months.
    I’m working on an functionality in the mailclient. In an opened new memo/reply/rplwithhistory a radiobutton field controlling the language of richtext signature/mailtrailer inserted into the body field of the memo. And this is in UI so the user sees what he/she sends.

  5. I try to use your DB and I got error “Error in loading DLL”
    Please you suggest me how I fix this problem?
    I am an user in windows2000 can’t create any file in win\system32

  6. Hi,

    Just kinda sidetrack a bit from the above problem.

    I wish to create a function attached to a button so that when the user insert the attachment , he should be able to see the attachment display on the current document. My code are as follows:

    Sub Click(Source As Button)

    Dim nwsBrowseWorkspace As New NotesUIWorkspace
    Dim nudWebdoc As NotesUIDocument
    Dim ndocBackWebdoc As NotesDocument
    Dim neoEmbedAttachment As NotesEmbeddedObject
    Dim nimAttachFileItem As NotesItem
    Dim nrimAttachment As NotesRichTextItem
    Dim varFilePath As Variant
    Dim strFilePath As String

    Set nudWebdoc = nwsBrowseWorkspace.currentdocument
    Set ndocBackWebdoc = nudWebdoc.document
    varFilePath = nwsBrowseWorkspace.OpenFileDialog(False)

    If Not Isempty(varFilePath) Then
    strFilePath = varFilePath(0)
    ndocBackWebdoc.txtFileName = strFilePath
    Msgbox “FilePath – ” &strFilePath
    Else
    Msgbox “The File Is Not Attached”,,”Bsuite”
    Exit Sub
    End If

    Set nrimAttachment = New notesrichtextitem(ndocBackWebdoc,”AttachedFile”)

    If nrimattachment Is Nothing Then
    Set nrimAttachment = ndocBackWebdoc.CreateRichTextItem(“AttachedFile”)
    End If
    Set neoEmbedAttachment = nrimAttachment.EmbedObject( EMBED_ATTACHMENT, “”, strFilePath)
    Call ndocBackWebdoc.save(True,True)
    Call nudWebdoc.FieldSetText( “AttachedFileName”, strFilePath )

    End Sub

    As the user tries to attach the file, he could not see the display of his attachment instantaneously.

    Please advice me on my problem.Thank you very much !

Comments are closed.