How to Deal with “Private” and “Private on First Use” Views
Paul Davies posted a very interesting question in response to our Changing a Lotus Notes view’s status from private to shared article:
I’ve spent some time (not much admittedly) looking for a stable and consistent method to delete ‘shared private on first use’ views (so they can be rebuilt with a new design) and have not found a combination of $Flag values that do this. They seem to change across versions. I might be able to do it by looking at the Class and $Reader and $Author fields. Any tips on that?
Paul
Around here, we pretty much gave up using Private on First Use and Private views/Private folders about a year ago.
The reason: We found them to be too much trouble. (For example, they can cause some headaches if the user does not have at least “Create personal folders/views” enabled in the ACL. In such cases, the private view or folder will be saved in the user’s local Notes desktop file, no matter what).
Nowadays, instead of using private views, we mostly use code to generate views and change the formula by ourselves. This involves a bit more work at the onset but it’s ultimately a time-saver and really much easier to manage afterward. And what’s even nicer: this approach gives you the flexibility to allow more than one user (or role/group etc) to access a view. This will be explained in detail in an upcoming Ytria Tech Lab post.
So back to the original question…
Listed below are a couple of functions we’d used a while back in some applications that had Private on First Use views (the functions are called in the PostOpen event of the DatabaseScript).
As you’ll see, we were looking for Flags$ that contain a “V” value–this signifies the view is private (see the aforementioned earlier article for more on this “V” value); this approach was more than sufficient in our particular case (we never encountered any trouble related to this).
But I should warn you, we did have one big issue with this code: it was sloooow…. This less-than-ideal performance was mainly due to the fact it had to look for all the views in the database (using dbCurrent.Views).
(An aside: Going way back, before we adopted this code, we had something even slower. This old code needed to find the “original” Private on First Use view then check to see if anything changed. If the private view in question did not match the ‘original,’ it would be updated).
So here’s the code (I should mention that despite its lackluster speed, it worked quite acceptably in the applications we used it for) :
Sub DelAllPrivateViews
Dim count As Integer
Dim Max As Integer
Dim AllView As Variant
count% = 0
Print "Getting the list of Views/Folders"
AllView = dbCurrent.Views
Print "Getting the list of Views/Folders - Done"
Max% =Ubound(AllView)+1
Forall vw In AllView
count% = count%+1
Print Trim$(Str$(count%))+"/"+Trim$(Str$(Max%))+" Check View/Folder : "+vw.Name
If IsPrivateView(vw) Then
If TagPrint Then Print "Remove Private View/Folder : "+vw.Name
vw.remove
End If
End Forall
End Sub
Function IsPrivateView(vwCurrent As Variant) As Integer
Dim ndView As NotesDocument
Dim item As NotesItem
IsPrivateView = False
Set ndView = vwCurrent.Parent.GetDocumentByUnid( vwCurrent.UniversalId )
If Not (ndView Is Nothing) Then
If ndView.HasItem("$Flags") Then
Set item = ndView.GetFirstItem("$Flags")
If Instr(item.Values(0), "V") Then
IsPrivateView = True
Exit Function
End If
End If
End If
End Function
The Hack Approach
For another application built later on, we tried a completely different approach: We used special ‘hack’ views designed to list the private views and private on first use views. These hack views let you quickly find any private views needed to be updated/removed (by looking at their modification dates).
This approach is really quite efficient. And since it uses the design class as a filter, it’s pretty much foolproof. You will find an example database that you can download below.
This example database contains:
1 agent named “Launch Private View code” which uses 1 Script Library (PrivateViewScript) with 1 function (RemoveOldPrivateView). It also includes 2 views (AllPrivateView and AllPrivateFirstUseView).
But here’s a word of warning: you should not re-save the views in this database in the Domino Designer because the $FormulaClass fields have been altered (naturally, we used scanEZ to perform these alterations).
There is also a 3rd way of simulating this private view type functionality. This 3rd way is with folders.
You can create a folder for each user and put and remove documents from the folders as needed with a bit of script. If you want to manage when these user folders get updated , you can check “do not allow refresh replace design to modify..” and user the undocumented function @UpdateViewDesign to update these views with a scheduled agent. So you would have one master view and @UpdateViewDesign would update all the folders based on the master view you pass as an argument to the function. This is userful if you have many folders and do not want to have to update each one manually if the folder design needs to be changed.
You only have to update the master view and the scheduled agent would update all the folders for you.