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!
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, _
db.FilePath,_
docSource.UniversalID)
End If
Set docSource = dc.GetNextDocument(docSource)
Wend
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;
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, _
db.FilePath,_
docSource.UniversalID, _
"C1256659:003A1D19", _
db.ReplicaID)
End If
Set docSource = dc.GetNextDocument(docSource)
Wend
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;
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.
ENJOY!
Addendum - How to set new directories in your PATH environment variable
1. Open up your Control Panel and open the System applet
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.
2. Click on the button Environment Variables
Locate the Path system variable, and click the Edit button
3. Enter you Notes program directory in the first 128 bytes
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!
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, _
db.FilePath,_
docSource.UniversalID)
End If
Set docSource = dc.GetNextDocument(docSource)
Wend
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;
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, _
db.FilePath,_
docSource.UniversalID, _
"C1256659:003A1D19", _
db.ReplicaID)
End If
Set docSource = dc.GetNextDocument(docSource)
Wend
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;
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.
ENJOY!
Addendum - How to set new directories in your PATH environment variable
1. Open up your Control Panel and open the System applet
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.
2. Click on the button Environment Variables
Locate the Path system variable, and click the Edit button
3. Enter you Notes program directory in the first 128 bytes
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!
Comments
Posted by null At 12:52:39 On 30.06.2009 | - Website - |
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.
Posted by Scott At 22:44:46 On 17.02.2010 | - Website - |
Posted by Beau Schless At 14:36:01 On 24.02.2010 | - Website - |
It works great! Thank you for dividing this usefull tool!
Posted by Gerhard At 15:47:25 On 07.05.2010 | - Website - |
Posted by Solar Education Kit At 04:30:02 On 11.04.2012 | - Website - |
Posted by Clark At 10:36:11 On 18.05.2012 | - Website - |
Posted by dioo At 10:23:04 On 25.08.2012 | - Website - |
Posted by Martin Clode At 13:19:51 On 13.02.2013 | - Website - |
Posted by Paul At 16:49:31 On 05.03.2014 | - Website - |
Posted by null At 07:53:18 On 04.04.2015 | - Website - |
Posted by owen At 07:39:39 On 30.04.2015 | - Website - |
Any suggestions? Is the source code for this DLL available?
Thanks
Posted by George At 06:34:32 On 20.01.2019 | - Website - |
Posted by Owen At 19:34:36 On 25.05.2022 | - Website - |