Extending The LotusScript Wrapper Classes

The wrapper classes I blogged about in February went down a lot better than I thought they might.

So, taking it further. Let's extend the DocumentWrapper class some more. Since first writing about them  on here I've been busy using and extending them as I go. Here are a few examples of some of the properties I've added

Simple Helper Properties

Some very simple properties: WebLink, UNID and IsNew.

Property Get WebLink As String
  WebLink = "/" + Replace(web.database.Filepath, "\", "/") + "/0/" + UNID + "?OpenDocument"
End Property
Property Get UNID As String
  UNID = Document.Universalid
End Property
Property Get IsNew As Boolean
  IsNew = document.Isnewnote
End Property

These don't do anything that can't already be done. They just make it simpler and quicker to code.

Logging Document Actions

Properties are all well and good. But they're just borne of laziness really. Let's add a method or two, to make it really useful. How about adding a new method to the base class called LogAction() which you might use like this:

invoice.LogAction("Invoice Approved")

And the method might look like this (it assumes all your Forms have a standard field called "ActionLog"):

Sub LogAction( Action As String )
  Dim item as NotesItem
  Set item = document.GetFirstItem( "ActionLog" )
  Call item.AppendToTextList( Action + " on " + Format(Now, "dd mmm yy") +_
   " at " + Format(Now, "hh:nn:ss") + " by " + web.User.Abbreviated )
End Sub

The web.user part assumes you're already using my WebSession Class.

Deleting Documents

If you never actually delete documents, but merely flag them as deleted then you can give all objects based on the DocumentWrapper class a Delete() method, like so:

Sub MarkDeleted()
 Call SetFieldValue("Delete", "1")
 Call LogAction("Document Deleted")
End Sub

You can then add an IsDeleted property to the DocumentWrapper class, like so:

Property IsDeleted As Boolean
  IsDeleted = (GetFieldValue("Deleted")="1")
End If

At this point you might consider moving some of the field name and their values to "static strings" at the top of the class, then changes the corresponding methods, like this:

Const DELETED_FIELD_NAME = "Deleted"

Sub MarkDeleted()
End Sub

Property IsDeleted As Boolean
End If

Naturally you might want to add an UnDelete() method too...

Extending Derived Classes

So far I've talked about extending the base DocumentWrapper class. Everything we add there is available to all classes derived from it. But, obviously, you can also add properties and methods to the derived classes. For example, the Invoice class might want an Approve() method. This could either simply flag it as approved or perform some more complex workflow logic, passing it between approvers.

Class Invoice As DocumentWrapper
 Sub Approve()
  'Do whatever 
 End Sub
 Sub AddItem(Description as String, Value as Currency)
  'Add to the relevant fields
 End Sub
End Class

Notice I added a call to LogAction() inside the Approve() method. That way you never forget to log the approval no matter where you call the Approve() method from.

The possibilities are almost endless.


These wrapper classes have completely changed the way I code my Domino web apps! My dream has always been to be a "proper coder". I'd love to be able to work completely in Visual Studio writing C#. Unless you've done that you won't appreciate what a pleasure it can be. I get a buzz from writing my own classes and then using them. This is a buzz I've never really had while coding for Domino. Until now. These wrapper classes will have to do for the time being.

Next week I'll talk even more about them and show how to handle collections of documents that belong to other documents. While I go, I'm working on a demo app that brings it all together.


  1. Jake, keep up the good work - am loving it :o)

    • avatar
    • Jeroen Jacobs
    • Fri 8 Mar 2013 08:38 AM

    Isn't the "Delete" subroutine used as a destructor in LotusScript?

    So you'll probably mark every document as deleted when the object gets out of scope :-)

    1. Terminate is called when the document goes out of scope but I believe Delete has to be invoked just like Sub New()

      Hide the rest of this thread

      1. Jeroen is correct:

        http://publib.boulder.ibm.com/infoc.. ..domino.main.doc%2FLSAZ_MANAGING_MEMORY_FOR_OBJECTS.html

        "When the reference count reaches 0, no variables contain references to the object so LotusScript automatically deletes the object and frees its memory."

        1. Cheers, Tim.

      2. Yep, see http://publib.boulder.ibm.com/infoc.. ..ibm.designer.domino.main.doc/LSAZ_DELETING_OBJECTS.html

        "A class's Sub Delete is called when LotusScript deletes an object of that class"

      • avatar
      • Jake Howlett
      • Mon 11 Mar 2013 03:07 AM

      I should have learnt by now not to post LotusScript code that I wrote "off the top of my head" in a text editto. I've done this in the past and been shouted down for it. Should only ever post code I've "compiled" and tested...

      Interesting that the Delete() sub is reserved. Didn't know that. Probably could have guessed though. Doh.

      I've updated the code in the post above.

  2. Why assume the ActionLog field is on a form? Just add it to the document conditionally so you don't have a runtime error when you forgot to add the field.

    if document.hasitem("ActionLog") then

    Set item = document.GetFirstItem( "ActionLog" )


    Set item = document.appenditemvalue ("ActionLog","")

    end if

    1. Not sure that you would want to use appendItemValue.

      From the help file:

      "If the document already has an item called name, appendItemValue does not replace it. Instead, it creates another item of the same name and gives it the value you specify."

      Show the rest of this thread

    • avatar
    • Chris C
    • Tue 12 Mar 2013 05:06 PM

    I didn't know that this "Property" statement even existed in LotusScript!

    Searching Help gives no relevant results.

    FWIW, I ended up searching Help for "Property Get" to find it.

      • avatar
      • Jake Howlett
      • Wed 13 Mar 2013 03:15 AM

      Now, that's a refreshing change. Nice to hear from somebody down at my level who is learning from what I write. Rather than only getting feedback from the know-it-alls who want to point the errors of my ways (I openly welcome any corrections to what I write but can't help sensing a smugness about it sometimes).

      It's always been a bone on contention for me that learning to code in Notes properly comes with very little decent help. I guess the way to have done it would have been to read some good books on (Visual) Basic and imply from them. Oh, how I wish I'd done that ten years ago....

      Show the rest of this thread

  3. Personally, I usually avoided the use of Properties. Trouble is, I seem to always forget why. Once in a while I try to use them again and then obviously stumble across some annoyance ...

    But that was back in the days of Domino 7 (in my case: more than 5 months ago :-P).

    Apart from some sort of implicit documentation, using getter and setter methods (read: standard functions) should serve the same purpose just as well.

Your Comments


About This Page

Written by Jake Howlett on Fri 8 Mar 2013

Share This Page

# ( ) '


The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social

About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content