logo: Ytria - Essential Tools for IBM Notes and Domino (Lotus)
Ytria Tech Lab
Articles, Tips, and Code for IBM Notes and Domino Administrators & Developers

How to Deal with “Private” and “Private on First Use” Views

on 11/25/09


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?

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
        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).

private view list database

Click this image to download our private view list database example

Credit: All code in this post was written by Eric Houvenaghel.

1 Comment

  1. 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.

Leave a Comment

To diplay code in your comment, put the code between these brackets: [cc]your code[/cc]. You can also put inline code by using these: [cci]your inline code[/cci]