I had to put together some code for my company and I thought I would share it here. My requirements were to restrict certain people (approximately 300 out of many thousands) from mailing any of the groups (approximately 1300) in the public NAB of our store environment.
I would first like to recognize Thomas J McArthur who put together some awesome code to address this need, and it is this same code that I started with as a base. It can be found here.
One of the major shortcomings with this code though, was that it only worked if a user was online or, if they were offline, if they in fact had a local replica of their public NAB and you knew what that file name was. If you could not access the “allow” group for some reason you cannot send the message. In his environment, he seemed to be able to count on knowing that his users could access at least a local replica of their public NAB. I could not count on that constant here. My users are bound to have either no local replica of local replicas named something along the lines of
“ahu32r523-ausdfas4fdashid10t.nsf”
Also I found that it only worked if you were mailing only one of the restricted groups. If you were mailing more than one or if the group name was buried in the midst of a whole bunch of other recipients, it did not pick it up. Also was the problem for me that the restricted groups were hard-coded in the formula itself. This was not practical for me since I had over 1300 restricted groups. Lastly was the problem for me that his code found a user in a group and then allowed them to send the mail. I had to reverse that because only 300 people were to be restricted. So my logic had to change to state that if you find them in the group, restrict them.
So, a very long-story-short and after many, many, many (did I say many?) changes and evolutions of my code, I decided to store all of the restriction documents in a user’s mail database. This addressed the online/offline issue. I did this by creating a db on a server that contained a simple form (form name = “fkeylist”) with only a few fields. One contained the doc name that I keyed on in the first column of my view (for @dblookups) and the other contained the members.
I then gave the business owner access to change those documents as they needed. In this db I created three docs. The first containing half of the restricted groups, the second containing the other half, and the third containing all the restricted users.
I then wrote some code in lotus script and put it in the post open event of our mail db template to copy the restriction docs into a user’s mail file – if they were in the restriction group. Additionally, I had to add a view called “($Keyword Fields)” in the mail db template so that my @dblookups in the formula code would have the proper view to do a lookup against. I also changed my “all documents” and “drafts” view selection to not contain docs with the form “fkeylist.” This prevented users from seeing the docs and deleting them mistakenly or otherwise. Here is this code:
Sub Postopen(Source As Notesuidatabase)
' written by Bryan Horton
Function AbbName(canonicalname As Variant) As String
’ Abbreviate a canonical name.
Dim nname As NotesName
Dim session As New NotesSession
Set nname = session.CreateName(canonicalname)
If nname.IsHierarchical Then
AbbName = nname.Abbreviated
Else
AbbName = canonicalname
End If
End Function
On Error Goto errhand
' declare some stuff
Dim s As New notessession
Dim localyn As String
Dim usn As String
Dim db As notesdatabase
Set db = s.currentdatabase
Dim view As notesview
Dim ldoc As notesdocument
Dim lndoc As notesdocument
Dim doc As notesdocument
Dim doc1 As NotesDocument
Dim doc2 As notesdocument
Dim kwdb As New notesdatabase("whatsmyservername","Keydb.nsf")
Dim kview As notesview
Dim keylist As Variant
Dim newdoc As New NotesDocument( db )
Dim newdoc1 As New NotesDocument( db )
Dim newdoc2 As New NotesDocument( db )
Dim kl As Variant
Dim fn As Variant
%REM check to make sure user is from ACME, if not script ends
%END REM
usn = s.UserName
If Not usn Like "*OU=ACME*" Then
Exit Sub
End If
%REM check to see if user is in local db. If so I assume no connection to the network and end the script
%END REM
localyn = db.server
If localyn = "" Then
Exit Sub
End If
%REM get handles on needed docs in keyword db and on first restriction doc in mail file if it exists.
%END REM
Set view = db.getview("($Keyword Fields)")
Set ldoc = view.getfirstdocument
Set kview = kwdb.getview("Keyword Fields")
Set doc = kview.GetDocumentByKey("M&MGroupsA-H")
Set doc1 = kview.GetDocumentByKey("M&MGroupsM-T")
Set doc2 = kview.GetDocumentByKey("M&MGroupsBlockList")
%REM Check to see if user is in restriction group on server and to see whether or not they have any restriction docs
in their mail file. If they are not in the group on the server and they have no restriction docs in their mail file
the script ends. If they are not in the group but they do have local restriction docs, the docs are deleted and then the script ends.
This covers those people who were once in the restriction group and then removed and should no longer be restricted.
%END REM
If Not (doc2 Is Nothing) Then
keylist = doc2.KeyList
If Isnull(Arraygetindex( keylist, AbbName(usn) )) And ldoc Is Nothing Then
Exit Sub
Elseif Isnull(Arraygetindex( keylist, AbbName(usn) )) And Not ldoc Is Nothing Then
While Not(ldoc Is Nothing)
Set lndoc = view.getnextdocument(ldoc)
Call ldoc.remove(True)
Set ldoc = lndoc
Wend
Exit Sub
End If
End If
%REM check to make sure I have handle on all three docs needed for mail restriction formula (in the send action) to work properly.
If I have the handles, I delete old docs in user's mail file and then create new documents containing the field values out of the source db. This insures users have the most up-to-date version of the restricted docs.
and no, (copytodb) method does not work as it retains the same unid and screws up replication (because of deletion stubs).
%END REM
If Not (doc Is Nothing) And Not (doc1 Is Nothing) And Not (doc2 Is Nothing) Then
While Not(ldoc Is Nothing)
Set lndoc = view.getnextdocument(ldoc)
Call ldoc.remove(True)
Set ldoc = lndoc
Wend
kl = doc.KeyList
fn = doc.FieldName
newdoc.KeyList = kl
newdoc.FieldName = fn
newdoc.Form = "fkeylist"
Call newdoc.save(True, False)
kl = doc1.KeyList
fn = doc1.FieldName
newdoc1.KeyList = kl
newdoc1.FieldName = fn
newdoc1.Form = "fkeylist"
Call newdoc1.save(True, False)
kl = doc2.KeyList
fn = doc2.FieldName
newdoc2.KeyList = kl
newdoc2.FieldName = fn
newdoc2.Form = "fkeylist"
Call newdoc2.save(True, False)
End If
errhand:
If Erl() <> "0" Then
Print Err & Error & " on " & Erl
Resume Next
End If
End Sub
See Part Two here: