Manage Learn to apply best practices and optimize your operations.

Hierarchical Web Report

Web Report Agent
This code generates a multi-column hyperlinked (for drill down) report on 3000 documents in five seconds, as opposed to several minutes (no one waited long enough to time it) using ODBC.

Missing are the script libraries for the CSOReport and DataLine classes. The DataLine class contains all the data for a single row of the table along with functions to manipulate that row, including summation and printing, It also contains link information for hierarchicial organization, ala Notes, used for table breaks. The CSOReport class contains and alphabetically sorted list DataLine objects, one for each of the highest-level breaks in the table, along with functions for manipulating them. Each lower-level break creates another set of DataLine objects under the current one, so the table generated by the code below looks like this:

CSOReport class instance
--DataLine for highest level break -- DataLine for second level break -- DataLine for third (and lowest) level break -- (add'l third level DataLine objects) -- DataLine for next second level break -- (Datalines for next third level) -- DataLine for next first level break (and so on)

Since a hierarchy is used, any number of table break levels may be incorporated with relative ease, once the CSOReport and DataLine classes are completed. TheCSOReport class handles the sorting so collation takes place in the proper sequence, which was the main reason ODBC was selected initially.
Sub Initialize
' What : WEBREPORT LotusScript Agent
' Who : Dave "Rags" Gilmore, Highland Technology Services, Inc
' When : December 16, 1999
' Why : Rework the WebReport Agent using a class structure to eliminate ODBC, which turns
' out to be far too slow to be usable.
' Notes :
' This uses a class-based approach to the problem. ODBC was originally used because it could
' retrieve data for summation without regard to any views, in particular. So it could find all the
' Reports that matched a CSO and derive totals from there, ultimately displaying this summary
' data in a table. This Agent does much the same thing, but it uses a heirarchical class structure
' to hold the info, whose data is populated by traversing the Notes document heirarchy. The
' class hierarchy is CSO -> Organization -> Site, reflected by the table generated.
' Modifications:
' 991219 by Rags - Stripped out the DataLine Class declaration into its own Script Library.
' 991220 by Rags - Added the Report Class use; now it builds the entire table using classes and
' only outputs it at the end. The original method didn't collate the data properly because it didn't
' sort it. Now it updates totals by the row break criteria, so puts it all in the right place.
' 991221 by Rags - Skip Reports without CAPS.
Dim RptByCSO As NotesView ' All Reports by CSO
Dim RptDoc As NotesDocument ' The Report we're currently summating
Dim RptData As New CSOReport ' Class containing the entire generated table
Dim CsoDL As Dataline ' Table row summaries for CSO level
Dim OrgDL As DataLine ' Table row summaries for ORG level
Dim SiteDL As DataLine ' Table row summaries for SITE level
Dim ThisCSO As String ' CSO to generate table for; " " for all CSOs (default)

Set s=New NotesSession ' Global
On Error Resume Next
Set RptDoc=s.DocumentContext
'---------- Generate an "ALL" report if not running from the web, or CSO value is
If(RptDoc Is Nothing Or Isempty(RptDoc)) Then
If(IsOnServer) Then
Print "Could not access document context for data retrieval!"
Exit Sub
Else ' We're running from the client; do a full report run
ThisCSO=" "
End If
If(Err<>0) Then
Print "Couldn't retrieve data from document context!
Exit Sub
End If
If(ThisCSO="") Then
Print "

I got nothing from the Web Form so I'm generating a Report for 'All'.

ThisCSO=" "
End If
End If ' RptDoc Is Nothing...
'---------- Initialize the Notes View & Document objects for document retrieval
Set RptByCSO=s.CurrentDatabase.GetView("(NdxReportsBy CSO)")
If(RptByCSO Is Nothing Or Isempty(RptByCSO)) Then
Print "Couldn't acquire view 'rptbycso' for data collection.
Exit Sub
End If
Set RptDoc=RptByCSO.GetFirstDocument
If(RptDoc Is Nothing Or Isempty(RptDoc)) Then
Print "The database appears to be empty.
Exit Sub
End If
'---------- Process everything in the View
While(Not(RptDoc Is Nothing Or Isempty(RptDoc)))
' Reports with LineMgr data should have CAP data populated
If(RptDoc.LineMgr(0)<>"" And (RptDoc.RespCSO(0)=ThisCSO Or ThisCSO=" ")) Then
If(NeedDL(CsoDL, RptDoc.RespCSO(0))) Then
' CSO Break: AddRpt searches for RptDoc and adds a new line if needed
Set CsoDL=RptData.AddRpt(RptDoc)
End If ' NeedDL(...)
If(NeedDL(OrgDL, RptDoc.RespORG(0))) Then
' ORG Break: New docs need new kids; FindKid() searches and spawns if req'd
If(CsoDL.IsNew) Then
Set OrgDL=CsoDL.NewKid(RptDoc.RespORG(0))
Set OrgDL=CsoDL.FindKid(RptDoc.RespORG(0))
End If
End If ' NeedDL(...)
If(NeedDL(SiteDL, RptDoc.FacReview(0))) Then
' Site Break: As ORG Break above
If(OrgDL.IsNew) Then
Set SiteDL=OrgDL.NewKid(RptDoc.FacReview(0))
Set SiteDL=OrgDL.FindKid(RptDoc.FacReview(0))
End If
End If ' NeedDL(...)
' Roll-up the data for this Site, trickling up to the ancestor totals.
Collate SiteDL, RptDoc
If(CsoDL.NoData) Then
RptData.DelRpt Nothing
End If
End If ' RptDoc.LineMgr(0)<>""
Set RptDoc=RptByCSO.GetNextDocument(RptDoc)
'---------- Dump all accumulated data as an HTML table.
' Update the EditBar buttons
Print | |
End Sub

Function Collate(node As DataLine, doc As NotesDocument)
' What : COLLATE LotusScript function
' Who : Dave "Rags" Gilmore, Highland Technology Services, Inc
' When : December 16, 1999
' Why : Add all data for a Report doc to the collation. This exists mainly to
' allow the same code work on all levels of DataLine class instances.
' Thing is, it only needs to work on Sites. (smirk)
If(doc Is Nothing Or Isempty(doc)) Then
node.LogErr DL_IVL_DOC, "No document specified for collation"
If(Not node.AddRpt(doc) Or node.IsErr) Then
Print "<h2>Report "+doc.RptTitle(0)+" progress log<h2>"
Print "If you see this, an error has occurred during the Report generation process."
Print "Please hit the [BACK] button on your browser and try again. If the problem "
Print "persists, inform the CATS WebMaster.

Print "

End If ' Not node.AddRpt()...
End If ' doc is Nothing...
End Function

Function NeedDL(node As DataLine, Criteria As String) As Integer
' What : NEEDDL LotusScript function
' Who : Dave "Rags" Gilmore, Highland Technology Services, Inc
' When : December 20, 1999
' Why : Check if a DataLine instance needs to be created.
If(node Is Nothing Or Isempty(node)) Then
If(node.DescText<>Criteria) Then NeedDL=True
End If ' node is Nothing...
End Function

This was last published in November 2000

Dig Deeper on Lotus Notes Domino Administration Tools

Start the conversation

Send me notifications when other members comment.

By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Please create a username to comment.




  • iSeries tutorials's tutorials provide in-depth information on the iSeries. Our iSeries tutorials address areas you need to know about...

  • V6R1 upgrade planning checklist

    When upgrading to V6R1, make sure your software will be supported, your programs will function and the correct PTFs have been ...

  • Connecting multiple iSeries systems through DDM

    Working with databases over multiple iSeries systems can be simple when remotely connecting logical partitions with distributed ...