Showtime
My Blackberry Enterprise Server Push Utility for the Lotus Notes Client, allows you to create Jobs for individual Channel, Message, and Browser Content Pushes, as well as allows you to delete Pushed Channel Icons from defined recipient devices.
Contact Information
Blogger, podcaster, writer, and geek Chris Toohey covers topics from application development to the latest must-have-gadgets.
Latest Updates
Products & Applications
Time Tracker
The idea is simple. At the start of your day - upon completion of your first task - create an entry highlighting what you did and whether you feel it was an efficient or inefficient use of your time. Based on several requests, you can also select the priority, apply categories, or even align your time against a project.
For Lotus Notes Client v8.0 and above, you can use the Time Tracker Widget to make this process even easier!
Zephyr
My Configuration-based Rich Text Mail Merge and Emailing Utility, Zephyr allows you to create rich, data-driven emails to support automated workflow - all via Microsoft Word Mail Merge-like architecture. Dear <firstname> allows you to personalize each email message not only to the individual recipient, but also to the individual application workflow event!
xCopy
xCopy is a simple configurable xCopy client for the Lotus Notes client. By creating and defining xCopy Profiles, you can batch process your file backup or remote upload jobs. With the addition of the xCopy sidebar widget, you can easily kick-off these jobs, and modify both the xCopy Profiles and xCopy itself.
Community & Resources
Lotus Technical Information & Education Community
The Lotus Technical Information & Education community is comprised of IBM, business partner, and customer subject matter experts who use product wikis, published articles, white papers, community blogs and the latest in social media to build and share high quality technical content.
OpenNTF.org - Open Source Community for Lotus Notes Domino
OpenNTF is devoted to enabling groups of individuals all over the world to collaborate on IBM Lotus Notes/Domino applications and release them as open source.
developerWorks Lotus : Wikis
Share your deployment experiences and best practices in our wikis and help IBM to create scenarios for successful deployments. Contribute to the community by collaborating on shared content and leverage the shared knowledge from that community.
Simple LotusScript NotesDocumentCollection Iteration
02/16/2010 12:21:31 PM by Chris Toohey
Sometimes a StampAll just doesn't give you enough flexibility or control when dealing with a NotesDocumentCollection. Sometimes you need to some logic behind each NotesDocument update. For those situations, we tend to use a technique called iteration... which sounds really awesome and consultant-like, but basically boils down to creating a looping function within your LotusScript.
There are several methods complete with built-in functions in LotusScript that allow you to iterate through NotesDocumentCollections, NotesViewEntryCollections, and such... so I'll start off by defining a simple use case, and then showing you how not to iterate through a given NotesDocumentCollection, and then ultimately showing you a solid approach to NotesDocumentCollection iteration!
Use Case
A scheduled Agent for a simple Project Management application will evaluate each new NotesDocument since last run and -- since we're going for simple here -- update the manager NotesItem with the value stored in the submitter's Person Document in the Domino Directory. Since this is an ideal world, every Person Document manager is both defined and contains the common name matching the manager's own Person Document.
Author's Note: Yeah, this would never happen, but this is a use case for iteration, not chasing down the manager NotesItem values... so go with me on this one.
How not to...
The below LotusScript uses the getNthDocument function to loop through a supplied NotesDocumentCollection and perform whatever NotesDocument application logic is needed (in this case, a Domino Directory lookup and NotesDocument update & save).
Function setManager(col As NotesDocumentCollection) Dim s As New NotesSession Dim counter As Integer Dim doc As NotesDocument Dim nab As New NotesDatabase(s.CurrentDatabase.Server, "names.nsf") Dim nabview As NotesView Dim nabcol As NotesDocumentCollection Dim nabdoc As NotesDocument Set nabview = nab.GetView("people") counter = 0 Set doc = col.GetFirstDocument Do Until(counter > col.Count) Set doc = col.GetNthDocument(counter) Set nabcol = nabview.GetAllDocumentsByKey(Join(doc.GetItemValue("submitter"), ""),True) Set nabdoc = nabcol.GetFirstDocument Call doc.ReplaceItemValue("manager", nabdoc.GetItemValue("manager")) Call doc.Save(True, False, True) counter = counter + 1 Loop End Function
provided by Julian Robichaux at nsftools.com.
If you have 5 NotesDocuments, this isn't that bad of an approach. I still wouldn't use it though and the reason is pretty simple: it scales horribly, and we're coding for the species here people!
The reason it scales so poorly is simply that the use results in the code losing it's place through the iteration. As a result, it starts from the first NotesDocument in the NotesDocumentCollection and steps through... the whole time asking it it's the Nth NotesDocument in the NotesDocumentCollection.
How To
Function setManager(col As NotesDocumentCollection) Dim s As New NotesSession Dim doc As NotesDocument Dim nab As New NotesDatabase(s.CurrentDatabase.Server, "names.nsf") Dim nabview As NotesView Dim nabcol As NotesDocumentCollection Dim nabdoc As NotesDocument Set nabview = nab.GetView("people") Set doc = col.GetFirstDocument Do Until(doc Is Nothing) Set nabcol = nabview.GetAllDocumentsByKey(Join(doc.GetItemValue("submitter"), ""),True) Set nabdoc = nabcol.GetFirstDocument Call doc.ReplaceItemValue("manager", nabdoc.GetItemValue("manager")) Call doc.Save(True, False, True) Set doc = col.GetNextDocument(doc) Loop End Function
provided by Julian Robichaux at nsftools.com.
Not a big change here, but using the getNextDocument steps through the NotesDocumentCollection and scales much better than the dreaded getNthDocument.
Conclusion
So what have we learned?
- There's no environment in the world where the above scenario would actually exist.
- I suck at creating Use Cases...
getNthDocumentis evil. If you come across it in your production code, you might as well just unplug the Domino server.getNextDocument-based iterations scale!
And, most importantly, NotesDocumentCollection iteration is an extremely powerful technique that can allow you to process large numbers of NotesDocuments with applied logic at the individual NotesDocument-level.






i always used
while not(doc is nothing)
wend
Mark, Do (While | Until) lets you use Exit Loop or add it later without changing the loop syntax.
I use:
Do While Not doc is Nothing
Loop
Let you exit out of it, but still is clearer to me.
Also check out NotesDocumentCollection.StampAll() and StampAllMulti.
...
...
Set collectionPiece = whateverCollection.GetNext(collectionPiece)
Set collectionPieceNext = whateverCollection.GetNext(collectionPiece)
...
...
Set collectionPiece = collectionPieceNext
Loop
I forgot: above code is pseudocode, not real LotusScript, just meant to generalize and show the concept
Lars - Yeah - will do something like your second code block if I might need to delete the working document... but otherwise I tend to stick to the first code block.
I've developed this style of defensive coding because I get to maintain a lot of crufty code. Requirements change, loops must be built, etc... I use this method to avoid unfortunate side-effects and thus also avoid egg on my face caused by cruftiness that was already there.
@Paul you need an Exit Do to exit the loop...
Ok, I give, why use:
Join(doc.GetItemValue("submitter"), "")
instead of
doc.GetItemValue("submitter")(0)
?
Yikes - it's really the simple things that start the best conversations huh?
While Not(doc is Nothing) always felt like Hide-When Formula logic to me.
@Lars:
Yeah, adding the next above the iterative payload is one of those things that you learn to do after you've pulled your hair out trying to figure out why your NotesDocument deletion routine keeps failing. It's an excellent practice, but I was going entry-level iterating with this particular post.
@Timothy:
Dunno, just a habit I've gotten into. I forget why now honestly, but I think it has something to do with Java.
@Chris that's why I chipped in, hoping to up the level, and save egg... And because we discussed it, they can even read why!
Hmmm, just was in a bit of code with this in it:
While Not(Doc Is Nothing)
Call ExportOne (doc, xlWkshtObj)
Set Doc = collection.GetNextDocument( doc )
Wend
Do you know if there are any hard/fast rules about performance of a While Not vs a Do Until?
OK, so I've just looked up the View article mentioned above at times for While and Do loops.It was May/June 2006 issue, but I reckon the speeds won't have changed much, at least comparatively.
What it says is there's not a lot of difference. In fact, on a looping test just reading from a doccollection, Do was faster over 100K docs, While over 200K docs, and Do faster again over 300K
So, I think it's just whatever you want to use.
Lars, the defensive coding is only needed if you change the doccollection while looping (eg deleting a doc). I find it's needed more often when looping through a view and changing values that then change the position of docs in views
Lars, the defensive coding is only needed if you change the doccollection while looping (eg deleting a doc). I find it's needed more often when looping through a view and changing values that then change the position of docs in views
@DanKing:
Dan, you can use view.AutoUpdate = False that prevents position changes of documents while iterating through a view once it is initialized.
When I think I'll be doing a large number of 'getdocumentbykeys' in a loop, I prefer to do it this way by first rolling through a view and putting everyone in a list. I believe list lookups are quicker than repeated getdocumentbykey calls.
There's some other tricks to speed it up further
I agree to a point. It's better to cache the manager doc after the first lookup than cache them all at the start of the code. I work in a company of 50,000+ people... imagine what that list would be like. :-)
While(doc is Not Nothing) is far harder for humans (and the peeps coming in behind you after you are long gone) than Do Until doc is Nothing.
Every time you use inverse boolean logic a puppy dies. Do you want that on your conscience? I don't think so....
Code of maintainability, understandability and readability. If you do, Santa will bring you a Wii.
@tom. Yeah, but I think you might be surprised...give it a shot next time. Notes list items are quite flexible.
I've used this method with > 40,000 entries in the initial list. It's still quite quick compared to doing 40k getdocumentbykey calls:)
@Darren
Considering most of us recommended Do While Not (doc Is Nothing)... I think it's readable enough.
In fact... I might use it more considering it irritates the philosophical developer. :-)
Lists are amazing, and are really underused in LotusScript. Perhaps that'll be the topic of my next beginner tip!
Agree lists are amazing. I usually builds a class managing a list of objects (wrap the list in a class for easy management and passing around).
While I'd love to read that article, it's currently out of reach for me. I have to rely on publicly available sources for budgetary reasons.
Lotusscript lists are amazing and what's also amazing is that in every other programming language they are called Maps or Dictionaries (and even associative arrays).
Most programming languages have lists AND maps/dictionaries. I would really liked to have had a real list type in Lotusscript all these years (I started writing LS with R4 alpha) in addition to the map. Sometimes you just need a list of things. No key. No index. Just a list, like a python list or a Java Array List. A Set or Tuple would have been useful too. In a scripting language, these data structures should all be first class types, like the Lotusscript map, I mean list.
But a generic (in the value) map called a list? Hey, that's worked out pretty well. Was this about lists ;-?
Love the variation of how people do their loops; it would be an interesting survey to see the combinations of Do/While/Until/Not/Nothing. I definitely agree on thinking about future maintenance, and always using Exit Loop rather than Goto.
And yes, any calls to getNthDocument - unless they're truly only interested in that one Nth document - are evil.
Love the Captcha!
I was always wondering what lists were for - the description in Designer help is somewhat clumsy. Then I found out that they're basically hash tables - and I use these a lot in Java coding. Doh. How did I ever code LS without lists? ;-)