Mapping Document Collections To Views

It's now a couple of months since I wrote about a Super Useful Set of LotusScript Wrapper Classes, which I've written about on and off since February.

Today I want to share a few more extensions I've made to them, which help massively when it comes to getting documents from views.

Imagine the following use scenario:


Dim factory As New CustomerFactory()
Dim coll As CustomerCollection

'Let's get a collection from a view
Set coll = factory.GetAll()

'Or you could to this
Set coll = factory.GetAllByID()

'Or you could to this

coll = factory.GetAllByCountry() 'Or you could to this Set coll = factory.GetCustomersMatching("foo")


This code utilises the following functions in the CustomerFactory class:


Class CustomerFactory As DocumentFactory

  Private Function FromView(ViewName As String) As CustomerCollection
    Set FromView = New CustomerCollection(GetViewNavigator(ViewName))
  End Function

  Function GetAll() As CustomerCollection
    Set GetAll = FromView("AllCustomers")
  End Function
  Function GetAllByCity() As CustomerCollection
    Set GetAllBySite = FromView("CustomersByCity")
  End Function

  Function GetAllByCountry() As CustomerCollection
    Set GetAllBySite = FromView("CustomersByCountry")
  End Function
  Function GetAllByStatus() As CustomerCollection
    Set GetAllByStatus = FromView("CustomersByStatus")
  End Function

  Function GetCustomerByID( id As String ) As Customer
    Set GetCustomerByID = New Customer( GetDocumentByKey( "CustomersByID", id ) )
  End Function
  Function GetCustomersMatching(query As String) As CustomerCollection
    Set GetCustomersMatching= New CustomerCollection(GetViewEntriesByKey("(LU-CustomersByAllKeys)", query, False))
  End Function
End Class


In turn the above code relies on a few additions to the base DocumentFactory class:


Class DocumentFactory
  Function GetViewEntriesByKey(ViewName As String, SearchTerm As Variant, ExactMatch As Boolean) As NotesViewEntryCollection
    Set GetViewEntriesByKey = GetView(ViewName).Getallentriesbykey(SearchTerm, Exactmatch)
  End Function

  Function GetViewNavigator(ViewName As String) As NotesViewNavigator
    Set GetViewNavigator = GetView(ViewName).Createviewnav()
  End Function

  Function GetAllViewEntries(ViewName As String) As NotesViewEntryCollection
    Set GetViewNavigator = GetView(ViewName).AllEntries
  End Function
  Function GetDocumentByKey(ViewName As String, Lookup As Variant) As NotesDocument
    Set GetDocumentByKey = GetView(ViewName).Getdocumentbykey( Lookup, True )
  End Function
End Class


What all this does is make it a lot less tiresome to get a handle on document(s) relating to a particular business object (in this case documents based on the "Customer" form). The base DocumentCollection class now has helper functions to get all view entries or simply a view navigator object. It also has a GetDocumentByKey method which defaults the ExactMatch option to True, because it always is, thus saving us passing it in to the call.

Going Forward

I've also been using these classes extensively in a new Domino database I've been lucky enough to create from scratch and have been working on lately. As I've gone along I've been tweaking and extending the classes and now feel they're at a solid point ready for wider use.

I don't want to bang my own drum too much, but they're amazing. You maybe have to use them to see why, but, once you do, there's no going back. If this were ten years ago they'd be almost revolutionary.

Talking of going back; will I ever!? Will I ever be asked to create a new Domino-based web app from scratch? Never say never and all that, but I have a feeling I won't. Which makes it a shame that I developed such a rich and powerful way of working with Notes objects via LotusScript so late in my days with Notes.

Either way, if you're still working with and creating new Notes apps I implore you to give these classes a go. You'll love them.

My plan is to scrub them all a bit, document them better and then share on Github, along with a demo database. Assuming there's interest?


    • avatar
    • Schlusi
    • Thu 11 Apr 2013 05:17 AM


    • avatar
    • Flaz
    • Thu 11 Apr 2013 07:44 AM

    Classes rules, not only in LS.

    I use intensively them too, there's only a quite annoying thing about the Erl() that returns a wrong line number in any class method. :(

    1. There is an IBM technote on that topic (21430623). This behavior was introduced with the Eclipse based LS editor and the technote describes a brilliant workaround:

      Go to "Options" and take note of the number of code lines. Add that number to the output of Erl(). Go to the full code view and - magic - find the correct line.

      Now the master question is: What about empty trailing lines? To count or not to count, that's the question.

      Show the rest of this thread

    • avatar
    • Jay
    • Fri 12 Apr 2013 04:33 AM


  1. +1

    So simple, yet so powerful!!

    • avatar
    • Ian Bradbury
    • Wed 8 May 2013 10:01 AM

    Jake, so if you're not creating new DB's on the Notes/Domino platform..... what technologies are you using more and more of for your new projects?

      • avatar
      • Jake Howlett
      • Wed 8 May 2013 02:40 PM

      It's looking likely that MS Dynamics CRM may plan a part in my immediate future. Coupled/front-ended with ASP.NET MVC.

      Show the rest of this thread

    • avatar
    • Ursus
    • Thu 23 May 2013 04:40 AM

    Jake, I am still using LotusScript on a daily basis (we are SLOWLY moving to Java/XPages) and there are a lot of databases here that are still going to be updated by me or that will be created from scratch using LotusScript. Would love to see your updated Weapper Classes :o)

    • avatar
    • harkpabst_meliantrop
    • Thu 11 Jul 2013 09:11 AM

    Finally found the time to dig a little into your code. Right now more to learn for my own coding rather than re-using your classes, I must admit.

    What puzzled me at first was the syntax you use for the constructors of your derived classes. E.g., the CustomerCollection class has this constructor sub:

    Sub New(docs As Variant), DocumentCollection(docs)

    End Sub

    I wasn't even aware of the fact, that you can actually pass a separate argument to the super class. Next I was wondering, why you wrote it like that at all.

    If I get Designer help right, the reference to the base class is only required, if the base class has a different list of arguments OR if you explicitly want to pass a different argument to the base class constructor. Otherwise the same argument passed to the sub-class constructor would be fed to the base class constructor at run time.

    Am I missing something? Or is it rather a matter of your personal taste?

      • avatar
      • Jake Howlett
      • Thu 11 Jul 2013 10:32 AM

      You know more than me already ;-)

      Bad habit I guess. Didn't realise it was optional.

Your Comments


About This Page

Written by Jake Howlett on Thu 11 Apr 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