Hey Jack,
Great work!
So far have been looking at the search functionality and have found a few issues:- if there is a space in the db path, the space is being converted to "%2520" (% is being url encoded again before calling the agent) so the "getParameter" function can not decode it properly. This means the dbSearch object cannot be set. As a work around I am manually replacing the string sequence before the Evaluate statement.
- If a column in the view being searched has "Show multiple values as separate entries" checked, the agent fails because the column value is returned as an array. I have done a Join on the array.
- When generating the search results any hidden columns need to be excluded and categorised column values set to blank(like notes does). The entrydata columnnumber is adjusted accordingly. When trying to troubleshoot this I was tripped up by the view sample "Sc1":
- When testing my fixes the column values where all moved left by one and missing the value for the "subject" column
- when looking at the output of the values, the subject was indeed missing from the array of columnValue from the view entry.
- Rembered that "view column constants" are not output to the columnvalues array and realized that the Hidden Column has a constant of "This should not display". This did not explain why the "subject" value was not available and the so called constant was.
- After much stuffing around realised that Domino was excluding the wrong column so(not sure if it is a bug on 6.5.4), to validate my assumption I changed the hidden column to lookup a field value and all worked perfectly--> Upshot is that if a view contains a column set to a fixed value it will mess with the column alignment(that is with my fixes applied).
- The IsHidden property of the NotesViewColumn object does not seem to be correct if a column is hidden by a "Hide When" formula (ie returns false when formula evaluates to true). This also has the effect of throwing out the column order of the returned results. Not sure if this is an issue on later versions of Domino and I haven't found away to overcome it yet.
I have not tested this with "restrict to single Category". I'm guessing that the existing code may not be needed to handle that with these changes in place.
Updated code for agent "extnd/3x/SearchView" initialize event:
Code:
Sub Initialize
%REM
This agent can be called from the web to search any view and return results in the
same format as the ?ReadViewEntries command. This was created for use with the
NotesView2 class v1.3 and above.
%END REM
On Error Goto ErrorHandler
Dim session As New NotesSession
Dim dbSearch As NotesDatabase
Dim colEntries As NotesViewEntryCollection
Dim vwSearch As NotesView
Dim entryResult As NotesViewEntry
Dim docCurrent As NotesDocument
Dim docResult As NotesDocument
Dim strQuery As String
Dim strDb As String
Dim strView As String
' variables for single category search
Dim strRTC As String
Dim intRTCAdjustment As Integer
Dim columnRTC As NotesViewColumn
Dim strRTCFormula As String
Dim intMax As Integer
Dim lngCount As Long, i As Long
Dim lngStart As Long, lngEnd As Long
Dim strParameters As String
Dim lngResults As Long
Dim tmpString As String
Dim x As Integer
Dim intExcludedColCount
'start the xml document
Print "Content-Type:text/xml;"
Print "<?xml version=""1.0"" encoding=""iso-8859-1""?>"
'first we get the search parameters out of the querystring
'db, vw, query, searchmax, count, and start
Set docCurrent = session.DocumentContext
strParameters = docCurrent.GetItemValue("Query_String")(0)
strDb = GetParameter("db",strParameters)
strDb = Replace(Strright(strDb,"/"),"/","\")
strView = GetParameter("vw",strParameters)
strQuery = GetParameter("query",strParameters)
intMax = 0
If Isnumeric(GetParameter("searchmax",strParameters)) Then intMax = Cint(GetParameter("searchmax",strParameters))
lngCount = 100
If Isnumeric(GetParameter("count",strParameters)) Then lngCount = Clng(GetParameter("count",strParameters))
lngStart = 1
If Isnumeric(GetParameter("start",strParameters)) Then lngStart = Clng(GetParameter("start",strParameters))
'now we get the view to search
Set dbSearch = session.GetDatabase("",strDb,False)
Set vwSearch = dbSearch.GetView(strView)
' check for RestrictToCategory because if one exists, we have to adjust the columnnumber attribute
' and we will need to tweak the strQuery to also search on the category
strRTC = GetParameter("RestrictToCategory",strParameters)
If (strRTC <> "") Then
intRTCAdjustment = 1
Set columnRTC = vwSearch.Columns(0) 'in a RestrictToCategory view, the first column, column 0, should be the category column
If columnRTC.IsFormula Then
strRTCFormula = columnRTC.Formula
Else
strRTCFormula = "FIELD " + columnRTC.ItemName
End If
strQuery = |(| + strRTCFormula + |="| + strRTC + |") AND (| + strQuery + |)|
Else
intRTCAdjustment = 0
End If
'msgbox strQuery
'now we run the search
lngResults = vwSearch.FTSearch(strQuery,intMax)
'now we spit out the results
Print "<viewentries toplevelentries=""" & Cstr(lngResults) & """>"
Set colEntries = vwSearch.AllEntries
'set the starting point for the loop
If lngStart > lngResults Then lngStart = lngResults
'set the ending point for the loop
lngEnd = lngStart + lngCount - 1
If lngEnd > lngResults Then lngEnd = lngResults
'now loop through the appropriate subset of results and print out a viewentry tag for each one
i = lngStart
While i <= lngEnd
Set entryResult = colEntries.GetNthEntry(i)
If Not entryResult Is Nothing Then
intExcludedColCount = intRTCAdjustment
Set docResult = entryResult.Document
Print "<viewentry position=""" & Cstr(i) & """ unid=""" & Cstr(docResult.universalID) & """ noteid=""" & Cstr(docResult.NoteID) & """ siblings=""" & Cstr(entryResult.SiblingCount) & """>"
x = 0
Forall value In entryResult.ColumnValues
If vwSearch.Columns(x).isCategory Then
value = ""
Elseif Isarray(value) Then
value = Join(FullTrim(value), ",")
End If
If vwSearch.Columns(x).isHidden = False Then
tmpString = ""
tmpString = tmpString + "<entrydata columnnumber=""" & Cstr(x - intExcludedColCount) & """ name=""" & vwSearch.Columns(x).itemName & """>"
tmpString = tmpString + "<text>" & XMLEscape(Cstr(value)) & "</text>"
tmpString = tmpString + "</entrydata>"
Print tmpString
Else
intExcludedColCount = intExcludedColCount + 1
End If
x = x + 1
End Forall
Print "</viewentry>"
End If
i = i + 1
Wend
AtEnd:
Print "</viewentries>"
Exit Sub
ErrorHandler:
Print "<error>" & "Error in SearchView: " & Error & "---at " & Erl & "</error>"
Resume AtEnd
End Sub
Thanks again Jack and Rich for all your efforts!
Regards
Sean