« Do you need zip and/or unzip support in LotusScript? Download my free DLL | Main| Just trying to add value to the Notes community ... is that bad? »

Do you have problems with hide-when formulas in rich text fields? Do you need to change servers in links? Download this free DLL to fix!

Tags: Lotus Notes
Some time ago I created a DLL which had two main features. Remove hide when formulas in rich text fields - and - change servers in your rich text field links. If you have such challenges, download my DLL and use some LotusScript to alleviate these problems!

As a Notes developer you may have tried to add hide when formulas to your rich text fields in Designer. What happens behind the curtain is that all documents created with the rich text field in question, inherits  the hide when formula, which stays put in your documents  no matter what you change your hide when formulas on the form's rich text field in the future. In other words, if you create a rich text field at one point in time with the hide when formula "txtDepartment != "Sales", all documents created with this design will have that formula in place. When you at some later point in time update your hide when formula to for example "txtDepartment != "R&D", only new  documents will inherit this new formula. All previously existing documents will still have the old hide when formula! Unfortunately it is pretty difficult to get at the hide when formulas with standard tools!

The first main feature of my DLL addresses this problem, and removes all rich text hide when formulas. More on that below!

You might also have application, view or documents links within your rich text fields pointing at certain Domino servers. When those servers are decommissioned or for other reasons not valid anymore, the links now points to nonexistent servers, and the user will see error messages when he or she tries to open the links.

The second main feature of my DLL allows you to change servers in your links!
A word of warning; While the DLL has been reported to be stable, some problems may still exist, and thus you should always make a backup of your database in question before  attempting to use this DLL.

The DLL is called VCFIXRTF and can be used from LotusScript to fix your documents.  The DLL itself is a Windows 32 bit DLL created with the Notes C and C++ API, and thus need to have the C++ runtime DLL LCPPN23.DLL also. The zip file contains both files, and you may or may not need the C++ runtime DLL if you already have it on your machine.

Where should you store these files? The short answer is "in a directory which is specified in your system's PATH environment variable". What I'd prefer is to store both files in your Notes program directory (search for the file NLNOTES.EXE and your're in the correct directory, typically C:\Program Files\IBM\Lotus\Notes) and then ensure that the Notes program directory itself is specified in the PATH-environment variable. Why is that? Because a Notes API program will need access to the Notes client- or the Domino server's own DLLs during runtime, and this is the best way to ensure that. You even want to to ensure that the Notes program directory is specified in the first 128 bytes of the PATH environment variable. This used to be a limitation in the old days of Lotus Notes, and I'm not sure when this requirement was- or has been, lifted. I do it the way I have always been doing it, and it always work . By the way, if you are uncertain of how to set new directories in your system's PATH environment variable, read the addendum at the end of this blog-post.

1. FixRichTextFields - Remove hide when formulas
Ok, lets say you have placed the DLL files in your Notes program directory as I recommended above, and that your PATH-statement actually contain this directory. Open up a database and create a simple LotusScript agent with the following code;

Option Public

' 1. Declare the function FixRichTextFields
Declare Function FixRichTextFields Lib "VCFIXRTF.DLL" (_
Byval pstrNotesServer As String, _
Byval pstrNotesDatabase As String, _
Byval pstrNotesUNID As String) As Long

Sub Initialize
        Dim session As New NotesSession                
        Dim db As NotesDatabase                                        
        Dim dc As NotesDocumentCollection
        Dim docSource As NotesDocument
        ' 2. Get the currently selected documents
        Set dc = db.UnprocessedDocuments
        If dc.Count = 0 Then
                Messagebox "Choose a document"
                Exit Sub
        End If
        Dim lRc As Long
    ' 3. Loop through selected documents

        Set docSource = dc.GetFirstDocument()
        While Not(docSource Is Nothing)
           ' 4. Process the document as long
          ' as it isn't open in Notes!

                If Not docSource.IsUIDocOpen Then
                        lRc = FixRichTextFields(db.Server, _
                End If
                Set docSource = dc.GetNextDocument(docSource)
End Sub

Below I describe what I do at each numbered and commented block of code.

1. Declare the function FixRichTextFields
By using LotusScripts own Declare feature I can reference a function within a DLL for later usage by LotusScript. By specifying just "VCFIXRTF.DLL" I tell LotusScript that "hey, you will find the DLL VCFIXRTF.DLL in one of the directories specified by the PATH environment variable. In other words, going the hard way when you install the DLLs and ensuring that the Notes program directory is specified in the PATH environment variable, you make it much easier for your self later! You could also specify the extact path and file name to the DLL here, such as "C:\Program Files\Voith's CODE\Fix Rich Text Fields\VCFIXRTF.DLL", but you would still need to specify the Notes program directory in the PATH in order to get VCFIXRTF to find the Notes/Domino DLLs at runtime. You should also note that.we must specify the parameter and return type of the function. FixRichTextFields accepts three parameters, the server, the database path and the universal ID (UNID) of the document we want to process.

2. Get the currently selected documents
By using the NotesDatabase's UnprocessedDocuments, you get a NotesDocumentCollection of the selected documents in the current view. You can of course use any other means of getting to the Notes documents. The trick is that the VCFIXRTF.DLL needs the document to exist in the database. In other words, you cannot use the functions within my DLL on documents you haven't already saved!

3. Loop through selected documents
By using a simple While loop, I loop through the selected documents.

4. Process the document as long as it isn't open in Notes!
Here I first check whether the current document is open in the Notes user interface. If it isn't, I call the function FixRichTextFields  which we declared in step 1. Note that the function accepts three parameters, where the server is simply the same server as the current database reside on, and the same is valid for the database path. The last parameter get the UniversalID from the current docSource NotesDocument.

FixRichTextFields will find all rich text fields by itself, and remove any hide when formulas.

2. ChangeServerInLinks - Change the server replica id in existing links to new replica id

The second feature in this DLL is the function ChangeServerInLinks, which do exactly that. I finds all links and if the existing server replica id matches the one you have specified, it is replaced with the new replica id you have specified. The
delaration looks like this;

Declare Function ChangeServerInLinks Lib "VCFIXRTF.DLL" (_
Byval pstrNotesServer As String, _
Byval pstrNotesDatabase As String, _
Byval pstrNotesUNID As String,_
Byval pstrOldDatabaseReplicaID As String,_
Byval pstrNewDatabaseReplicaID As String) As Long

Just as for FixRichTextFields, the three first parameters specifies the server, database path and document UNID to process. The next parameter, pstrOldDatabaseReplicaID specify the old, existing server replica that to want to replace with the new replica id, specified in the last parameter, pstrNewDatabaseReplicaID. Note that you can specify a list of old replica ids if you want to change more than one replica id in one go!

Below you see a screen shot where I look at the details of an existing document link;
A picture named M2

If I for example wanted to change the server replica id C1256659:003A1D19 to the current NotesDatabase.ReplicaID, the code could look something like this;

Set docSource = dc.GetFirstDocument()
While Not(docSource Is Nothing)
If Not docSource.IsUIDocOpen Then
     ' Remember - the OLD replica ID field
     ' can contain a list of replica ids to search for.
     ' Separate with semi-colon
     lRc = ChangeServerInLinks(db.Server, _
           docSource.UniversalID, _
           "C1256659:003A1D19", _
End If

Set docSource = dc.GetNextDocument(docSource)

Please note that ChangeServerInLinks doesn't update the so called server hint, which the user typically sees when he or she hover over the link.

Rich text programming can be notoriously difficult, and to just be one step ahead, the ChangeServerInLinks  also create a backup of the $Links  field before it processes it. The backup field has the fieldname format $Links_Backup_YYYYMMDDHHMMSS, and can look like this;

A picture named M3

If ChangeServerInLinks doesn't work properly, it should be a small task to write some LotusScript- or @formula code to rename this backup field back to the original $Links name.

Support functions available in the DLL

The DLL also contains some small support functions, such as GetMajorVersion, GetMinorVersion  and GetBuildNumber. All these functions return an integer and has no parameters. You can use these functions to build in logic in your code to ensure that VCFIXRTF.DLL is of a certain version before attempting to use the other functions.


Addendum - How to set new directories in your PATH environment variable

1. Open up your Control Panel  and open the System  applet

A picture named M4

Locate the Environment Variables -button. This is located in different places. The screen shot above comes from Windows XP. In Vista you click on Advanced System Settings.

A picture named M5

2. Click on the button Environment Variables

A picture named M6

Locate the Path system variable, and click the Edit  button

3. Enter you Notes program directory in the first 128 bytes

A picture named M7

Use the program path where you find NLNOTES.EXE.

A word of warning if you have multiple clients installed on the same machine; Decide first  what version of Notes you want to use, say the latest, and set up the Path and DLLs accordingly. Don't try to use the DLL on the other versions!. If you do, you will make the Notes C and C++ API DLL load and use the wrong DLLs according to your version. This may be a real mess!!

If you want to install VCFIXRTF.DLL on a Domino server, it is just as important to use the program directory of the Domino installation, and for Gods sake, not the Notes client installation!

4. Reboot

To be absolutely sure that your updated Path environment variable is actually taken into account for all processes on your machine, please, PLEASE reboot!


Gravatar Image1 - goodEmoticon :Emoticon Emoticon Emoticon Emoticon

Gravatar Image2 - Looks like the ChangeServerInLinks() function is exactly what I need. I tried it and I can't seem to get it to work. The function returns 1, and the links don't change. I'm running Notes release 6.5.4. Any idea what I may be doing wrong?

When I couldn't get the dll to work I tried using the rtlink.dbreplicaid to set the links via script, but I end up getting the dreaded lookuphandle error when it hits the call to set the id. I can REM out the single line that sets the dbreplicaid and I don't get the error.

Gravatar Image3 - Thanks, Bob! Much appreciated. My customer has requested I move the attachments to another field, which does seem to be appearing okay. It's a strange problem, since the field appears in Noes but not through web browsers. Guess the hidewhen tag must have been somehow turned on.

Gravatar Image4 - Remove Hide_when_formula in RichTextFields
It works great! Thank you for dividing this usefull tool!

Gravatar Image5 - Looks like the ChangeServerInLinks() function is exactly what I need. I tried it and I can't seem to get it to work. The function returns 1, and the links don't change. I'm running Notes release 6.5.4. Any idea what I may be doing wrong?

Gravatar Image6 - I also want to learn how to use ChangeServerInLinks()

Gravatar Image7 - Del.icio.us bookmarks, backlinks and clickthroughs.

Gravatar Image8 - Thank you very much. The hide formulas in Rich text was almost a show stopper for a migration project to a new version of one of our big Notes apps.

Gravatar Image9 - Thanks. Saved me from a big headache.

Gravatar Image10 - Awesome GREAT work on removing hide-whence in RTFs...

Gravatar Image11 - never thought that hide-when problem can be solved, thank for sharing and free download

Gravatar Image12 - I'm looking to do something similar to this. Instead of removing the hide when formulas, I need to set/reset the "Hide paragraph when document is" properties. For example, I have paras in RTF fields with "Hide paragraph when document is 'Previewed for reading'" that I want to remove so they are not hidden.

Any suggestions? Is the source code for this DLL available?


Gravatar Image13 - Any chance you can share code? I need something similar, but not exact. I need to fix the hide-when properties of all paragraphs so that 1) if it is hidden from notes, it is hidden from web; and 2) if it is NOT hidden from notes, it is NOT hidden from web.

Post A Comment