Name based hide-whens with nested groups

First, in the process of writing this post, I had a nagging feeling that I was missing something. I could not shake it but I wrote the post anyway and saved as a draft. I did some research and found that I had essentially done something the hard way. A new feature added to R6 @Formula language (hence why I could not remember it) gave me the functioanlity that I needed. So since the post was written, I’ll leave it and detail both methods at the end.


Ok, so I find myself hacking my way through an app written by a here-today gone-tomorrow consulting company to add in a feature where no forethought had been used. In a nutshell, the application had a list of names from a directory, and a key action button was hidden based upon the condition that the user is a member of that list. Easy enough when you list people individually, but when you add groups it gets more difficult. Add the idea of nested groups, or group names within groups, and alot of developers will simply get that blank stare on their face.

Funny how when you ask the original authors about the functionality (which to me should have been there to begin with), they are suddenly there to help…….for a price. Numbers are irrelevant, but their estimate was 2 days!!

Enter the concept of iteration, where a function can call itself. In the case of finding the members of a nested group, the function that looks at each group members name, will call itself when it comes upon another group name. All the while building a list of only user names. So we take the list of user/group names, and pass each list member into our function. If the list member is a user name, then we add that name to our list. If the name is a group name, we call our function again, passing it the group name, and it repeats itself.

Once we have that list of individual user names, all we need to do is alter the hide-when to use our new list when determining if to render the button, and we are all set. Total time to deliver…….4 hours (5 including my final method). Now you know why I left the consulting arena; I am too honest.

Here is a more detailed breakdown of the code and its execution. The exact usage of the lotusscript is dependant upon your situation, but I do the call when I am saving the document and change the hide-when to look at my new list. The @Formula option I used within the button hide-when formula.

First, the easy way. In R6 Domino we now have the function @UserNamesList which returns all names, groups, and roles that the present user belongs to. I eventually used this to determine if the present users name, or group memberships are listed in the invite list to allow button visibility. This method has to be coupled with another R6 addition which was @For.

This is the @Formula code to hide the button from someone not in the invite list. userCheck is a boolean value that is the determinator. If it is false (0) then it will hide the button.

userList := @UserNamesList;
userCheck := 0;
inviteList := @Explode(@UpperCase(@Implode(@Name([Abbreviate];invitees);":"));":");
@For(n := 1; n < = @Elements(userList); n := n + 1;
     @If(@IsMember(@UpperCase(@Name([CN];userList[n]));inviteList);
          userCheck := 1;
          ""
     )
);
@If(userCheck=0; @True ; @False);

So now we come to the much longer lotusscript solution that would only be needed if we did not have access to the credentials of the current user (i.e. a server process).

‘Here are some global objects:
Dim arrMemList() As String
Dim intMemListSize As Integer

‘ This is the code that calls the function originally, and sets the new field in the end

Dim s As New NotesSession
Dim dbThis As NotesDatabase, dbNames As NotesDatabase
Dim doc As NotesDocument
Dim server As String
Dim invitees As Variant
Dim bSuccess As Boolean
Set dbThis = s.CurrentDatabase
server = dbThis.server
Set dbNames = New NotesDatabase(server, "names.nsf")
Set vw = dbNames.GetView("($VIMUsers)")
Set doc = You_Set_This
invitees = doc.ListFieldWithUserNames
intMemListSize = -1
Forall member In invitees
	If createExplodedNameList(vw, Cstr(member)) Then
		bSuccess = True
	Else
		bSuccess = False
	End If
End Forall
If bSuccess Then
	doc.newListOfNames = arrMemList
Else
	Messagebox "There seems to be a problem parsing the invitee names. "
	doc.newListOfNames = arrMemList
End If

‘ finally the function that gets called everytime it has a group name to explode

Function createExplodedNameList(vw As NotesView, key As String) As Boolean
	On Error Goto errorCatch
	createExplodedNameList = False
	Dim docLoop As NotesDocument
	Dim nm As NotesName
	Dim varMembers As Variant
	Set docLoop = vw.GetDocumentByKey(key)
	If docLoop Is Nothing Then
		Exit Function
	Else
		varMembers = docLoop.Members
		Forall member In varMembers
			Set nm = New NotesName(Cstr(member)) ' check for Notes name or group name
			If nm.IsHierarchical Then ' this is a hierarchical notes name
				intMemListSize = intMemListSize + 1
				Redim Preserve arrMemList(intMemListSize)
				arrMemList(intMemListSize) = nm.Abbreviated
			Else
				' this is a group, go explode it
				Call createExplodedNameList(vw, Cstr(member))
			End If
		End Forall
	End If
	createExplodedNameList = True
	Exit Function
errorCatch:
	Messagebox "Error in getGroupMembers..createResultsNode in line: " & Erl() & " error$: " & Error$
	Exit Function
End Function

Leave a Reply


Spam Karma 2 has sent 158 comments to hell and 17 comments to purgatory. The total spam karma of this blog is -20. What's your karma?