January 18, 2008

Folder and embedded view problems

Notes is not being nice to me right now!

The last couple of days I have been struggling with notes problems that are really frustrating and to me seems like they are limitations hard to get around. If it's possible to get around them it's a lot of work and causes something else in the requirement specification to fail. I have another problem not described below which makes this feeling worse. I might post about that later on.

I posted on developerworks the other day about one of the problems and got a response which were good suggestions but not solutions I'm afraid.

Here is the issue with more information on other approaches:
We have a situation where there are currently 13 databases, one for a specific project and all inheriting from the same template. The prediction is that a new database (with the same template) will have to be created every week for some time. This is not a suitable solution and instead we want one database where all projects can fit in.

The people working with a specific database still need to feel that they are working the same way seing only the documents for a particular project. The database has a frameset with an outline displaying 23 views which are opened in the right frame.

Approach #1:
For each existing and each new project (former db), create 23 new outline entries and 23 new views. Since we don't know how many projects the new db will contain this is not a good solution looking at performace and usability.

Approach #2:
Use an environment variable to set which project a specific person is working on. Depending on the choice, a fixed amount of outline entries would display computed content in a fixed amount of views or folders, based on the environment variable.

Using approach #2 and views:
It is possible to (in queryopen of a view), when clicking an outline entry for the view, perform an FTSearch (for example FIELD field_name = field_value) to find and display the documents for a specific project. However the resultset is not categorized and it has to be, so this is not an option.

Using approach #2 and folders:
In queryopen of a folder, delete any existing content in the folder using "RemoveAllFromFolder" (from previous runs), perform a lookup to a view (getDocumentsByKey on the environment variable value) and put the result (notesdocumentcollection) into the folder.

This last solution works great BUT only when there are no response documents and also only if you are the only one working with the folders since they are shared. When clicking on a folder that has response documents, a message box displays saying:

"Notes error: All related response documents are being removed from this folder along with their parents. (FolderName)".

Also when refreshing the folder afterwards, all documents disappears. This error is due to the "RemoveAllFromFolder".
I can't seem to catch the error either (I think it is 4005) and do a Resume Next or similar because it is not treated as an error. A messagebox appears and the folder is not rendered as it should.

If I uncheck the folderoption "Show response documents in a hierarchy" the problem is gone. However this is not an option either.

So even if I got rid if this problem I would still be stuck with the shared folder problem. I don't won't to create private folders because then I would be stuck with perfomance issues anyway if there are many users.
I guess I could create a new folder each time an outline entry is clicked for a user, populate it and then remove it when the user leaves. But that really seems complicated as well as time-consuming for the user. It can not take longer time than it already does to open a folder as it is now.

Approch #3:
Each outline entry refers to a form which has the original view embedded. Now this is simple and works great BUT now I can't search in the embedded view AND the embedded view can not be auto-collapsed which makes it harder to read.
I tried to fix the search issue by adding a text input field above the embedded view and do an FTSearch but FTSearch is not available for NotesUIViews.
Then I saw a post on developerWorks with a link to an article by Mr André Guirard from the View which has a solution where the search button is an action in the embedded view's action bar. When clicking on it a dialog box opens a new form which creates a query and performs a search.
This does not work for me however as I want it to. Not in the following example database and not when I try it myself. I'm sure I'm doing something wrong, I am running out of patience though...

I am stuck and either they will have to live with multiple databases as it was before or they will have to use this last example without the search capability (I have added a section in the outline where all views are categorized on the projects so the functionality is still there).

Now I wonder:
#1 Does anyone know a solution or workaround to this folder approach or any of the other approaches?
#2 Does anyone have a suggestion to another solution?
#3 Does anyone have a shoulder to cry on? ;-)

Below is the QueryOpen sub of one of the folders for approach #2:
Sub Queryopen(Source As Notesuiview, Continue As Variant)
Dim s As New NotesSession
Dim db As NotesDatabase
Dim folder As NotesView
Dim view As NotesView
Dim folderName As String
Dim viewName As String
Dim coll As NotesDocumentCollection
Dim vec As NotesViewEntryCollection

folderName = "ReqByReqIdFolder"
viewName = "ReqByID2FolderLookup"

Set db = s.CurrentDatabase

' * Get environment variable
value$ = s.GetEnvironmentString("currentProject")

Set folder = db.GetView(folderName)
Set vec = folder.AllEntries

Call folder.Refresh
folder.AutoUpdate = False

' * Remove all documents from folder from last session
Call vec.RemoveAllFromFolder(folderName)

Set view = db.GetView(viewName)

' * No environment variable has been set
' * Add all documents in view to folder
If (value$ = "") Then
Set vec = view.AllEntries
Call vec.PutAllInFolder(folderName, False)
Exit Sub
End If

' * Get all documents from view which are categorized by the value 'value$'
' * Put them in folder
Set coll = view.GetAllDocumentsByKey(value$, True)
Call coll.PutAllInFolder(folderName, False)

Call folder.Refresh
folder.AutoUpdate = True
Call folder.Refresh
End Sub

/ Take care!

Technorati tags:
, , , ,


Vitor Pereira said...

Nick, I'm working on an application that uses the folder technique for searches and I am using private on first use folders, the database has over 200.000 docs and I have no performance issues.
I am not doing this with response docs, so I don't have the problem you mention and which is reported here.

Did you try using a show single category view and have the users select the project on a field or something like that?

Niklas Waller said...

I haven't tried that, worth a try then. I read about it in the designer help and if one is really picky there is a backside of it if the design is modified of the views/folders after a while when a lot of private views have been already created. This is because they don't inherit the design anymore when becoming private.
Then the design won't be reflected in the private views until they are deleted and accessed again. However you can't get it all I suppose.
If I only could solve the response documents problem when deleting the folder content then.

Have you got any experience in adding and deleting folders dynamically for each user?

The current solution I am working on is embedded views on forms. The embedded views are categorized with the project value and using 'Show single category' with the value of the project as you assume which is fetched from an environment variable. The environment variable is set when choosing a value from a combobox in the left frame of the frameset.

Thank's for your help!

Anonymous said...

@SetViewInfo? Ever tried that?

Niklas Waller said...

I actually have. Good point though.
I remember trying it briefly and that I fast came to the conclusion that I would not use it since it didn't work. Partly this formula function has several recognized bugs and partly it seems to have several not yet identified bugs. Thus, unfortunately not a solution to this problem.

James said...

I've come up against this before and think I came up with a particularly novel way to cope with this.

I use the private on first use folder but with a twist. On the post open event of the database script I have placed some code to detect if the shared copy of view has been modified since the private folder was created. and if so, delete it and refresh it.

code here:
Sub UpdatePrivateView()
Dim s As New notesSession
Dim db As notesDatabase
Dim ws As New NotesUIWorkspace
Dim view As notesView
Dim viewNote As notesDocument
Dim pviewNote As NotesDocument
Dim flags As Variant
Dim removeIt As Integer

Set db = s.currentDatabase

Dim views As NotesNoteCollection
Dim privateviews As NotesNoteCollection

Set privateviews = db.CreateNoteCollection(False)

privateviews.SelectFolders = True
privateviews.SelectViews = True
privateviews.SelectionFormula = |@Contains($Flags; "p") & !@Contains($Flags; "V")|
Call privateviews.BuildCollection()

pfirstNote$ = privateviews.GetFirstNoteId
If Not pfirstNote$ = "" Then Set pviewNote = db.GetDocumentByID(pfirstNote$) Else Set pviewNote=Nothing
While Not pviewNote Is Nothing
ptitle = Split(pviewNote.GetItemValue("$TITLE")(0), "|")
Set views = db.CreateNoteCollection(False)
views.SelectFolders = True
views.SelectViews = True
views.SelectionFormula = |@Contains($TITLE;"| & ptitle(Ubound(ptitle)) & |") & @Contains($Flags; "V")|
Print "Searching for " & |@Contains($TITLE;"| & ptitle(Ubound(ptitle)) & |") & @Contains($Flags; "V")|
Call views.BuildCollection()
Print "Found " & Str(views.Count) & " Note(s)"
firstNote$ = views.GetFirstNoteId
If Not firstNote$ = "" Then
Set viewNote = db.GetDocumentByID(firstNote$)
Print "No private view found for " & ptitle(0)
Set viewNote=Nothing
Call ws.OpenDatabase("","", ptitle(0))
Call ws.ViewRebuild()
Call ws.CurrentView.Close()
End If
While Not viewNote Is Nothing
If Instr(1, viewNote.GetItemValue("$Flags")(0), "V") > 0 Then 'ignore non-private views
Print "Private view Checked"
vtitle = Split(viewNote.GetItemValue("$TITLE")(0), "|")
Print "Checking Titles " & ptitle(0) & " - " & vtitle(0)
If ptitle(0) = vtitle(0) Then 'check if is master doc
Print "Checked Matched Titles"
If Not viewNote.NoteID = pviewnote.NoteID Then ' double check its not the same document
Print "Checked Different NoteIDs"
If pviewNote.LastModified > viewNote.Created Then
Print "Checked Modified Dates"
Print "Remove View - " & vtitle(0)
Call ws.OpenDatabase("","", ptitle(0))
Call ws.ViewRebuild()
Call ws.CurrentView.Close()
End If
End If
End If
End If
firstNote$ = views.GetNextNoteId(firstNote$)
If Not firstNote$ = "" Then Set viewNote = db.GetDocumentByID(firstNote$) Else Set viewNote=Nothing
Delete views
pfirstNote$ = privateviews.GetNextNoteId(pfirstNote$)
If Not pfirstNote$ = "" Then Set pviewNote = db.GetDocumentByID(pfirstNote$) Else Set pviewNote=Nothing

End Sub

Synergetics India said...

Synergetics India is managing the campaign for Microsoft's Windows Mobile market place, Synergetics India also does technical readiness on azure best .net 4.0, SQL server 2008.

Synergetics India said...

Thanks For this post
It’s really useful to me.
ASP .Net Training | Microsoft Training India | SQL Server 2005 & 2008 Training India

Synergetics India said...

Thanks, I like this post
Windows Mobile Marketplace 6.5

Mitch said...

Well, I may be veeeeery late, but as there is still no solution and I am having the same problem, I would approach it using Readers/Authors fields, filled with roles. One specific role for each "database". Add the roles to the users and they can have the full Notes functionality, use the same views and everything... No more changes needed...

Aria Kerry said...
This comment has been removed by the author.
Anonymous said...

Found this post when struggling with the folder messagebox quirk. The solution I use when dealing with Notes quirks that cannot be trapped in an orderly fashion is ruling the 'non-errors' out in a SELECT...CASE statement based on the error line number and putting in the dreaded but functional 'resume next'.

Select Case Erl
Case 99, 100, 101 'Unable to find document window, actually a ghost error code, see http://www-01.ibm.com/support/docview.wss?uid=swg21091227
Resume Next
Case 89 'http://www-01.ibm.com/support/docview.wss?uid=swg21166365
Resume Next
Case Else
Msgbox {Error on line } & Erl & {: Error # } & Err & { > } & Error$
Resume ExitSub
End Select

marven said...

This is because they don't inherit the design anymore when becoming private. banner design . I have read all post and its very useful for all.

youlacka said...

That is really very good article.kızlarla chat,I am glad to know.mersin chat,Thanks for sharing !avrupa chat

saç ekimi said...

Heya i’m for the first time here. I found this board and I find It truly useful & it helped me out a lot. I hope to give something back and help others like you aided me.

marven said...

It is funny but my daughter is more inclined then my wife in using the computer, considering that my wife finished .logo design

Anonymous said...


marven said...

I am running Jobs in Pakistan blog and I would share this info there as it would be beneficial for my visitor.wireless internet .

marven said...

I love your information on this topic ... very interesting and I would like to put more on this article . evdo wireless broadband .

çiçek said...

good topic thanks admin