I have a LotusScript agent that accesses several databases and loops through each view, using the .views property of the database. Sometimes the line “Forall v in db.Views” raises a Type Mismatch error. Through debugging code I’ve determined that the DB is, in fact, Open, and by setting a variant from db.Views that it is not an array – even though the DB does have several views. Is this a known issue? Am I missing something? Is there any way around it?
Subject: If Not views Is Nothing
views = db.ViewsIf Not views Is Nothing Then
Forall v In views
If v.IsDefaultView Then
Set view = v
Exit Forall
End If
End Forall
End If
or it might be
views = db.Views
If Not IsEmpty(views) Then
Forall v In views
If v.IsDefaultView Then
Set view = v
Exit Forall
End If
End Forall
End If
Subject: Been there. Done that. Help?
That keeps the agent from failing, but it doesn’t tell me why SOMETIMES db.views is empty even when the db DOES have views.
I use GetDbDirectory for a given server then loop through all its DBs (using 1246 for the 1st call). I make sure the db is open before calling a routine that uses db.views to loop through the views. It consistently fails (db.views is empty) on some dbs that I know have views, and the views are available to all readers and above.
If it was a db security issue then I shouldn’t be able to open the db at all.
Subject: private views?
it won’t get private views or private on first use views so perhaps these are the views you are seeing in the UI but you cannot get to them via the Views property. You could try another way. Use NotesNoteCollection then narrow the collection down to just the view design elements with SelectViews to get just the view design notes then you can loop through those and treat them as documents to get at the properties of each one.
Just loop through the collection using GetNextNoteID then use the noteid with GetDocumentByID to set it as a notesdocument so you can get at the view items. Below is a code snippet I created to sign design elements that have been changed. Maybe it will help get you on the right track. Good luck.
Function Views(nc As NotesNoteCollection)
typ = "View"
Set nc = ntf.CreateNoteCollection(False)
nc.SelectViews = True
Call nc.BuildCollection
If nc.Count > 0 Then
Print "Checking " & Cstr(nc.Count) & " " & typ & "(s) in " & ntf.Title
Call Record(nc)
End If
End Function
Function Record(nc As NotesNoteCollection)
Dim ns As New NotesSession
Dim itm As NotesItem
nid = nc.GetFirstNoteId
For i = 1 To nc.Count
'get the next note ID before doing anything
nextid = nc.GetNextNoteId(nid)
Set doc = ntf.GetDocumentByID(nid)
If doc.HasItem("$TITLE") Then
Set item = doc.GetFirstItem("$TITLE")
ename$ = item.Text
Else
ename$ = "Unknown element name"
End If
' If this is a private design element then skip it
' May add new feature here to create a collection of private design elements and delete them from the template
' Caveat: it appears we can see private agents but not private views
If doc.HasItem("$Flags") Then
Set itm = doc.GetFirstItem("$Flags")
If Instr(itm.Text, "V") > 0 Then
Print "skipping private " & typ & ": " & item.Text
Goto nxt
End If
End If
' sometimes a user may copy/paste a design element, this does not update the signature unless the element is opened and saved
' if the signature is OK we check the last author as well and we will resave the design element if there is no match to the signer
lastAuthor$ = doc.Signer
If lastAuthor$ = ns.UserName Then
' we start with -1 because the array starts at 0
authcount% = -1
Forall n In doc.Authors
authcount% = authcount% + 1
End Forall
If authcount% > -1 Then
lastAuthor$ = doc.Authors(authcount%)
If lastAuthor$ = ns.UserName Then
Goto nxt
End If
End If
End If
Set ldoc = db.CreateDocument
ldoc.Form = "Log"
ldoc.ElementType = typ
ldoc.Title = pdoc.Title(0)
ldoc.Server = pdoc.Server(0)
ldoc.FilePath = pdoc.FilePath(0)
ldoc.ReplicaID = pdoc.ReplicaID(0)
ldoc.LastModifiedDate = doc.LastModified
If doc.Signer = "" Then
ldoc.LastModifiedBy = "No signature"
Else
ldoc.LastModifiedBy = lastAuthor$
End If
ldoc.ElementName = ename$
Call doc.Sign
Call doc.Save(True, False)
ldoc.UpdatedDate = doc.LastModified
ldoc.UpdatedBy = doc.Signer
Call ldoc.ComputeWithForm(False, False)
Call ldoc.MakeResponse(pdoc)
Call ldoc.Save(True, False)
count = count + 1
nxt:
nid = nextid
Next
End Function
Subject: Found it - No Access
Paul, Thanks for your help!I was running the agent using LEI on our dev server, so it was running under the dev server’s notes id. The agent could get a handle to DBs on another server, but for some DBs the dev server id had no access – and the views were accessible to “All readers and above”. The views are there, but the server id couldn’t see them, so db.Views was empty. I’ll have to find a better way to test the agent…
Thanks again!