Lesson 2: Counting the documents in a view category
This is the second of three lessons designed to introduce you to using the LotusScript® language in Domino®. You should already have completed Lesson 1.
Lesson 2 helps you create a script that counts the number of documents in one category of the "By Category" view of the "Learning LotusScript®" database. The script runs from an agent.
Step A: Add documents to the test database
Add three documents to your test database so your agent script will have something to work with.
- In the Notes® client, open the "Learning LotusScript®" database that you created in Lesson 1. (Or in Domino® Designer, you can preview a view of the database.)
- Create and save three or more new "Main Topic" documents. Be sure to fill in the Subject and Category fields. Use names like "Subject 1" and "Category 1." Use the same category for several documents.
Step B: Create an agent
The script runs whenever an agent runs, so begin by creating the agent. In Domino® Designer:
- Select "Agents" in the Design pane, then click "New Agent." The Agent Properties box appears. The Programmer's pane appears next to it.
- Name the agent "Count documents."
- Select the "Shared" option.
- In the Runtime section click the "On event" trigger and select "Action menu selection" from the drop-down box.
- Select "All documents in database" for the target.
- Select LotusScript® from the Run menu in the Programmer's pane.
- Select Initialize from the list of programmable events on the Objects tab.
Step C: Access the Reference tab
The following steps do not create anything. They are just to familiarize you with the Domino® classes.
- In the Info List, click the Reference tab.
- Select "Domino®: Classes" and expand NotesDatabase.
- Under NotesDatabase, expand Methods. You looked at methods before, and now you're ready to use them in a script.
- Scroll until you find the GetView method. The type of value that a method returns is indicated after "As" at the end of the method. The GetView method returns a NotesView object.
- Under "Domino®: Classes," expand NotesView. This class represents a view of a database.
- Under NotesView, expand Methods and then scroll until you find the methods that start with CreateViewNav. These methods return a NotesViewNavigator object.
- Under NotesViewNavigator expand Methods and then scroll until you find the GetFirstDocument method. This method returns a NotesViewEntry object.
- Scroll until you find the GetNextDocument method. It, too, returns a NotesViewEntry object.
Step D: Enter the script
You're ready to enter the script. Edit the subroutine so that it looks exactly like this with one exception. Substitute the name of an actual category for "Category 1"if necessary.
Sub Initialize
Dim db As NotesDatabase
Dim view As NotesView
Dim nav As NotesViewNavigator
Dim entry As NotesViewEntry
Dim count As Integer
Set db = New NotesDatabase( "", "Learning LotusScript.nsf" )
Set view = db.GetView( "By Category" )
view.AutoUpdate = False
Set nav = view.CreateViewNavFromCategory( "Category 1" )
Set entry = nav.GetFirstDocument
count = 0
' begin counting documents
' stop when there are no more documents
Do Until entry Is Nothing
count = count + 1
Set entry = nav.GetNextDocument( entry )
Loop
Messagebox "Number of documents = " & count,, "Category 1"
End Sub
Step E: Compile and test the script
- Choose File - Save.
- If you get the message "Data not saved due to script error(s)," check the error at the end of the Programmer's pane, then double-check your typing to make sure that the script looks exactly like the one in Step D.
- Choose File - Close.
- Ensure that your agent is highlighted and choose Actions - Run. Domino® displays a dialog box
that tells you the number of documents in "Category 1" (or the specified
category).
If the number of documents is 0 or an unexpected number, ensure that CreateNavFromCategory in your script specifies the correct category name. Recompile and save if necessary. Also ensure that you have sample documents in the specified category.
Another common error is to not specify the name of the view correctly. If you do that, "view" is not associated with an actual NotesView object because none is set. When you try to use "view" as an object name, you will get the error, "Object variable not set." If you get this error, check the statements in your script that set object variables. Fix the script, recompile, and test it again.
Step F: Edit the script
You may not need to edit your script after saving it, but if you do, here's how.
- Open the "Learning LotusScript®" database if it does not appear in the Design pane.
- Select "Agents" in the Design pane.
- Open the "Count documents" agent.
- Select Initialize from the Objects tab.
Review: How did the script work?
The lines of script you entered mean:
- I want to access the "Learning LotusScript®.nsf" database on my local drive, and I want to use the name db to refer to this database.
- Next, I want to access the "By Category" view in the database, and I want to use the name view to refer to this view. Note that the script accesses the "By Category" view on disk -- therefore, it does not matter what view is open in the user interface when you run the agent. Setting AutoUpdate to False keeps the view static for your processing.
- Next I want to build a view navigator that contains all the entries categorized under "Category 1" and I want to use the name nav to refer to this navigator.
- Next, I want to access the first document entry in the view navigator, and I want to use the name entry to refer to it.
- Next, I want to assign a value of 0 to the integer called count. I want to count how many documents are in the view navigator by getting each document and incrementing count until every document has been counted.
- Last, I want to display the count in a dialog box on the screen.
Line 1: Begin a subroutine
Sub Initialize defines the beginning of the subroutine. Domino® creates this line for you.
Lines 2 to 6: Declare variables
Dim db As NotesDatabase declares an object called db. It is an instance of the NotesDatabase class.
Dim view As NotesView declares an object called view. It is an instance of the NotesView class.
Dim nav As NotesViewNavigator declares an object called nav. It is an instance of the NotesViewNavigator class.
Dim entry As NotesViewEntry declares an object called entry. It is an instance of the NotesViewEntry class.
Dim count As Integer declares a variable called count. It is an integer.
Lines 7 to 11: Set the values of the variables
Set db = New NotesDatabase( "", "Learning LotusScript®.nsf" ) sets the value of db so that it refers to the "Learning LotusScript®.nsf" database on the local computer.
Set view = db.GetView( "By Category" ) sets view equal to the value returned by GetView. GetView is a method defined in the NotesDatabase class that returns a NotesView object. The parameter,"By Category," indicates which view you want. Since you use db to call it, GetView returns an object representing a view in "Learning LotusScript®.nsf."
View.AutoUpdate = False turns off automatic updating of the view object when changes occur in the view. This improves performance and ensures that the view navigator does not encounter unexpected entries.
Set nav = view.CreateViewNavFromCategory( "Category 1" ) sets nav equal to the value returned by CreateViewNavFromCategory. CreateViewNavFromCategory is a method defined in the NotesView class that returns a NotesViewNavigator object. The parameter, which should be the name of a category in the database, says that you want the navigator to consist of all the entries categorized there.
Set entry = nav.GetFirstDocument sets entry equal to the value returned by GetFirstDocument. GetFirstDocument is a method defined in the NotesViewNavigator class that returns a NotesViewEntry object. It returns the first view entry that represents a document rather than a category.
count = 0 sets count equal to 0. You must use Set to set the value of an object, but you must not use Set to set the value of an integer or any other plain data type.
In Lesson 1, you learned about properties, which represent the attributes of an object. In this lesson, you're also using methods, which represent the behavior of an object. To use a method in a script, you need four things:
- The name of the object, such as db, view, or nav
- A dot, or period (.)
- The name of the method, such as GetView, CreateViewNavFromCategory, or GetFirstDocument
- Any parameters required by the method
Like a property, a method is only useful if you know which object it pertains to -- that's why you need an object to use it. For example, the GetView method is only useful if you know which database it pertains to, which is why you use the db object to access it. Similarly, the GetFirstDocument method is only useful if you know which view it pertains to, which is why you use the view object to access it.
Some methods are like functions and return values. Other methods are like subroutines and don't return values.
Lines 12 to 13: Insert comments
' begin counting documents
' stop when there are no more documents
These are in-line comments that explain what's happening in the script. LotusScript® ignores any line that begins with an apostrophe ( ' ) or the keyword REM.
Lines 14 to 17: Count the documents in the view
Do Until entry Is Nothing defines the beginning of a loop, and specifies what condition causes the loop to stop. The loop will execute zero, one, or multiple times, until the entry object is Nothing.
Loop defines the end of the loop. The lines between Do Until entry Is Nothing and Loop are called the body of the loop:
- count = count + 1 increments the current value of count by one. The script does this each time it gets a new document, so that it maintains a current count of documents in the view.
- Set entry = nav.GetNextDocument( entry ) assigns the next entry in the view that is a document to entry. If there are no more documents in the view, it assigns Nothing to entry.
Nothing is a LotusScript® keyword that means you have a null, or empty, object. For example, the entry object is Nothing when it's first declared, until you assign a value to it. The GetNextDocument method returns Nothing when you send it the last document in the view as a parameter, because there are no documents after the last one. In this script, this means stop counting.
If there are no documents at all in the "By Category" view, the loop body never runs. If there is one document in the view, the loop body runs once; if there are two documents, the loop body runs twice, and so on.
Line 18: Display the result in a dialog box
Messagebox "Number of documents = " & count,, "Category 1" displays the value of count in a dialog box on the screen.
Line 19: End the subroutine
End Sub defines the end of a subroutine.
Challenge: Counting the categories in a view
Using what you have learned, write a script that counts the categories in the "By Category" view of the "Learning LotusScript®" database. The script should create a view navigator that represents all the entries in the view. The script should count the first entry, which always represents a category in a categorized view, and then each next entry that represents a category, stopping when there are no more category entries to count. Use the Reference tab to find the methods or properties you need.
Solution: Counting the categories in a view
The methods you need are CreateViewNav in the NotesView class, and GetFirst and GetNextCategory, both in the NotesViewNavigator class. CreateViewNav, which has no parameters, creates a NotesViewNavigator object that represents the entire view. One correct solution is as follows:
Sub Initialize
Dim db As NotesDatabase
Dim view As NotesView
Dim nav As NotesViewNavigator
Dim entry As NotesViewEntry
Dim count As Integer
Set db = New NotesDatabase( "", "Learning LotusScript.nsf" )
Set view = db.GetView( "By Category" )
view.AutoUpdate = False
Set nav = view.CreateViewNav( )
Set entry = nav.GetFirst
count = 0
' begin counting categories
' stop when there are no more categories
Do Until entry Is Nothing
count = count + 1
Set entry = nav.GetNextCategory( entry )
Loop
Messagebox "Number of categories = " & count,, "By Category"
End Sub