Tip: Deleting Private On First Use Views/Folders

As has been previously posted, there’s a bug in r6 with using the GetView method of the NotesDatabase class to get a handle on POFU views/folders.

http://www-10.lotus.com/ldd/nd6forum.nsf/55c38d716d632d9b8525689b005ba1c0/60aafa7d9dc27e5a85256d1a00305c85?OpenDocument&Highlight=0,getview

http://www-1.ibm.com/support/docview.wss?rs=0&uid=swg21108323

Through testing I have found that once a Private view/folder has been created by accessing the Shared one, Formula commands such as @Command([RemoveFromFolder]) and Script such as PutAllInFolder( ) are using the Private one so putting docs into a POFU view/folder and removing them should not be a problem.

On the other hand, you might want to delete Private views/folders automatically when a user exits the database so they are cleaned up. In r5 the GetView method would grab the Private view/folder instead of the Shared one so if you wanted to delete the Private one, it was easy. With the bug in r6, others have posted workarounds (i.e. http://www-10.lotus.com/ldd/nd6forum.nsf/DateAllThreadedWeb/0ea2fac1f4731db285256da20048c1ee?OpenDocument) to loop through all of the views and find the matching one that has something in the Readers field. The problem with this is that if the database has quite a few views or folders, it can take forever to loop through them all when the user leaves the database.

To make up for the bug, I wrote some script using Notes API calls to grab the Private view by name, get its NoteID, get it as a Document using the NotesID, and then delete it. The code below goes into the Database Script. Some of the documentation is directly from the Lotus C API Reference.

NOTE: I deleted my errorhandling routine to send emails or edit the agent log but I would definitely suggest you add your own.

'DECLARATIONS

Const APIModule = “NNOTES” ’ Windows/32 only

Const NOTE_CLASS_VIEW= &H0008

Declare Function OSPathNetConstruct Lib APIModule Alias “OSPathNetConstruct” _

( Byval NullPort As Long, Byval Server As String, Byval FIle As String, Byval PathNet As String) As Integer

Declare Function NSFDbOpen Lib APIModule Alias “NSFDbOpen” _

( Byval PathName As String, DbHandle As Long) As Integer

Declare Function NSFDbClose Lib APIModule Alias “NSFDbClose” _

( Byval DbHandle As Long) As Integer

Declare Function NIFFindPrivateDesignNote Lib APIModule Alias “NIFFindPrivateDesignNote” _

( Byval hdb As Long, Byval NoteName As String, Byval NoteClass As Integer, NoteID As Long ) As Integer

Sub DeletePrivateView(db As NotesDatabase, vname As String)

' To open a Domino database on a server, use this function to create 

' the full path specification, and pass this specification as input to NSFDbOpen 

' or NSFDbOpenExtended.

p$ = String(1024, " ")

OSPathNetConstruct 0, db.Server, db.FilePath, p$	



' This function takes a pathname to an existing Domino database or database 

' template (whether on a Lotus Domino Server or a local database), opens the 

' database, and returns a handle to it. All subsequent access to the database is 

' carried out via this handle.  Use NSFDbClose to close the database file handle

' and deallocate the memory associated with it.

Dim hDB As Long

NSFDbOpen p$, hDB



' Given the name and NOTE_CLASS_xxx of a private design note (form, view,

' folder, helpindex, macro, field, or replication formula ), this function returns the note ID.

' Uses the View or Folder name passed to it - vname.

Dim retNoteID As Long

Dim result As Integer

result = NIFFindPrivateDesignNote(hDB, vname, NOTE_CLASS_VIEW, retNoteID)



'If result is anything other than 0, the Private Design Note could not be found

If result = 0 Then

	Dim doc As NotesDocument

	' Get the Private View or Folder by its NoteID

	Set doc = db.GetDocumentByID( Hex$(retNoteID) )	

	Call doc.Remove( True )

	Print "Removing : " & vname

End If



' This function closes a previously opened database.

NSFDbClose hDB

End Sub

And then in the QueryClose event, I just pass the database and view/folder name. Again, add your own errorhandling.

Sub Queryclose(Source As Notesuidatabase, Continue As Variant)

Dim s As New NotesSession

Dim db As NotesDatabase



Set db = s.CurrentDatabase



' Pass the name of the Private View or Folder to delete

Call DeletePrivateView(db, "Custom Query")

Call DeletePrivateView(db, "Search Results")

Call DeletePrivateView(db, "Excel Export")

End Sub

Hope this might help someone. If anyone sees a problem with it or places it could be improved, please let me know.

Bryce

Subject: Tip: Deleting Private On First Use Views/Folders

Hi!

Thanks a lot for your code. I have been experimenting in this field for a long time and used the “iterate through all views” method in various incarnations. But as you stated, it was simply too slow in bigger databases.

For me, it typical Lotus/IBM style. Invent a good feature (private views), than make it unusable (refresh). Again, thanks a lot for this snippet.

Chris


Subject: Tip: Deleting Private On First Use Views/Folders

Hi

I am a bit late in this discussion thread.

I have a related problem with “desktop private on first use” folder. It seems that I cannot add document into a “desktop private on first use” folder using NotesDocumentCollection.putAllInFolder method. Whenever I add doc into the folder, I get the message “Can’t move document to shared Private On First Use folder (FMAINSEARCH)”.

I have been stuck in this problem for days…Please help.

Subject: Tip: Deleting Private On First Use Views/Folders

Hi Bryce, You Rock!!! You wont belive it but the code you posted is of so much help.

Thanks Pal.

Cheers,

Subject: Problems with russian view name

Thanks for great job.I tried to use your tip - works fine with views that have english name. But when I used it for views with russian name it didn’t work.

After executing:

result = NIFFindPrivateDesignNote(hDB, vname, NOTE_CLASS_VIEW, retNoteID)

result has value 17412.

I tried to use aliases for views but have same result. Can you help me ?

Thanks.

Subject: RE: Problems with russian view name

You may need to use OSTranslate function. I found this note that may explain your problem and why English/ASCII characters work:

ASCII-to-EBCDIC conversion

Notes stores data internally in LMBCS (Lotus Multi-Byte Character Set), and the character string representation for the Notes C API parameters is assumed to be LMBCS. When you write C programs using EBCDIC character strings, you must use the Notes OSTranslate API to convert between the EBCDIC strings used by the program and the LMBCS parameters passed to and from the C APIs.

You may see Notes sample programs where this is not done. Those sample programs are technically incorrect, although functional in most cases. The sample programs usually work because ASCII code page 850 (PC ASCII) is a proper subset of LMBCS; therefore, characters in that character set do not need to be translated to and from LMBCS because they are already in LMBCS. Because most of today’s Notes applications use code page 850, or its 7-bit ASCII subset, the use of OSTranslate is not needed under those circumstances.

The C++ APIs require EBCDIC strings for input and output, rather than the LMBCS strings used for C APIs.

There may be posts in the forums related directly to this issue.

Bryce

Subject: Tip: Deleting Private On First Use Views/Folders

I have carefully implemented this code in the hope that it would solve my private view problems. However, although the code appears to run perfectly, as soon as it calls the API function, it returns a non-zero reply which says it can’t find the private design note. I know that the private view design does exist and that the name is correct and the db is correct. So, why does it not find the private view design note? Anyone any ideas? I’m tearing my hair out (what’s left of it!) trying to delete private views when the db is exited. My own code comes close but seems to fall over when normal users try it (Author access only). When I run with my ID, everything works fine (Manager access). Any help would be greatly appreciated. By the way, I have thoroughly searched the forum and technical docs and can’t find an answer that actually works. Thanks in advance, hopefully.

Subject: RE: Tip: Deleting Private On First Use Views/Folders

Hi Chris,

Do the users have “Create personal folders/views” checked in the ACL?

Is the private view “Shared, private on first use” and NOT “Shared, desktop private on first use”?

Subject: RE: Tip: Deleting Private On First Use Views/Folders

Hi Bryce,

Thanks a lot for this code it really help my apps. I had a question though, is there a way we can copy the search result display of notes using C API? As you will noticed it uses the view were you conduct your search for the display. Then when you click the Clear Result button it goes back to the original contents of the view. In this way its more faster to display the search result unlike when we use the “PutAllInFolder” method.

Again, Thanks for the tip.

Mon

Subject: Thanks

Massive thanks for this one Bryce - it has caused me no end of problems in the past

Thanks again

David