Hi Blake, the reason the POFU view doesn't highlight in the embedded outline, I believe, is because the outline points to the "model" for the POFU view, not the personal version created in either the person's desktop or the Db.
It looks like you need the POFU view link to be highlighted when a person 1st opens the Db. In that case, you can remedy the highlighting problem with step 1 but I'd also recommend you do step 2 too:
1. Create 2 outlines -- I am not 100% sure you will need the 2 outlines, but if the outline entry for your POFU view is computed then you will. But the trick to get the highlighting to work may be the "Other Folders" & "Other Private Folders" section (in your case "Views") -- see the bottom graphic.
One outline will have the POFU entry computed, and the other will not. The [OpenView] command in the computed entry will create the POFU folder/view if it doesn't exist:
(aargh, that sucks! only I can see the graphic...) so let me include all the specifics ....
For the Outline with the Computed Entry, the formula for the entry is:
folderName := "Records - by Company";
@SetTargetFrame("Content");
@Command([OpenFrameset];"Frameset-SearchResults");
@SetTargetFrame("FolderView");
@Command([OpenView];folderName) <<-- this creates the POFU folder/view if it doesn't exist
Then the "Other Folders" section has hide-when = @False
REM { Trick/Kludge: This entry needs to be present but with an empty label & cannot be hidden, };
REM { so that the Private folders created from the Shared POFU ones can retain outline focus & display properly. };
REM { You DO need to have an outline entry for each Private folder beneath this outline entry, };
REM { and they should always be hidden & then also put them where you want them [see Reports] };
REM { CAVEAT: The name that displays in the outline for these entries is the actual folder name, not the outline entry label. };
@False
& the Records - by Company outline entry is just Named Element / View / Records - by Company but HIDE ALWAYS
Then the "Other Private Folders" section has hide-when = @False
REM { Trick/Kludge: This entry needs to be present but with an empty label & cannot be hidden, };
REM { so that the Private folders created from the Shared POFU ones can retain outline focus & display properly. };
REM { You DO need to have an outline entry for each Private folder beneath this outline entry, };
REM { and they should always be hidden & then also put them where you want them [see Reports] };
REM { CAVEAT: The name that displays in the outline for these entries is the actual folder name, not the outline entry label. };
@False
& the Records - by Company outline entry is just Named Element / View / Records - by Company but HIDE ALWAYS
For the Outline with the Named Element entry:
It's just a regular Named Element / View / Records - by Company
Then the "Other Folders" section has hide-when = @True
REM { Trick/Kludge: This entry needs to be present but with an empty label & MUST be hidden, };
REM { so that the Private folders created from the Shared POFU ones can retain outline focus & display properly. };
REM { You DO need to have an outline entry for each Shared POFU/Private folder beneath this outline entry, };
REM { and they should always be hidden & then also put them where you want them [see Reports] };
REM { CAVEAT: The name that displays in the outline for these entries is the actual folder name, not the outline entry label. };
@True
& the Records - by Company outline entry is just Named Element / View / Records - by Company but HIDE ALWAYS
Then the "Other Private Folders" section has hide-when = @False
REM { Trick/Kludge: This entry needs to be present but with an empty label & cannot be hidden, };
REM { so that the Private folders created from the Shared POFU ones can retain outline focus & display properly. };
REM { You DO need to have an outline entry for each Private folder beneath this outline entry, };
REM { and they should always be hidden & then also put them where you want them [see Reports] };
REM { CAVEAT: The name that displays in the outline for these entries is the actual folder name, not the outline entry label. };
@False
& the Records - by Company outline entry is just Named Element / View / Records - by Company but HIDE ALWAYS
Then in the Page holding your embedded outline, you can use formula to determine which outline to load. I had to keep track of the last view opened in an environment variable to get this to work:
REM { Load up the correct outline if the last-used view was actually a folder, otherwise, open up the default outline };
REM { This is needed because the outline entries that link to folders must open up a different frameset with a split frame
than normal views which open up in a 1 frame frameset, and as a result each outline entry for a folder link is a Computed Action
not just a standard Named Element link. Doing things this way gets around a problem where Notes can't recognize
a Computed Action link as the one that should be highlighted when the Db is first opened (Db Launch is set to
"Restore as last used by user"). Having separate Outlines for each folder that has just a Named Element / Folder
as the outline entry will cause the appropriate folder link to be highlighted if that was the last one used by the user. };
viewOrFolder := @Environment("YOUR-DB-ViewOrFolder");
outlineName := @If( @Begins(viewOrFolder;"Records - "); "Outline-Folder: " + viewOrFolder; "Outline-Main" );
@If( @IsMember("[DBManager]";@UserRoles); @StatusBar("opening " + outlineName); "" );
outlineName
2. Ensure stale POFU views/folders aren't being used
I'd suggest you store all the users' POFU views on the server if that's not too many. That way you can have some code that runs once when a person opens the Db to compare their POFU view to the "model" POFU view & delete the user's POFU if it is stale. This way you don't end up with obsolete versions of POFU views being used out in the wild & having no (easy) way of updating them. For instance, I put this agent in the QueryOpen PostOpen of a BannerPage that only gets loaded once per session -- this code was modified slightly from something I found in the Ytria site's blog [ http://techlab.ytria.com/2381/tutorials/reveal-private-views-folders-agents-lotus-notes-applications/ ]:
REM { This agent only needs to run once at the beginning of each Db session } --> I do this at beginning of session, others say do it when user closes Db session (your pick);
@Command([ToolsRunMacro];"(Delete My Stale Private Views)")
Sub Initialize
On Error GoTo HANDLE_ERROR
Dim s As New NotesSession
Dim ws As New NotesUIWorkspace
Dim db As NotesDatabase
Dim OKtoRemove As Boolean
Dim forceDelete As Boolean
Set db = s.CurrentDatabase
' - This will remove the current user's private folders if they are stale so they can be refreshed/rebuilt using the shared (model) folder
' - If there are entries in a stale folder, the folder will be rebuilt from the model folder, then the entries restored to the rebuilt folder
' - If there are no entries in the stale folder, the folder will just be deleted & will only be rebuilt as needed when search results are
' placed in it
' - This has to be run by each user due to the $Readers fields on the private folders
' - In the subroutine, [DBManager] will be able to override the deletion
OKtoRemove = True
' - You can force the private views/folders to be re-built even if they aren't stale but we don't want that in this case
forceDelete = False
Call RemoveOldPrivateViews(db,OKtoRemove,forceDelete)
END_ROUTINE:
Exit Sub
HANDLE_ERROR:
Error Err, Error$ & Chr$(10) & " in subroutine " & GetThreadInfo(1) & " on line " & CStr(Erl)
End Sub
Sub RemoveOldPrivateViews( pdb As NotesDatabase, OKtoRemove As Boolean, forceDelete As Boolean )
%REM
SUBROUTINE: RemoveOldPrivateViews
PURPOSE: This code is a modified version of that found on the Ytria web site that will delete any private views stored in
the database (Shared-Private-on-1st-Use) and remove them. It is used to refresh the design of these POFU views
when the template/model version of the view changes. In order for private views to be stored in the Db on the server
the user must have the ACL privilege = "Create personal folders/views" selected.
It allows users with [DBManager] role to override the stale private view deletion for testing or trouble-shooting purposes.
This routine is triggered from the PostOpen event on the Main Menu page, and optionally from view action button on views that
only [DBManager] will see in the outline.
With modification, this code could also be used to remove any personal views or folders that users create on their own
that are stored in the Db on the server (ACL privilege = "Create personal folders/views").
PARAMETERS:
- pdb : current database
- OKtoRemove : Flag to switch deletion on/off of stale views. Default = TRUE.
- forceDelete : Flag to force views to be deleted even if they aren't stale. Default = FALSE.
WRITTEN BY: 2013.08.01
MODIFICATIONS:
2013.08.01 (JLK) : *new* - Modified from original code posted by Ytria on their web site
2014.03.26 (JLK) : copied & modified for use in this Db to delete POFU-Folders from the MasterDocLibOutline
page PostOpen event
%END REM
Dim s As New NotesSession
Dim ws As New NotesUIWorkspace
Dim uiDb As NotesUIDatabase
Dim nvPr As NotesView
Dim nvFi As NotesView
Dim nvecPr As NotesViewEntryCollection ' the Private stored-in-Db views
Dim nvePr As NotesViewEntry
Dim nvecFi As NotesViewEntryCollection ' the Shared POFU model views
Dim nveFi As NotesViewEntry
Dim lView List As String
Dim nvTgt As NotesView
Dim nfPr As NotesView
Dim doc As NotesDocument
Dim vec As NotesViewEntryCollection ' the entries in a Private stored-in-Db view
Dim ve As NotesViewEntry
Dim dc As NotesDocumentCollection ' the documents for the vec above
Dim curUIView As NotesUIView
Dim curViewName As String
Dim deletedViewNames As String
Dim userRoles As Variant
Dim isDBManager As Boolean
Dim oldViewCount As Integer
' - Keep track of the current view & environment variables
Set uiDb = ws.CurrentDatabase
Set curUIView = ws.CurrentView
If Not( curUIView Is Nothing ) Then
curViewName = curUIView.ViewName
End If
' - QueryAccessRoles will return all roles assigned if user in multiple groups, or all roles assigned
' to individual entry if user listed explicitly (group roles assigned ignored in that case)
userRoles = pdb.QueryAccessRoles(s.Effectiveusername)
ForAll aRole In userRoles
If aRole = "[DBManager]" Then
isDBManager = True
Exit ForAll
End If
End ForAll
Print "Getting the list of Views/Folders"
Set nvPr = pdb.GetView("AllMyPrivateViews") ' the private views stored on the server
Call nvPr.Refresh()
Set nvFi = pdb.GetView("AllPrivateFirstUseViews") ' the shared (model) views that are POFU
Call nvFi.Refresh()
' - Loop through all the private views, see if there is a matching shared view with the same alias name
' - If match found, check if the shared view has a newer Last-Modified date than the private view
' --> YES : save the NoteID of the private view for deletion
' --> NO : private view is current, no need to delete it
Set nvecPr = nvPr.AllEntries
Set nvePr = nvecPr.GetFirstEntry()
Do While Not nvePr Is Nothing
Set nveFi = nvFi.GetEntryByKey( nvePr.ColumnValues(0), True )
If Not nveFi Is Nothing Then
If nveFi.ColumnValues(2) > nvePr.ColumnValues(4) Then
Print "Update needed for View/Folder : "+nvePr.ColumnValues(1)+" ["+nvePr.NoteID+" / " +nvePr.Universalid+"]"
' lView( nvePr.NoteID ) = nvePr.ColumnValues(0) ' alias name
lView( nvePr.NoteID ) = nvePr.ColumnValues(1) ' regular view name
deletedViewNames = deletedViewNames + Chr$(13) + nvePr.ColumnValues(1)
oldViewCount = oldViewCount + 1
ElseIf forceDelete Then
Print "View/Folder : "+nvePr.ColumnValues(1) +" is up-to-date ["+nvePr.NoteID+" / " +nvePr.Universalid+"] but force delete is ON"
' lView( nvePr.NoteID ) = nvePr.ColumnValues(0)
lView( nvePr.NoteID ) = nvePr.ColumnValues(1)
oldViewCount = oldViewCount + 1
Else
Print "View/Folder : "+nvePr.ColumnValues(1) +" is up-to-date ["+nvePr.NoteID+" / " +nvePr.Universalid+"]"
End If
End If
Set nvePr = nvecPr.GetNextEntry( nvePr )
Loop
Print "Getting the list of Views/Folders - Done"
' - If there are stale private views & current user is DBManager, prompt to override deletion
If isDBManager And oldViewCount > 0 Then
OKtoRemove = ws.Prompt(PROMPT_YESNO,"Delete stale private views/folders?", + _
"Prompt for DBManager Only --" + Chr$(13) + Chr$(13) + _
"# of Out-of-date Private Views/Folders found = " + CStr(oldViewCount) + Chr$(13) + _
"Delete the Private ones modelled on Shared-Personal-on-First-Use views/folders to refresh their design?" + Chr$(13) + Chr$(13) + _
"( *NOTE* This will only delete YOUR private views/folders )")
End If
If OKtoRemove Then
ForAll theView In lView
Set nvTgt = Nothing
On Error Resume Next ' this will get around the "Index is not to be generated on server" error that will likely happen with GetView
Set nvTgt = pdb.GetView( theView ) ' this IS getting the PRIVATE folder
On Error GoTo 0 ' I think this will force the routine to continue on with removing the private view (bypass all errors)
' - Before deleting the private view/folder, get a count of all entries in it -- was never able to rebuild & re-populate
' the private folder successfully so this will have to do
Set vec = nvTgt.AllEntries ' this IS getting the entries in the PRIVATE folder
Print "Removing View/Folder : "+nvTgt.Name+" ["+nvTgt.UniversalID+"] -- # entries = " + CStr(vec.Count)
Call nvTgt.Remove()
End ForAll
If oldViewCount > 0 Then
MessageBox "The design of the following report folders has been updated:" + Chr$(13) + deletedViewNames + Chr$(13) + Chr$(13) +_
"You will need to re-run your search using the [Run Again] button " + Chr$(13) + _
"on the Query to refresh the report contents." + Chr$(13) + Chr$(13) +_
"*** Please CLOSE & RE-OPEN the database to finalize this update ***", 0+64+0+0, "Report refreshed ..."
' - To ensure Db doesn't try to open to one of the now-deleted private folders, delete the last-used environment variables
Call s.SetEnvironmentVar("YOUR-DB-Frameset","")
Call s.SetEnvironmentVar("YOUR-DB-ViewOrFolder","")
End If
End If ' ... If OKtoRemove Then
Erase lView
Print "Getting the list of Views/Folders - Done"
End Sub
The 2 views you'll need referenced above can be found in the original NSF here http://techlab.ytria.com/243/lotus-notes-code/case-private-views/
Hope this helps you or someone else confronted with this.
Judy