Hide Empty Rich Text Field in Lotus Notes

The problem is very simple: I want to hide a Rich Text field (RTF) if it is empty and show it if it has something in it, in my case one or more attachments. In Lotus Notes a Rich Text Field will not evaluate to empty even if it is emtpy so using a common Hide-When forumula such as MyRTF=”” will not work and you can only use @Formulas.

The solution:

1) Create a new Numeric field, Computed for Display, Hidden, and with Value set to @ThisValue (or HideMyRTF if you are using an earlier release than ND6)  Lets call this field HideMyRTF in this example.

2) Set the Hide-When formula of your existing Rich Text Field – lets call it MyRTF in this example – simply to HideMyRTF (meaning if HideMyRTF is True then hide MyRTF)

3) Add some LotusScript using the NotesRichTextItem EmbeddedObjects property to the Forms QueryOpen event. This will check if there are attachments or text in the field:

Dim rtitem As NotesRichTextItem
Set rtitem = source.Document.GetFirstItem( "MyRTF" )
If Isempty(rtitem.EmbeddedObjects) And Trim(rtitem.Text) = "" Then
    source.Document.HideMyRTF = 1
    source.Document.HideMyRTF = 0
End If

That’s it.

It was a long time since I did any Lotus Notes development so I’m a bit rusty. I’m sure I’ve come up with this or a similar solution in the past but I could not find any when searching so I had to start from the beginning.

This was for an existing app that has been around for quite a few years so there is no way for me to control anything from the beginning. I guess I could have used an agent to set some stuff but this would most likely cause tons of replication conflicts as there are tens of thousands of documents, still being updated by users and replicated across several servers.

Done with a Lotus Notes 7.02 client (I told you it’s been a while…) but should work on older and newer releases.

Lotus Notes data directory on Windows Vista

Just installed and old CD with Lotus Notes 7.02 on my Windows Vista laptop.
Could not find notes.ini, names.nsf in the file system, apparently it’s no longer stored in C:\Program Files\Lotus\Notes\Data. After some searching I found it here: C:\Users\[UserName]\AppData\Local\VirtualStore\Program Files\lotus\notes\data>

Word as Editor in Lotus Notes

I have just started a new project at OpenNTF, the Lotus Notes Open Source community.

The base is a project that I in part developed together with SKF about 18 months ago. Thanks to SKF and Gunilla Darrell for agreeing to donate this code to the OpenNTF community.

The aim was to enhance current functionality when using Word as editor in Notes and be able to use Microsoft Word 2003 functionality such as the Research Pane and Smart Tags (but also simpler things such as the spell checker) to boost user productivity.
Other practical things were addressed, for example that in current functionality Notes sends an email created with Word both as Rich Text and as an OLE object which increases email size by a factor 10-100.

There is one Word as Editor template for OpenNTF Mail Experience and one for standard R6 mail.

Notes uses OLE Automation for it’s Word integration and this of course has its limitations. I did manage to work around many of them but I’m sure others will emerge that will need to be addressed.

Development was done using Microsoft Word 2003 and Lotus Notes 6.
Notes 7 and Notes 8 (currently in public beta) together with Word 2007 will with all certainty add new possibilities yet to be explored.

I hope other organizations will find the project interesting and maybe even useful 🙂

I am looking for an OpenNTF “co-chef” for this project as I currently don’t have that much time to spend on it. Let me know if you want to contribute to this project.

Click here for the Word as Editor projects homepage at OpenNTF.

Things I miss from Notes in Outlook + Desktop Search for Lotus Notes released

I used Lotus Notes as email client for many years, starting with Notes R2 up to R6, and for the last 3 years I’ve been using Outlook 2003. Both have their pro’s and con’s. When I started using Outlook I loved the UI and the Office integration. But there are (at least) two things I miss from Notes:

1) The All view
This is the view where you see ALL your emails – recieved, sent, drafts. With this view you don’t really need your inbox, sent folder etc (though Notes have these too).
What I miss is for example when you email someone back and forth, you want to delete everything but the last email since you already keep the email history in each email. With Outlook you have to switch between the inbox and the sent folder. Of course you can’t bother to do so, so your sent folder gets full of thousands and thousands of useless emails that should have been deleted.
You can probably build this view yourself in Outlook, I did give it a quick try a year or two ago but failed. If you know how to do this please let me know…!

2) Full-text indexing
This is my all time favourite, Notes have had this ever since I started using it in R2 (at least I think so). Anyone who uses Google Desktop or Microsoft Windows Desktop Search (WDS) knows what I’m talking about. No more looking through folders and scroll thousands of emails in search for that email about that thing from that guy who’s name you can’t really remember…
The big difference is that Notes full text indexing works and is superfast. I don’t know what’s wrong with Google Desktop and Desktop Search but it just does not index all my email no matter how I rebuild indexes, reinstall and follow various other tips and tricks found on the net.
For exampel if I search for any email containing the word “logo” (of which I have many) Desktop Search just keeps telling me “Nothing found in All locations for query “logo”. While other searches seems to be working fine. It’s just unreliable which Notes full text search never was.

I haven’t looked that much at Office 2007 yet so maybe these things will be solved there (but somehow I doubt that). The thing about Office 2007 that I personally look forward to the most is the improved use of tasks in Outlook 2007, where tasks will show up on your daily calendar. If they just fix tasks in Windows Mobile Smartphone edition everything will be great 😉 (as blogged about elsewhere…)

Windows Desktop Search Add-in for Lotus Notes
Speaking of full text indexing I just saw that Microsoft released a Lotus Notes add-in for Desktop Search. It should work for Notes R5 and up but only seems to index selected Notes databases:

The Windows Desktop Search Add-in for Lotus Notes is a protocol handler that allows you to index the conent of Lotus Notes email, contacts, calendar items, and journal items stored on your computer.

Ps: Three blog posts in two days! This is a new record for me 🙂
I was going to write about my wife’s brand new Sony Ericsson Z610 which seems to be a great phone but we can’t figure out what some of the icons on the screen mean and the manual does not have a single page explaining what is going on on the screen(!) Also the external screen does not show when a new text/SMS message has arrived for more than a few seconds. After that you have to open the phone to check the internal screen to see if there were any messages while you were gone. Or maybe it’s just a setting but I cannot find it… Well, that will have to be in another post.

How to access a locked down Notes database and one more thing

I don’t do much Notes development these days but every now and then it happens. The last few days I’ve been spending some time with Notes doing a few modifications to a client’s system and came across these two problems:

The client emailed me two Notes database but forgot to uncheck “Enforce a consistent Access Control List”.

Back in the good old days, I’m talking Notes R4 and earlier, you used to have full access to any database that you accessed locally, i.e. a database that was stored or replicated to your local machine. I don’t know what the design reasons for this might have been, but one major drawback of course was that you couldn’t restrict what a user could and could not do as efficiently on a local replica as you could if the application resided on a server. Also Roles did not work locally. Anyway, this all changed in some R4 sub release when the Enforce a consistent ACL was introduced. But now you’ve got a problem whenever you as a developer need access to a database and you’re not in the ACL.

So usually there are two ways around this:
– If there is a manager group in the ACL, create this group in your local address book and add yourself.
– Ask the client to send you a new copy of the database where Enforce a consistent ACL is unchecked.

Today neither of these were an option and I was on a deadline so I Googled to see if there was a solution somewhere. At Ben Poole’s blog I found a third solution. Ben has written some code that uses the Notes API to uncheck Enforce a consistent ACL for you on a local database, no matter what your access rights are.
Simply download the code from Ben’s blog and copy and paste it to a button on a Notes form. Then call the removeEnforce function with the full path and filename of the database as argument.
For me the checkbox got unchecked but for some reason I still didn’t have full access to the ACL so I had to restart Notes and then it worked fine. According to Ben this script should do the trick for both Notes R5 and R6. Myself I used it in R7.

Ok, so with that done time for next problem: I was simply changing what default view should be opened to the user in a frameset (Notes client, no web). The old view worked fine but when I changed to the new one I got one of Notes many informative error messages: “Cannot execute the specified command.”
After doing some troubleshooting I found out that the problem was that I did a @Command([ViewCollapseAll]) in the views PostOpen event. So I searched Notes.net/LDD/Developerworks (I don’t even know what they call it anymore) and I found this thread that didn’t explain why but at least provided a work around. Adding @Command([OpenView];@ThisName) worked for me in Notes 7.0

@Command([OpenView]; @ThisName );

@ThisName is new in R7 R6 [corrected] so to get this to work in previous versions you need to provide the view name as a common string (see the Notes.net thread).

How to sort a NotesDocumentCollection in Lotusscript

This Lotusscript function sorts a document collection on one or multiple fields.

I have previously used several other algorithms that use a view to sort the collection, these however have the drawback that they become very inefficient (i.e. slow) as the number of documents in the view used for sorting grows. The solution presented below does not have this problem.

It has been developed and tested in Lotus Notes 6.5.3 but should work in all ND6 (release 6) and possibly earlier Lotus Notes releases too (if you test this successfully or unsuccessfully write a comment to this post and everyone will know).

Example of use:

Dim fieldnames(0 To 2) As String
fieldnames(0) = "SKU"
fieldnames(1) = "OrderDate"
fieldnames(2) = "Client"
Set collection = SortCollection (collection, fieldnames)

Function to sort DocumentCollection:

Function SortCollection(coll As NotesDocumentCollection, fieldnames() As String) As NotesDocumentCollection

' ------------------------------------------------
' --- You may use and/or change this code freely
' --- provided you keep this message
' ---
' --- Description:
' --- Sorts and returns a NotesDocumentCollection
' --- Fieldnames parameter is an array of strings
' --- with the field names to be sorted on
' ---
' --- By Max Flodén 2005 - http://www.tjitjing.com
' ------------------------------------------------

Dim session As New NotesSession
Dim db As NotesDatabase
Dim collSorted As NotesDocumentCollection
Dim doc As NotesDocument
Dim i As Integer, n As Integer
Dim arrFieldValueLength() As Long
Dim arrSort, strSort As String
Dim viewname As String, fakesearchstring As String

viewname = "$All" 'This could be any existing view in database with first column sorted
fakesearchstring = "zzzzzzz" 'This search string must NOT match anything in view
Set db = session.CurrentDatabase

' ---
' --- 1) Build array to be sorted
' ---

'Fill array with fieldvalues and docid and get max field length
Redim arrSort(0 To coll.Count -1, 0 To Ubound(fieldnames) + 1)
Redim arrFieldValueLength(0 To Ubound(fieldnames) + 1)
For i = 0 To coll.Count - 1
Set doc = coll.GetNthDocument(i + 1)
For n = 0 To Ubound(fieldnames) + 1

If n = Ubound(fieldnames) + 1 Then
arrSort(i,n) = doc.UniversalID
arrFieldValueLength(n) = 32
arrSort(i,n) = "" & doc.GetItemValue(fieldnames(n))(0)
' Check length of field value
If Len(arrSort(i,n)) > arrFieldValueLength(n) Then
arrFieldValueLength(n) = Len(arrSort(i,n))
End If
End If

Next n
Next i

'Merge fields into list that can be used for sorting using @Sort function
For i = 0 To coll.Count - 1
If Not strSort = "" Then strSort = strSort & ":"
strSort = strSort & """"
For n = Lbound(fieldnames) To Ubound(fieldnames) + 1
strSort = strSort & Left(arrSort(i,n) & Space(arrFieldValueLength(n)), arrFieldValueLength(n))
Next n
strSort = strSort & """"
Next i

' ---
' --- 2) Sort array
' ---
arrSort = Evaluate("@Sort(" & strSort & ")")

' ---
' --- 3) Use sorted array to sort collection
' ---
Set collSorted = coll.Parent.GetView(viewname).GetAllDocumentsByKey(fakesearchstring)

For i = 0 To Ubound(arrSort)
Set doc = db.GetDocumentByUNID(Right(arrSort(i), 32))
Call collSorted.AddDocument(doc)
Next i

' ---
' --- 4) Return collection
' ---
Set SortCollection = collSorted

End Function

(This article is previously published and has been moved to this blog)

[Update: Instead of using Evaluate and @Sort in section 2 in the code you can of course use any of your favourite sort routines. Or search the Net for one, there are many out there.]

Lotusscript: Body Above Signature in Memo

I got a library of Lotusscript functions and code examples that I find useful and reuse in projects every now and then. Some are very simple and some did require a little or a lot of research and work before I got them working. In this post is an example on how to disable the email signature from Lotusscript.

When creating a memo from backend Lotusscript and then showing it to the user using the frontend/UI classes, the user email signature (if enabled) will be inserted at the top of the document, i.e. the body text will be below the signature instead of above it as expected.

Disable the signature and then re-enable it as shown in the following code example.

This is only an example on how to disable the user email signature. If you want it inserted at the end of whatever your email contents is (in this example “Hello world!”) you can easily modify the example to read the signature from docProfile and then insert it.

This has been tested in Lotus Notes 6.5.3 but it should work both in previous releases such as R5 and in the later ND7 release.
Write a comment if you have confirmed this working (or not working) in other releases.

Below is a code example that
1) creates a memo using Lotusscript backend classes,
2) disables user email signature,
3) shows the memo to the user using Lotusscript frontend classes, and
4) re-enables the user email signature

Please note that the NotesRichTextItem Update method used in this example is new in ND6.

' ------------------------------------------------
' --- You may use and/or change this code freely
' --- provided you keep this message in your code
' ---
' --- Example by Max Flodén 2005
' --- http://www.tjitjing.com
' ------------------------------------------------

Dim workspace As New NotesUIWorkspace
Dim dbMail As NotesDatabase
Dim docMail As NotesDocument
Dim rtitem As NotesRichTextItem

Dim docProfile As NotesDocument
Dim strProfileEnableSignature As String

'Open users mail database
Set dbMail = New NotesDatabase( "", "" )
Call dbMail.OpenMail
If Not dbMail.IsOpen Then
Call Messagebox("Could not open mail database.", 48, "Error")
Exit Sub
End If

'Create new memo from back end
Set docMail = dbMail.CreateDocument
docMail.Form = "Memo"
docMail.Subject = "Hello"
Set rtitem = New NotesRichTextItem( docMail, "Body" )
Call rtitem.AppendText("Hello world!")
Call rtitem.AddNewline(1)
Call rtitem.Update 'Update method is new in ND6

'Disable signature in users mail profile
Set docProfile = dbMail.GetProfileDocument("CalendarProfile")
strProfileEnableSignature = docProfile.EnableSignature(0)
If strProfileEnableSignature = "1" Then
docProfile.EnableSignature = ""
Call docProfile.Save(True,False)
End If

'Show memo to UI/front end
Set uidoc = workspace.EditDocument(True, docMail,,,True,True)

'Re-enable signature in users mail profile
If strProfileEnableSignature = "1" Then
docProfile.EnableSignature = "1"
Call docProfile.Save(True,False)
End If