When GetProfileDocCollection fails
Posted by Theo Heselmans on June 18th, 2010
I needed to loop over all profile documents to update some stuff. LotusScript has a nice method for this, called GetProfileDocCollection.
This is how you use it:
...
Set dc = db.GetProfileDocCollection("Profile")
'I only need profile documents called 'Profile'
I skip the obvious initial Dim's and Set's, as we all know them. Set dc = db.GetProfileDocCollection("Profile")
'I only need profile documents called 'Profile'
This works fine most of the time. However, if there are too many profile documents, you get the following 'self-explaining :-)' error message:
"Profile document enumeration pool is full".
Some Googling reveals this Technote. With the following remark: "This problem was reported to Quality Engineering and determined to be a software limitation." Duh ?
They offer a workaround too, but this is complete BS.
Olga Babushkina offered me a great solution, by using CreateNoteCollection. I've never had any use for this function, but I can see it's power.
Here's how to use it:
Dim nc As NotesNoteCollection
Dim noteID As String
Dim doc As NotesDocument
... 'other dim's and set's here
Set nc = db.CreateNoteCollection(False) 'this creates an empty collection of noteIDs
nc.SelectProfiles = True 'we only need profile documents
Call nc.BuildCollection 'execute the building of the notecollection
If nc.Count = 0 Then Exit Function 'bail out if nothing found
noteID = nc.GetFirstNoteId 'get the first noteid
While noteID<>""
Set doc = db.GetDocumentByID (noteID) 'now get the doc itself
If doc.form(0) = "Profile" Then 'I only want to find the profile documents called 'Profile'
'do some stuff here
End If
noteID = nc.GetNextNoteId(noteID) 'get the next noteid
Wend
Dim noteID As String
Dim doc As NotesDocument
... 'other dim's and set's here
Set nc = db.CreateNoteCollection(False) 'this creates an empty collection of noteIDs
nc.SelectProfiles = True 'we only need profile documents
Call nc.BuildCollection 'execute the building of the notecollection
If nc.Count = 0 Then Exit Function 'bail out if nothing found
noteID = nc.GetFirstNoteId 'get the first noteid
While noteID<>""
Set doc = db.GetDocumentByID (noteID) 'now get the doc itself
If doc.form(0) = "Profile" Then 'I only want to find the profile documents called 'Profile'
'do some stuff here
End If
noteID = nc.GetNextNoteId(noteID) 'get the next noteid
Wend
Using this allowed me to have access to over 7000 profile documents.
Thanks Olga, a lifesaver !
Category: Domino Notes Show-n-Tell Thursday SnTT | Technorati: Domino, Notes, Show-n-Tell Thursday, SnTT
Comments (11)
Theo, you could also skip the doc.form(0) = "Profile" check by setting a selection formula for the NoteCollection prior to building it.
nc.SelectProfiles=True
nc.SelectionFormula={Form="Profile"}
Call nc.BuildCollection
@Nathan
Cool, there's apparently a lot I don't know about this stuff.
fantastic! This has saved me a lot of trouble too after accidentally creating hundreds of thousands of profile docs in a db!
bedankt voor deze ontzettend handige tip !
Theo, thanks for sharing this piece of code. Even though it looks short, it has potential!!
thanks for your help
I used this technique to determine the mail archive db name in the mail db.
Appreciated!
Great tip, thank you for sharing.
NotesNoteCollection too me was one of theses features, that when you discover them, make you call out: "Great, wonder what I could do with that!". Trouble is, one month later you still think: "What could I do with that???"
Note to myself, when reading this entry again in 4 years time:
Checking the Form item is NOT a safe way to find the desired profile documents! Neither directly (doc.form(0) = "Profile") nor setting the SelectionFormula property of the NotesNoteCollection.
Why not? It's so simple I can hardly admitt my mistake. If you create profiles in the backend, the Form item will not be there, unless you explicitely add it. Well, I didn't, so no documents were found. :-P
The safe bet would be to check the value of the $Name item instead. According to the C API documentation, its value is represented as "prefix_nnnprofilename_username":
prefix = the type of document (apperantly always $profile)
nnn = 3 digit character representation of the length of the profile name
profilename = the name of the profile document
username = the UserName of the profile (if any)
thanks to Theo and Olga for this great tip.
Thanks Theo !