Skip to main content
    Country/region select      Terms of use
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks  >  Lotus  >  Forums & community  >  Best Practice Makes Perfect

Best Practice Makes Perfect

A collaboration with Domino developers about how to do it and how to get it right in Domino

For a Lotusphere demo, I wrote an agent to execute on all documents in the currently highlighted top-level category, and I thought the technique might be useful to others.  Since it isn't central to what I'm presenting, I won't be covering it during The Show, so I'll put it out here instead.

The problem isn't dead simple because:

  • The NotesUIView.CaretCategory property doesn't always tell you which top-level category you're in -- for instance, if you have multiple levels of categories, it returns the inmost category you're in, and that's not useful for looking up the set of documents.
  • NotesView.GetAllDocumentsByKey doesn't work in views with multiple levels of categorization -- you have to use a view navigator.
  • The selected document may be in multiple categories.
  • This technique doesn't work in views containing totals -- the total gets reported as the CaretCategory value, which is fairly useless.
  • Since we need the NotesView object to get the matching documents, this doesn't work in "desktop private" views.
  • The category headings need to be text, which is unfortunate since date categories are very useful in this context.  Something like this can be made to work in views categorized by non-text, but I don't see a way to combine that with multiple levels of categories.
If you know the view has only one level of categorization, you don't need to use quite this complex a function. However, in most applications there are different views with different designs, or a view may later be modified, and it's just as well to have a system that works in every circumstance you can manage to make it work.  To this end, this routine could probably be improved, e.g. to check whether there's a totals column interfering with the CaretCategory, or to use a NotesViewNavigator to scan for a second-level category entry by its note ID to find its parent, instead of displaying an error message as we do now (though that might be a bit slow).

Anyway, here's the code; it should be fairly clear how to call it.

Function GetSelectedCategory(Byval windowTitle$, returnKey$) As NotesDocumentCollection
     ' Returns all the documents in the highlighted top-level category, or Nothing
if there is a problem.
     ' User may be prompted or an error message displayed. Argument gives window title

     ' to use for such prompt dialogs.

     ' returnKey (output value) is used to returns the selected key value, in case the caller wants it for

     ' telling the user anything.

     Dim session As New NotesSession

     Dim coll As NotesDocumentCollection

     Dim ecoll As NotesViewEntryCollection

     Dim db As NotesDatabase

     Set db = session.CurrentDatabase

     Dim wksp As New NotesUIWorkspace

     Dim result As Boolean

     Dim uivu As NotesUIView

     Dim vu As NotesView

     Set uivu = wksp.CurrentView

     Set vu = uivu.View                ' assumes this is not a desktop private view -- if it is, sorry!

     Dim key, strID$

     Dim abort As Boolean

     key = uivu.CaretCategory

     strID = uivu.CaretNoteID

     If strID Like "[89A-F]???????" Then

             ' category row is highlighted. We'll assume CaretCategory is our key value

             ' (though if the highlighted category isn't top-level we have no way to tell what the

             '  top-level one is.)


             ' We have a document selected: we may be able to correct the
CaretCategory value if it's incorrect.
             abort = True

             Forall col In vu.Columns

                     If col.IsCategory Then

                             Dim docSelected As NotesDocument

                             Set docSelected = db.GetDocumentByID(strID)

                             Dim cats, copyCats

                             cats = Evaluate(col.Formula, docSelected)

                             copyCats = cats

                             Forall valu In copyCats

                                     If valu key Then

                                             ' we're good -- highlighted doc's first categorized column does match the key.

                                             abort = False

                                             Exit Forall


                                             valu = Cstr(valu)

                                     End If

                             End Forall

                             ' if we get here, the caret category doesn't match a value in the first sorted column

                             ' Ask the user which category they meant.

                             If Ubound(cats) = 0 Then

                                     ' with only one choice, correct the key automatically.

                                     key = cats(0)


                                     key = wksp.Prompt(PROMPT_OKCANCELLIST, windowtitle, {I can't tell for sure which category you mean -- please select one:

(in future, select the category row and I won't have to ask)}, copyCats(0), copyCats)

                                     If Isempty(key) Then Exit Function

                             End If

                             abort = False ' we have a key

                             Exit Forall ' after finding first sorted column we're done looking

                     End If

                     If Not abort Then Exit Forall

             End Forall

             ' if we reach this point we scanned all columns and found no categories.

     End If

     If abort Then

             Msgbox {Operation failed; can't tell which was the current category, probably because the design of this view is not appropriate for this agent.}, MB_ICONSTOP, windowtitle

             Exit Function

     End If

     ' locate the documents to be processed.

     returnKey = key

     Set coll = db.CreateDocumentCollection

     Dim nav As NotesViewNavigator

     Dim doc As NotesDocument

     Dim entry As NotesViewEntry

     Set nav = vu.CreateViewNavFromCategory(key)

     Set entry = nav.GetFirst

     Do Until entry Is Nothing

             If entry.IsCategory And entry.IndentLevel = 0 Then

                     Exit Do

             End If

             If entry.IsDocument Then

                     coll.AddDocument entry.Document

             End If

             Set entry = nav.GetNext(entry)


     ' optional if statement -- the caller might want to have its own exception code to handle this case.
     If coll.Count = 0 Then

             Msgbox {No matching documents found (category key = '} & key & {').

This can happen either because you have no access to documents in that category, or because it's not a top-level category. Either select the top-level category row, or a document.}, _
MB_ICONSTOP, windowtitle

             Exit Function

     End If


     Set GetSelectedCategory = coll

End Function

Andre Guirard | 12 January 2009 09:53:00 AM ET | Home, Plymouth, MN, USA | Comments (2)


1) Question...
David Leedy | 1/12/2009 10:49:58 AM


I see you're using db.CreateDocumentcollection. Is that still undocumented? Or did that change in 8.5 and we can use it without fear?


2) Run agent on selected category
Andre Guirard | 1/12/2009 3:44:09 PM


The function is officially unsupported. You may judge the degree of risk that it will be removed from the product, considering that doing so would break older versions of Lotus' own mail file design. If you're uncomfortable with that, I have documented an alternate method of creating an empty document collection here:

3) NotesView.GetAllDocumentsByKey doesn’t work in views with multiple levels of categorization? false
tigreci | 4/4/2016 10:44:25 AM

Sorry but my english is not well but yes Getalldocumentsbykey run with multiple categorization level only use array not string example

Dim clave (1 To 3) As String

clave(1)="value category 1"

clave(2)="value category 2"

clave(3)="value category 3"

Dim coldoc As notesdocumentcollection

Set coldoc = view.GetAllDocumentsByKey(clave,True)

4) It’s fine if you specify all the category values...
Andre Guirard | 4/4/2016 12:05:38 PM

The problem is when you just provide one key. For instance, suppose you have main-level category "A" and subcategories "x" and "y". If you just search for "A" you would expect to get ALL the documents in subcategory "A". Instead you only get the documents in "A\x" -- even though you didn't specify "x" as a key.

 Add a Comment
Comment:  (No HTML - Links will be converted if prefixed http://)
Remember Me?     Cancel

Search this blog 


    About IBM Privacy Contact