IBM Support

LotusScript Self-Help Training Module 2: 'How to write a simple back-end LotusScript agent'

Education


Abstract

This technote is the second of two modules that train you on how to use LotusScript within a custom built application. Module 1 covers Domino Designer, LotusScript debugger and the Designer Help file. Module 2 covers the creation of back-end LotusScript agents.

Content



Introduction
This self-help training is designed to introduce you to the LotusScript programming language, to help you learn the basic LotusScript skills required to write a simple back-end LotusScript agent, and to show you how to use Domino Designer Help to actually learn as you write your code.

When you have completed all parts of this course module, you will have created a LotusScript agent that will process all the documents in a specified view in a Notes Database. It will check each document, and if a certain field has a specific value, it will change the value of another field. This demonstrates a very common usage of a LotusScript agent. Many production agents have this basic functionality at their core, with additional functionality added to it.

This same course is also available in video format. There is one video that includes parts 1, 2, and 3 of this course, corresponding to parts 1, 2, and 3 of this document. There are separate videos for each of the other parts 4 through 17. For the most part, the content of the videos is the same as the content of this document, but there is some additional content in the videos, especially for parts 16 and 17.


Part 1: Prerequisites, Learning Objectives, and Course Format

Video: Part 1, 2 & 3 (8 min 15 sec)

Prerequisites for this course:

- You should have a good working knowledge of the parts of a Notes database, such as forms, views, documents, fields, etc.

- You should already know how to use the Domino Designer client to create an agent. This topic is explained in the LotusScript Self-Help Training Module 1 - 'Using LotusScript within a custom application'


Learning objectives for this course module:

- Learn to declare and use variables
- Be introduced to the LotusScript back-end classes for Notes and Domino
- Use flow control to loop through documents
- Use "If" statements to control execution of parts of your code depending on conditions
- Read and set field values
- Save changes to documents
- Use the debugger to test and troubleshoot your code

Format of this course module:

This course will take you step by step through the process of creating a LotusScript agent, starting with a general idea of what you need an agent to do, and going through all the steps to create and test that agent. It will introduce some concepts that are essential to programming in LotusScript, and describe some of the thought processes that might be used to create an agent to accomplish the job at hand.

This course is not a comprehensive training in LotusScript, but rather an introduction by example to LotusScript programming. It is intended to get you started so you can learn as you go. You can teach yourself LotusScript using this course and relying on the Domino Designer Help database as a reference. However, you may find that a comprehensive LotusScript training course would be helpful to more quickly learn LotusScript skills. For information on course offerings, go to this URL:

http://www.ibm.com/software/sw-lotus/services/cweeducation.nsf/wdocs/notesdomino

The "course description" links on that page are a good way to get a list of all the courses available, and find the ones for LotusScript.
Back to top

Part 2: Verifying that Designer is installed & Introduction to Designer Help

Video: Part 1, 2 & 3 (8 min 15 sec)

In order to create LotusScript agents, you must have the Domino Designer client installed. To verify that you have the Domino Designer client, start your Notes client and look for the Designer icon in the Bookmarks bar at the left of the Notes client window. It looks like the yellow Notes icon with a green triangle on top of it.




If it is present, click on it to confirm that it launches the Designer client, which will look like this:





If the Designer client is not installed on your computer, you will need to install it before you can proceed with this course or create a LotusScript agent.

Throughout this course there will be references to topics in the Lotus Domino Designer 7 Help database where you can find more information. If you are using Notes 6, you will use the Lotus Domino Designer 6 Help database. We will just refer to it as "Designer Help" from now on. To find the Designer Help, start your Notes client and use the menu option File - Open - Database. Choose "Local" for the server, and in the list of databases, scroll down to the list of folders and double-click on the folder named "Help". In the list of databases in that folder you should see a database named Lotus Domino Designer 7 Help (or Lotus Domino Designer 6 Help). Click on the database title to select it, and then click on the "Open" button. By default, the Designer Help file will launch in a separate window from your Notes client.

There are different ways to find information in the Domino Designer Help. You can use the Index view for an alphabetical listing of all topics, or you can use the Search view to use full text searching to find documents that contain the word or words to want to search for. The references in this course will guide you to topics for further reading in the Contents view, using the format of: LotusScript Language / Script and Statement Construction Rules / Keywords to find the document on the "Keywords" topic, for example. This means you open the Contents view, and in the left pane click on the triangle pointer (called a twistie) next to "LotusScript Language" to expand that section in the Contents, and then under that section expand the "Script and Statement Construction Rules", and then click on the word "Keywords" to open that document in the right pane of the Designer Help window.






Get familiar with Designer Help, it is a great reference resource, and you will be using it a lot.

Back to top

Part 3: Sample agent

Video: Part 1, 2 & 3 (8 min 15 sec)

For this module, imagine that you work for a company that provides services to industries across the US. Your customers are divided into four regions with home offices in each region. All customers call one common 800 number to place an order for services, and the person taking the call creates a document in a Notes database to route the order to the correct regional office by filling out the region and city fields in the form. All of these documents appear in a view named "Service Requests".

ServReqs.zip

Detach the database file, named "ServReqs.nsf" and place it in your c:\lotus\notes\data directory, or the correct data directory for your installation of the Notes client. The database title is “Service Requests”. Open the database, and you will see that it contains a view named "Services and Locations", and that there are several documents in it. Open a couple of the documents to see what they look like. The form used for the documents is named "Service Location", and contains fields named "Service", "Region", and "Location". This is all very simplified, but it will serve our purposes for the sake of this example.

You have been notified that your two offices for the South region, in Atlanta and El Paso, are combining and moving to Houston. You have many service records that need to be updated to the new location. You have been assigned the task of writing a LotusScript agent that will reset all the city fields in the documents for the South region to the new office location. Your agent will need to check every document in the database view named Service Requests, and if it is for the South region set the city field to Houston instead of Atlanta or El Paso. You have never written a LotusScript agent before, but you can visualize that your agent will need to be written to process each document in the view, determine if the Region field has the value "South" in it, and if so reset the value in the city field. Documents that do not have "South" in the region field should not be changed by the agent.

Back to top

Part 4: Overview of LotusScript

Video: Part 4 (6 min 43 sec)

LotusScript is a BASIC scripted programming language. What this means is that it is based on the BASIC language that has been around for many years, the same programming language that has evolved into Visual Basic that is used today. LotusScript uses most of the same syntax rules as Visual Basic. Compared to many programming languages, it is easy to learn, and easy to code.

LotusScript is cross platform. LotusScript runs within Notes and Domino, so it can be run on any platform that the Domino server or the Notes client can run on, including Windows, AIX, OS400, Linux, etc. With very few exceptions, the same LotusScript code can be run in a Notes database on any of these platforms. The only exception that is commonly encountered is when LotusScript code opens a file out on the operating system's hard drive, such as to read a text file for data input. Some platforms use forward slashes and others use backslashes to separate directories, so the path to such a file in the LotusScript code needs to use the appropriate pathing syntax for the operating system the code is running on. But even in this case, LotusScript can be coded to detect what platform it is running on and the code can be written to use that information to work on both types of systems.

LotusScript is object-oriented. This is a general programming concept, but to explain it in the context of LotusScript in Lotus Notes, it means that the various parts of the Notes database and Notes/Domino environment are represented in LotusScript by what we call "objects". For example, a Notes database is an object, and a view within that database is an object, and a document is an object. The fields in a document are objects too. As logic would suggest, a document object would be contained within a database object, as would a view object. The organization of the objects in the LotusScript object oriented programming language follow the logical organization of the Notes database structure. That is the whole idea behind object-oriented programming -- you use objects in your program to represent real-life things that you want your program to process. It makes programming easier because it more closely matches the way humans think, and the common LotusScript programming "objects", like Notes databases, documents, etc. can be used like building blocks to build complicated LotusScript programs.

For the example agent, we will need to work with a database, and within that database a view and some documents, and within the documents we will need to work with fields.

To take a look at the types of Domino Object variables that are available in the LotusScript programming language, go to the Designer Help LotusScript/COM/OLE Classes / LotusScript Classes A-Z. You can expand the section LotusScript Classes A - Z to see the list of all the LotusScript classes for working with Notes and Domino.

Take a minute to read through the list to get an idea of what is available, and how it relates to the structure of the Notes Domino database. Each class is named in such a way that you immediately have a pretty good idea what part of the Domino database structure it is used to work with, but some may be more obvious than others until you get more familiar with them.

Click on a few of the class names to see the documentation on that class, and you will see that there is a list of properties and methods for each class. Think of a property as information about that part of the Notes database structure, or information that it may contain. You use properties to get that information or, in some cases, to set it. For example, the NotesDatabase class has a property called "Title". This provides a way to get the title of a database, which is one piece of information about that database. Another property of the NotesDatabase is "Size", which gives you the size of the database file.

Methods are things that you can do with that part of the database structure. The NotesDatabase class has a method named CreateDocument. Something you can do within a NotesDatabase is create a document, and this LotusScript method does just that. There are also methods to get existing documents in a database, such as GetDocumentByID, GetDocumentByUNID, and GetDocumentByURL. Take a look at each of these in the Designer Help to see what each one does. Notice that after you have expanded the list of classes in the left pane of Designer Help you can expand each of the classes to see a list of all the properties and methods in that class. First the properties are listed in alphabetical order, followed by the alphabetical list of methods. As you begin writing LotusScript code, you can scan through the list of classes and the properties and methods of each class, and find something that fits what you want to do or information you want to access. Until you get familiar with all the classes and their methods and properties you may not know what class and method you need to use, but if you look through the list you are likely to see something that sounds like it might be what you need. With experiences, this will get much easier.

Back to top
Part 5: Overview of where to place code in an agent

Video: Part 5 (5 min 36 sec)

Open the example database in the Designer client, by first starting the Designer client, and then use File - Database - Open to select and open the database in the Designer client, just like we did to open it in the Notes client.

In the left side of the Designer client you will see the different types of design elements that exist in a database. Agents are listed under "Shared code", so expand that section and then click on "Agents" to show the agents that are in the database. Right now there are not any agents in this database. Create a new agent by clicking on the "New Agent" button. This opens up a new agent, and also opens the Agent Properties dialog box, where you can make the settings for the agent.

The example agent will be named "Update Locations", so type that in the "Name" field. The settings in the Options section can be left at the defaults. In the Trigger section, this agent will be set to run "On event" and "Action menu selection", and the agent will have a target of "All documents in database". Your Agent Properties dialog box should look like this:





Close the Agent Properties box. Set the agent to be a LotusScript agent by selecting that option in second field next to "Run".






There are four parts of a LotusScript agent which you will see in the "Objects" pane once you set the agent to be a LotusScript agent. They are Options, Declarations, Initialize, and Terminate. Here is a brief overview of what each is for:

Options:

The Options part of the agent is where you can specify certain settings, or options for how your LotusScript agent will behave. "Option Public" is automatically added to the Options section of a LotusScript agent. This means that any variables declared are automatically public variables. Explaining this further is beyond the scope of this course module, and does not really come into play unless you are writing advanced code in which you are programming your own classes. There are other options settings that can be added here as well.

Declarations:

In LotusScript you declare variables to represent the data and objects the code is going to work with. These can be declared in the Declarations section of the agent, but do not have to be declared here. More often they are declared in the code in the Initialize section. The concept of declaring variables will be discussed in this module, but the full purpose and use of the Declarations section is related to the concept of the "scope" of the variables in LotusScript, and is beyond the scope of this module. For the purposes of this course module, it is not necessary to understand the concept of the scope of variables, but it can become very important with more complex and advanced LotusScript programming.

Initialize:

This is the part of the agent where, for the purposes of this module, all of your LotusScript code goes. The Initialize part of the agent is called the Initialize "event" because it represents the action, or event, of the agent being loaded so it can be run. In more complex LotusScript programming, only some of your code will be in the Initialize event, but most simple LotusScript agents can be completely coded in the Initialize event. When an agent runs, the code execution always starts with the code in the Initialize event. The code in the Initialize event is also referred to as the Initialize sub, meaning that is a subroutine of the entire agent. Again, in most cases it may be the only subroutine in the agent that has any code in it, but it is possible to create additional subroutines, or subs, within your LotusScript code.

Terminate:

This is another event, or sub, in a LotusScript agent that is created automatically. This event occurs when the agent is done running and being unloaded from memory. Although it can be used to perform any clean-up operations that need to be executed when the agent is finished running, generally code is not placed in the Terminate event. This is for two reasons: First, LotusScript code pretty much cleans up after itself so it is not necessary to write code that does any clean-up or frees up the memory used by LotusScript. Second, since code in this event is not executed until the agent is shutting down, some of the context of the agent may already be unloaded from memory when the Terminate code executes, which can result in unexpected behavior and errors if code is placed here. Except in rare cases, do not put code in the Terminate event.

Back to top

Part 6: Declaring variables

Video: Part 6 (4 min 48 sec)

The first thing you need to do when you program in LotusScript is to declare the variables you are going to use in your code. You use variable names to work with your data and your class objects. You can name your variables almost anything you want, but naming them something that helps you to be able to readily identify what kind of variables they are is good programming practice. You can name a NotesDatabase object variable "Fred", and a NotesView object variable "peach", and a NotesDocument object variable "peanut" and it won't matter to LotusScript, but your code would be difficult to follow when read by humans. It makes a lot more sense to name the NotesDatabase object variable something like "db", or "database", and to name a NotesDocument object variable "doc" or "NewDoc" or "ServiceDoc". There are certain words that you cannot use for your variable names. These are called keywords, because they have a special meaning or use in the LotusScript language.

For a list of these keywords, open the Designer Help topic Language / Script and Statement Construction Rules / Keywords for a alphabetical listing of all the LotusScript keywords. Do not use any of these words when naming your variables.

There are two kinds of variables in LotusScript. There are data variables and object variables. Data variables are used to hold data information, such as numbers and text, called scalar data types. For a list of the data types in LotusScript refer to the Domino Designer Help topic LotusScript Language / Data Types, Constants, and Variables / Summary of LotusScript data types. Examples of number data types are an integer, a long, a single, a double, and currency. The string data type is used for text information. There is also a scalar data type called Boolean. Boolean variables appear to have a numeric value, but they are not used numerically. They are used to represent True or False, and you can type the words True and False to specify the value of a Boolean. The Boolean value 0 (zero) means False, and the Boolean value of -1 is generally used for True. However, any nonzero Boolean value means True, and this fact is often used in programming logic.

The other kind of variable is an object variable, which is used to hold references to the various kinds of Domino objects, such as NotesDatabase, NotesDocument, etc.

To declare a variable, you use a "Dim" statement. The Dim statement specifies the name of the variable and the type of variable it is. The syntax of the Dim statement, in its simplest form, is this:

Dim variablename As type

For example:

Dim x As Integer

This statement declares a variable named "x" to be an integer. This means that the variable "x" can hold a numeric whole number in the range from -32,678 to 32,767. If you wanted a variable to hold the number 45,250 you would have to declare your variable to be of type Long. So why would you use an integer variable rather than a Long variable? Because the Integer data type uses 2 bytes of memory for storage, and the Long data type uses 4 bytes of memory. Although this is a minute amount of memory by today's standards, it is good programming practice to conserve memory as much as possible, so you would use a long only if you expected the value of your variable "x" to exceed 32,767, which in many programs would not be the case.

You declare an object variable the same way you declare a data variable. For example:

Dim db As NotesDatabase

This statement declares that the variable named "db" is of type NotesDatabase. That means that you can use the "db" variable to refer to, or hold a reference to, a NotesDatabase object. Simply declaring an object variable as a NotesDatabase does not mean it refers to a specific Notes database. It just creates a variable and reserves a space in memory that can be used to hold a NotesDatabase. You have to set the variable to a specific database before there is anything in the variable. An object variable that does not contain a reference to a specific object of its type is said to be "Nothing". More on this a little later.

Back to top

Part 7: Overview of LotusScript back-end classes

Video: Part 7 (3 min 44 sec)

The Domino object system is organized in a hierarchy, in which objects are contained by other objects, and they also contain other objects. This is displayed visually in a chart that you can display in the Designer client.

Go to the Domino Designer welcome page, which first opens when you start the Designer client. If you have already moved beyond the Designer welcome page, you can get back to it by clicking on the far left tab at the top of the Designer client window, the one with the house icon on it.

Once you have the welcome page open on your screen, click on the drop-down list of options in the "Show me:" field and select "Domino Objects for LotusScript and OLE" to display the chart of the Domino objects.





The lines and arrows show some of the hierarchy containment model, but they are not complete. You can click on any of the boxes for the classes to open the Designer Help document for that class -- which is the same document that you can open from the Contents view in the Designer Help and going to the "LotusScript Classes A to Z" section under the "LotusScript / COM / OLE Classes" section. In the document for each class, there is a "Containment" section that lists what classes that class is contained by and what classes it contains. For example, if you click on the NotesDatabase box to open the Designer Help document that describes the NotesDatabase class, you can see that the NotesDatabase class is contained by the NotesDbDirectory, NotesSession, and NotesUIDatabase classes, and that it contains the NotesACL, NotesAgent, NotesDocument, NotesDocumentCollection, NotesForm, NotesNoteCollection, NotesOutline, NotesReplication, and NotesView classes.

A key concept to understand about the LotusScript Domino class structure is that there are back-end classes and front-end classes. Front-end refers to the Notes client user interface (UI). Back-end refers to the data structure and storage behind the scenes, or what is going on behind the user interface. Front-end classes duplicate functionality that you can do manually with your mouse and keyboard in the Notes client, and in fact when you execute code using the front-end classes you will actually see everything happen on your screen in the Notes client, although it may happen so fast that you miss it. Back-end LotusScript classes do things directly in the database structure itself, and are not seen on the screen. You may see the results of what the back-end classes did if you have a database open in your client that you modify with back-end LotusScript, and the client automatically refreshes the display to show the changes that the script made, but you won't actually see the agent doing it.

The difference between back-end and front-end LotusScript is an important distinction because some things work differently between the two, even though it may seem as if they are doing the same thing. One important difference is that when you run LotusScript code manually, such as by running an agent from the Actions menu, you can use either front-end or back-end classes, or a combination of both. But when you run an agent on the server, such as with a scheduled agent, you can only use front-end classes. This makes sense, since there is no UI, or Notes client user interface, on the server. It is easy to tell if a LotusScript class for Domino is a front-end or back-end class. All the front-end classes contain "UI" in their name, such as NotesUIDatabase, NotesUIView, and NotesUIDocument.

In this course module we are working only with back-end classes.

Back to top

Part 8: NotesSession class (top of the back-end class hierarchy)

Video: Part 8 (8 min 03 sec)

Look again at the "Domino Class for LotusScript and OLE" chart on the Designer client welcome page. The top of the back-end class hierarchy is the NotesSession class. This is indicated in the classes chart by the fact that there are arrows going only from the NotesSession box, there are no arrows going to it.

Click on the NotesSession box in the chart to open the Designer Help document on that class. As stated in the Designer Help, the NotesSession class "Represents the environment of the current script." In the Containment section of the document on the NotesSession class, there is no "Contained by" list, because it is at the top of the back-end class hierarchy, and therefore is not contained by any other classes.

Although there are exceptions, most back-end LotusScript code will start with creating a NotesSession object, which provides the context and starting point for getting to any of the other back-end classes. From the NotesSession class, we are able to get to the NotesDatabase class and several other classes -- all the ones listed as being contained by the NotesSession class. By navigating our way through the classes, we can get to everything that is available in the back-end Domino object class model.

To declare a NotesSession object, we use a Dim statement. Let's use the variable name "sess". This statement declares an object variable named "sess" as a NotesSession object:

Dim sess As NotesSession

This just declares the variable, it does not set it to anything. At this point, our NotesSession object variable named "sess" is just a blank, or empty, reference that is created for the purpose of holding a NotesSession object. To set the object to an actual NotesSession, we have to do something in our code to make that happen. As you will see a little later, many objects are set by getting them from or through an object we already have. You can get a NotesDocument object through a NotesDatabase object, for example. But the NotesSession object is at the top of the class hierarchy, so we don't usually have any objects from which we can get a NotesSession object. For this, there is the "New" keyword in LotusScript. As in many programming languages, the keyword "New" is used to call a constructor, meaning that it executes code to construct, or create, an object. You don't have to write any constructor code in this case, just using the "New" keyword will automatically run constructor code behind the scenes to create your NotesSession object. Some, but not all, the Domino classes allow the use of "New" in this way.

To create the object reference for our object variable "sess", you can use the "Set" statement to set the object reference, and the "New" keyword to create the object. To do this after first declaring the object variable, the code would look like this:

Dim sess As NotesSession
Set sess = New NotesSession

The first line declares the object variable, and the second line sets the object variable to an actual NotesSession object reference. This is also called instantiating the object. At this point, we have a NotesSession object referenced by the "sess" variable, and can use the properties and methods of the NotesSession class with that object reference named "sess".

LotusScript also allows us to declare and set the NotesSession object variable with one line of code.

Dim sess As New NotesSession

This one line does exactly the same thing as the two lines in the previous code example.

Let's take a look at a couple of the properties of the NotesSession class to get an idea what information it can provide.

In Designer Help, go to LotusScript/COM/OLE Classes / LotusScript Classes A-Z / NotesSession and expand it to look at the list of the properties. Find the NotesVersion property, and click on it to open the document on that property. It provides the version of Notes that the current script is running in. Note the "Data Type" section, that shows that this property returns a string data type. That means the informational value this property provides, or returns is in the form of a text string. Also note that it says that this property is "Read only". This means that this property of the NotesSession class can be used to get the information about the Notes or Domino version that the current script is running in, but it cannot be used to set it. This makes sense -- you can't expect the change the version of Notes you are running just because your LotusScript code says it is something other than what it is.

Another property of the NotesSession class is the UserName property. This property is used to get the name of the user who is running the code. Note that if the agent is running on a server, such as in the case of a scheduled agent, this returns the name of the server it is running on. The property is also read-only. Most of the properties of the NotesSession class are read-only, because there is not much about the Notes session that can be changed. We will look at class properties that are not read-only when we look at other Domino object classes.

An example of a method of the NotesSession class is the GetDatabase method. Find and open the Designer Help document on this method. The NotesSession.GetDatabase method provides the ability to get a database by providing the name of the server that the database is on and the file name of the database as parameters, or arguments, of the method. These parameters, named "server$" and "dbfile$" are required every time you use this method. The names of the parameters are for descriptive purposes only, you don't have to use those names in your code.

The dollar sign ($) at the end of the parameter name indicates that these parameters are strings, or text. There is a list of the suffix characters that can indicate the data type of parameters or variables in Designer Help, but the topic is somewhat hard to find. Go to the Designer Help topic LotusScript Language / Data Types, Constants, and Variables / Summary of LotusScript data types. Scroll down to the bottom of the document and click on the link "Integer data type". At the bottom of the "Integer data type" document,click on the link "About data types" to open the document containing the list of data type suffixes.

Go back to the document on the GetDatabase method, and notice that there is a third parameter for this method called "createonfail". This parameter is optional, which is indicated by the square brackets around it in the syntax for the method, and also with the word "Optional" in the description of the parameter. This means that it is OK to just leave this parameter out if you do not want to use it. If you don't use an optional parameter, its default value will be in effect. The "createonfail" parameter for this method is a Boolean, meaning that it can be "True" or "False". When using Booleans, the words "True" and "False" do not have quotes around them in the code. The default is "True", which specifies that if the database that you specify with the first two parameters (server name and database file name) cannot be opened or does not exist, the NotesDatabase object variable will be set by this method anyway. This does not mean that the database file will be created, it just means that a NotesDatabase object will be created in memory; it will exist only while the code is running.

Back to top
Part 9: NotesDatabase class

Video: Part 9 (4 min 47 sec)

Another class we are going to need to work with in our sample agent is the NotesDatabase class. The database is the container for all data in Notes and Domino, so you can expect to be using this class a lot. To find the documentation on this class, go to the Designer Help topic LotusScript/COM/OLE Classes / LotusScript Classes A-Z / NotesDatabase.

An example of a property of the NotesDatabase class is Title, which provides access to the title of a database. In Designer Help, click on the Title property in the list of properties for the NotesDatabase class to see the documentation for it. Note that this property is "Read-write". This means that not only can the property be used to get the current title information of the database, but it can be used to change the title of the database as well.

Also look at the "Usage" section of the document for the Title property. It states that "A script cannot change the title of the database in which it is currently running." This means that if you want to change the title of a database with LotusScript, your LotusScript code will need to be in a different database. The "Usage" section of the documentation on the Domino classes and their properties and methods often contain important information about using that class, method, or property. Reading this section of the Designer Help documents can save a lot of time when learning to write LotusScript code.

A useful method of the NotesDatabase class is the CreateDocument method. Look at the document in Designer Help on this method. Note that this method is used to set a NotesDocument object variable. This means that it not only creates a new document in the database, it sets a NotesDocument object variable that you can use to then work with that document in your LotusScript code. The document this method creates is just a blank document. It contains no fields and uses no form at this point. You have to create all the fields, including the "Form" field, in the document in subsequent lines of code.

By now you should be getting a pretty good feel for how to use the Designer Help database to find the information you need about the classes that are available in LotusScript, and the properties and methods of each class. You can use this when writing LotusScript code to find a way to do something that you want your code to do, and details of how to write the code to do it using that class method or property.

To declare a NotesDatabase object variable, you use a Dim statement:

Dim db As NotesDatabase

A NotesDatabase object variable can be set to reference a specific NotesDatabase object in several ways. A couple of them are:

Set Db = Session.CurrentDatabase
and
Set Db = Session.GetDatabase("ServerName","DatabaseFileName")

Note the syntax used here. To use a property or method of a class in LotusScript, you first have to specify what object variable of that class you are using that property or method on, which in this case is a NotesSession object variable "Session". Then you use a dot (period), and then the property or method of that class that you are using. This is called "dot notation".

Go to the Designer Help document on the NotesDatabase method (LotusScript/COM/OLE Classes / LotusScript Classes A-Z / NotesDatabase) and scroll down to the section "Creation and access". This section is common to most of the Designer Help documents on the Notes/Domino classes, and provides useful information on using that class to get access to the part of Notes that the class represents.

Back to top

Part 10: Starting to write the agent code

Video: Part 10 (3 min 28 sec)

It is time to use what we have learned so far to start to write our LotusScript agent.

Earlier, we created our agent named "Update Locations", but did not put any code in it. Now that we know a little bit about the NotesSession and NotesDatabase classes, we can use that knowledge to start writing the code for our agent. So with the database open in the Designer client, under Shared Code click on Agents, and we see our agent on the right part of the screen. Double-click the "Update Locations" agent to edit it, and since we have already set the Agent Properties we can close that dialog box. In the Objects pane, click on Initialize. This is where the code for the agent will go.

The IDE, which stands for the Integrated Development Environment, automatically puts two lines in the Initialize event: "Sub Initialize" and "EndSub". These mark the beginning and the end of the subroutine named Initialize. All the rest of the code for this sub will go between these two lines.




First, we need a NotesSession to give us the context in which to work in the back-end LotusScript realm. We get this by declaring and instantiating a NotesSession object variable, which we can do with one line of code:

Dim sess As New NotesSession

Next, we need a NotesDatabase object variable, because we are going to need to work with data in a Notes database. So we will need to declare a NotesDatabase object variable:

Dim db As NotesDatabase

Now we have to think about how we are going to set this NotesDatabase object variable to the database we need to work in. As we saw in the NotesDatabase class documentation in Designer Help, there are several ways to set a NotesDatabase object variable to a database. In this case, we are creating our agent in the same database that we are going to modify the documents in, which is a very common practice. So it makes sense to use the CurrentDatabase property of the NotesSession class, like this:

Set db = sess.CurrentDatabase

So at this point, we have the first three lines of our LotusScript code:

Dim sess As New NotesSession
Dim db As NotesDatabase
Set db = sess.CurrentDatabase

Your agent should look like this:





The agent is going to process the documents that appear in a certain view in the database, so next we will look at working with Notes database views in LotusScript.

Back to top

Part 11: NotesView class

Video: Part 11 (7 min 02 sec)

A common practice with LotusScript agents is to write an agent to process the documents that are in a particular view in a database. A view provides a convenient way to have an agent operate only on documents that meet a certain criteria, because a view selection formula specifies what criteria a document must meet to appear in that view.

Often an agent will be written to use a view that already exists in the database, which was created for users of the database because it organizes the documents in a way that makes it easy for them to find the documents they need to work with. If an existing view contains the documents that an agent is going to work on as well, then it makes sense to have the agent use that view too. In some cases, however, it is efficient to actually create a view just for an agent to use, because we can create a view selection formula to include the documents that we want an agent to process. Often such a view would be created as a hidden view, if it's not a view that users of the database would use.

In this case, there is already a view in our database that displays all the service request documents, which are the documents we are interested in processing. We actually only want the agent to modify the documents that are for the south region, so we could create a new view that displays only service request documents that have the value "South" in the "Region" field, and then just have the agent process all the documents in that view. However, since this agent will only need to run and process these documents one time, we will use the view that already exists, and check the documents as we process them to determine if they are for the south region.

The NotesView class is the LotusScript class that represents a view in a database. To find the documentation on this class, go to the Designer Help database and find the topic LotusScript/COM/OLE Classes / LotusScript Classes A-Z / NotesView. Take a look at the list of the properties and methods of the NotesView class in Designer Help.

An example of a property of this class is the IsFolder property. LotusScript uses the NotesView class to work with both views and folders, because views and folders are almost the same in a Notes database. The only difference between a view and a folder is how documents get to be in them. A view has a selection formula, and Domino automatically creates and updates an index for each view. Documents that match the criteria of the view selection formula will be displayed in the view; documents that do not meet the view selection criteria will not appear in the view. A folder, on the other hand, has no selection formula. Documents appear in a folder because they are put in that folder by a user or programmatically, and remain there until they are removed from the folder or deleted from the database. For the most part, LotusScript can work with either a view or a folder the same way, but in some cases it is important that you determine if the object referenced by a NotesView object variable is a view or a folder. The IsFolder property tells you which it is, as this property will return True for a folder, and False for a view.

A example of a method of the NotesView class is the Refresh method. Calling this method refreshes the view index, so the view will display any recent changes to the database, such as new or modified documents.

So we know we need to use the NotesView class to work with a view, but how do we set it? A good way to find out is to look at the "Access" section of the Designer Help document for the NotesView class. It tells us that to access a view or folder when you know its name or alias, use the GetView method, and we can just click on the "GetView method" link to jump to the document on that method. The syntax is pretty straight forward. It requires one parameter, as string parameter which is the name of the view you want to get.

So going to our agent code, we first need to declare a NotesView object variable, and then set it to the view we want to work with. We will name our NotesView object variable "view", and so our Dim statement will look like this:

Dim view As NotesView

It is standard practice to put all the Dim statements at the beginning of the code. It is not required to do this, and in fact the code will work the same no matter where in the subroutine we put the Dim statements because the Dim statements are actually processed first when that subroutine is loaded to run. But putting them at the top makes it easy to see what variables the code is using, and is a good way to organize our code.

All other code executes in the order it is written, so we have to set the NotesView object variable only after we have set the NotesDatabase object that we are going to use to get the NotesView object. So the line to set the view will go after the line that sets the NotesDatabase object variable "db"

After adding these lines, your code should look like this:

Dim sess As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Set db = sess.CurrentDatabase
Set view = db.GetView("Services and Locations")

So far we have our database and view objects set. The next thing to look at his how we work with the documents in that view.

Back to top

Part 12: NotesDocument class

Video: Part 12 (3 min 16 sec)


The LotusScript class that represents a Notes document is the NotesDocument class. Just as you spend most of your time working in documents in your Notes client, you will be using the NotesDocument class a lot in LotusScript because the document is the core component of data in Notes. LotusScript provides the ability to create documents, put data in document fields, and read data from document fields, as well as ways to get other information about documents. Take a minute to review the list of properties and methods of the NotesDocument class in Designer Help.

Look at the "Access" section of the NotesDocument class Help document. It shows that there are several ways to access a document to set a NotesDocument object variable.

When choosing which property or method to use in LotusScript, you have to stop an think about what information you have, or can easily get, and how you can use that information to get to what you want. For example, if you want to write your code to do something to a document, and you know what database the document is in and you know the UNID of the document, you can use this information to get the document by first getting to the database with the NotesSession.GetDatabase method, and then using the NotesDatabase.GetDocumentByUNID method. In our example, we do not know the UNIDs of the documents we want to process, we just know that they all appear in a specific view in a database. We are going to write our script in the database that the documents are in, so it will be the "current database" to the script. And we know that the name of the view where the documents are displayed is "Services and Locations", and we found the GetView method that will get us the view.

The documentation for the NotesDocument class says "To get a document based on its position in a view, use a NotesView." It does not say what property or method of the NotesView class to use. Looking through the list of properties and methods of the NotesView class, we see that there is a method called "GetAllDocumentsByKey" which sounds like it might be useful, but reading the documentation on that class we see that it requires a parameter called "keyarray", which is the values in one or more columns of the view for the documents that we want to find. More reading on this method also reveals that the view needs to be sorted by the columns that the key values are in, and that the method returns a NotesDocumentCollection object. This sounds like a handy method, but is not ideal for what we need to do in this case, so keep looking.

There is a method in the NotesView class called "GetFirstDocument". The documentation for this class says "GetFirstDocument is useful when: You want to access every document in the view. Use GetNextDocument to find documents after the first one." This sounds like just what we need. Take a look at the documentation on the GetNextDocument method of the NotesView class. Click on the "Example" link to see the example of using the method. The first example shows just getting the first and the second document. The second example says "This script shows how you can use a While loop and GetNextDocument to access every document in a view. This is exactly what we want to do. And, it brings us to the next topic -- loops in LotusScript.

Back to top

Part 13: Loops in LotusScript

Video: Part 13 (13 min 23 sec)


For the most part, LotusScript works with one object at a time. For example, in the case of documents, LotusScript code gets data from, or makes modifications to, one document at a time. So to process more than one document it is necessary to write what we call a "loop" in the LotusScript code. A loop is a block of code that will execute multiple times. So we would write the code to modify one document, and then have that same code execute again on another document, and keep executing that code over and over again until it has processed all the documents that we want to process.

A loop checks some condition or count every time it loops in order to decide whether to loop again to exit out of the loop. Loops must be coded carefully so that the code in the loop executes the right number of times to process everything that we want to process, and not miss anything. It is also important to make sure that the loop exits at the right time, or errors may occur if code tries to execute on something that does not exist. Worse yet, incorrect coding of loops can result in an infinite loop, where the loop executes over and over again and never stops. Such code will never finish running, and it may be necessary to forcibly terminate the Notes client or Domino server program in order to get the code to stop running.

There are a few different looping statements in LotusScript. For documentation on these, see the Designer Help section LotusScript Language / Managing flow in Scripts / Iterative statements. The "For" loop is used when you wish to loop through a block of code a certain number of times. The "Do" and "Do While" statements execute a loop based on a condition being true or false. A "Forall" statement loops through all the elements in an array, list or collection. And the "While" statement executes a loop as long as a condition is true.

In our example script, we want to loop through all the documents in a view. If we knew how many documents we were going to process when we were writing the script, we could use a "For" loop, but typically we would not know this at the time we are writing the code, and for code that was going to be used multiple times the number of documents that need to be processed may be different every time the code is run. So we have to be able to loop based on a condition. But we want to loop through all the documents in a view. Our agent will only modify some of the documents -- the ones with "South" in the "Region" field, but we don't want to stop looping through documents the first time we come across one that is not in the south region, because there are likely to be more documents after that one that are in the south region. So we can't use that as our condition for our loop, although we will be checking that condition as we process the documents in order to decide whether or not to modify each one. But first we need to create the loop to iterate through all the documents in the view.

The condition that we want to check for each time through our loop is whether all the documents in the view have been processed or not. This makes sense in terms of human thinking, but how do we write our code to tell it to loop through all the documents in the view and stop when all the documents have been processed? Basically, our code needs to start with the first document in the view, process it, and then go to the next document in the view and process it, and then go to the next document and process it, etc. If we get to the last document in the view and process it, and then we try to go to the next document, what would that document be? It would not be anything, because there is no next document. So we would try to get the next document, and end up getting nothing. It turns out that "Nothing" is a constant in LotusScript that indicates just this kind of condition.

To find the document in Designer Help that explains the "Nothing" constant, go to LotusScript Language / Data Types, Constants, and Variables / Constants / Built-in constants. "Nothing" is the state of an object variable when it is first declared, because it has not yet been set to anything. So if we just declare a NotesDocument object variable named "doc" with the Dim statement:

Dim doc as NotesDocument

At this point, "doc" is just an object variable that does not yet contain a reference to an actual Notes document, so it can be said that "doc" is "Nothing". If we use another line of code to set the "doc" object variable to a specific document, then it actually becomes a NotesDocument object and, in effect, becomes something. But there is no LotusScript constant or condition called "Something". Instead, we say that the "doc" object variable is "Not Nothing".

When looping through all the documents in a view, when we are processing the last document in the view and then we try to get the next document, we will get no document, or the NotesDocument object variable named "doc" will become "Nothing". So this is the condition that we want to use to control our loop -- we want to exit the loop when the "doc" is Nothing. The looping statement most suited to this kind of loop is the "While" statement, which checks for a condition at the beginning of each iteration of the loop, and if the condition is true it proceeds to execute the code in the loop. But what if we want to execute the loop code if a condition is false? For that we can use the LotusScript "Not" operator, which negates an expression.

So the condition we are going to evaluate is whether the NotesDocument object variable is "Nothing", which is expressed in LotusScript as:

doc Is Nothing

but we want to determine if it is True that doc is Not Nothing. This would be written like this:

Not (doc Is Nothing)

The While loop statement can be written like this:

While Not (doc is Nothing)
< code to execute within each iteration of the loop >
Wend

As long as the "doc" object variable is set to a valid Notes document, then the expression

Not (doc Is Nothing)

will evaluate to True, the code in the loop will execute, and then the condition will be checked again.

"Wend" indicates the end of the While loop, so when the code gets to the "Wend" the path of execution goes back to the "While" statement, which will evaluate the condition again. If the condition is True, the code within the loop will execute again. If the condition is False, the code will exit the loop and will continue executing with the next line of code after the "Wend".

So now we can go back to our example agent, and write the code that will loop it through the documents in the view.

So our code will look like this:

Dim sess As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim doc As Nothing
Set db = sess.CurrentDatabase
Set view = db.GetView("Services and Locations")
Set doc = view.GetFirstDocument
While Not (doc is Nothing)
<code to execute within each iteration of the loop>
Wend

Between the While statement and the Wend is where we will put the code that will actually check each document and modify the document if it needs to be updated.

There is nothing about the While and Wend statements that will cause the "doc" NotesDocument object variable to change from one document to the next document in the view. If "doc" is the same document every time the loop executes, it will never be Nothing, unless the code actually deletes the document. In the above code, we would have an infinite loop, and our agent would theoretically execute forever, processing the first document in the view over and over again. So part of the code within the loop must change "doc" to point to the next document. This is where the GetNextDocument method comes in. It is essential that we add this to the code within the loop.

Dim sess As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Set db = sess.CurrentDatabase
Set view = db.GetView("Services and Locations")
Set doc = view.GetFirstDocument
While Not (doc is Nothing)
<code to execute within each iteration of the loop>
Set doc = view.GetNextDocument(doc)
Wend

Now the code will go to the next document each time through the loop, and then check to see if that document is "Not Nothing" before executing the code in the loop again. The result will be that every document in the view will get processed, and the loop will stop executing after the last document.

Back to top

Part 14: Accessing the fields in a document

Video: Part 14 (9 min 25 sec)


Once we have a document, we need to get to the fields in the document. Fields are called "items" in LotusScript, and are represented by the NotesItem class. It is not always necessary to use the NotesItem class to get values from fields and the set the values of fields, there are ways to do this with the NotesDocument class. But for some things it is required to work directly in the NotesItem class. There are various properties and methods of the NotesItem class that enable you to do just about anything you would want to do with a field. But since we can do everything we need to do in this example directly in the NotesDocument class, this course module will not go into detail about the NotesItem class. There is a section in the NotesItem class Designer Help document about accessing items directly from a document, which is what will be discussed in this part of this course. Open that document now (LotusScript/COM/OLE Classes / LotusScript Classes A-Z / NotesItem) and scroll down to the section "Accessing items directly from a document".

It says that to get the value from an item, use the GetItemValue method. We can click on the word "GetItemValue", which is a link, to take a look at the documentation on this method in the Designer Help. It requires a string argument to specify the name of the field that you want to get the value from. Notice that the return value depends on the type of field that it is, but in all cases it is array. What is an array? Designer Help defines an array as follows: "An array is a named collection of elements of the same data type, where each element can be accessed individually by its position within the collection." Arrays are another topic that this course module is not going to go into detail about. You can read up on arrays in LotusScript in Designer Help under LotusScript Language / Arrays. For the purpose of this course module, it is adequate to understand that when we say that the NotesDocument.GetItemValue method returns an array it means that it returns a group of values.

A field in Notes can contain a single value or multiple values. In the case of a multiple value field containing more than one value, it's a little more obvious that the field contains an array, or group, of values. As far as LotusScript is concerned, a field (item) always contains an array of values. If it is not a multiple value field, then it will contain only one value, but in LotusScript it will be an array containing one element and must be treated as an array. The way you specify which element of an array you want to work with is with an index. The first element in an array has the index of 0 (zero). If there is second element in the array, it has the index of 1, and so on. The index goes in parentheses right after the array. So if we want to get the first value in a field named "Subject" using the GetItemValue method and assign it to a variable named myVariable, we write it as follows:

myVariable = doc.GetItemValue("Subject")(0)

This line of code says to get the array of values that are in the "Subject" field in the document currently referenced by the "doc" object variable, get the first element or value in that array of values, and set the value of myVariable to that first value. The index of zero applies to the entire expression 'doc.GetItemValue("Subject")', because that is the expression that returns the array. It seems complicated, but it becomes second nature with experience.

If you forget to put the (0) to specify the first element in the array, like this:

myVariable = doc.GetItemValue("Subject")

a "Type mismatch" error will occur when this script runs. This error refers to data type. If "myVariable" is declared as a String, it can hold only a String data type. But the GetItemValue method returns an array of strings. A String data type variable cannot accept an array, so the "Type mismatch" error occurs because the value that the code is trying to put in the variable does not match the data type of the variable. If myVariable was declared as a Variant, no error would occur, because an variant can hold an array. But anything you did with myVariable afterword would have to take into consideration that myVariable is an array. The Variant data type is basically a universal data type that can hold any scalar data or any class object, or an array.

To set the value of a field in a document, the ReplaceItemValue method of the NotesDocument class can be used. This method requires two parameters: the name of the field to be set, and the value to put in that field.

This would look like this:

Call doc.ReplaceItemValue("Subject", "Hello")

Note that no array index is required when setting the value of a field with ReplaceItemValue. The field will be created with an array of values, containing one element, but LotusScript does this automatically and it is not necessary to treat it as an array in your code when putting a value in the field.

In these examples we used strings for the parameters, so the parameters are in quotes to indicate that they are hard-coded strings. Every time this code runs, the parameters will be the same. Variables can be used to specify most parameters for methods in LotusScript. Here is an example of using variables for the parameters of the ReplaceItemValue method:

.....Dim other variables as needed....
Dim doc as NotesDocument
Dim fieldName as String
Dim fieldValue as String
.....set doc to a valid NotesDocument...
fieldName = "Subject"
fieldValue = "Hello"
Call doc.ReplaceItemValue(fieldName, fieldValue)

Note that the variable names do not go in quotes. In this example we are hard coding the values of the variables "fieldName" and "fieldValue" in the code, so again they would always have the same values, but we could have the variables set by other code so that they could be different every time the code ran, depending on what it was processing at that time.

We could also use the NotesItem class to get and set the values in a field in a document, but again, that is not a topic that will be discussed in the course module. But there is yet another way to get and set field values in LotusScript, that we will discuss here. It is called "Extended class syntax". It is called that because it extends the NotesDocument class by letting you use an item (field) name as if it were a property of NotesDocument.

Here is how to use extended class syntax to get the value of a field named "Subject":

myVariable = doc.Subject(0)

Note that the name of the field does not go in quotes, because it is being treated as a property of the NotesDocument object variable doc. Also note that the return value is still an array, so you must use the array index of (0) to designate the first element of the array.

Here is how to use extended class syntax to get the value of a field:

doc.Subject = "Hello"

The same rules apply as with ReplaceItemValue value, in that you do not have to use an array index when setting the field value with extended class syntax.

Any changes made to a document in LotusScript back-end classes are changed in memory only. The actual document stored in the database is not changed until the document in memory is saved by the script. The Save method of the NotesDocument class must be called to save the document to the database. Read the documentation on this method in Design Help: LotusScript/COM/OLE Classes / LotusScript Classes A-Z / NotesDocument class / Save method. Note that is has two required parameters. In most cases, specify True for these two parameters, but read the documentation on these parameters in Designer Help. There may be situations in which you would want to use False for one or both of the arguments.

Back to top

Part 15: Using If - Then to determine code execution based on a condition

Video: Part 15 (3 min 13 sec)

A common requirement in programming is to execute a specific block of code if a condition is true, and not execute that code, or execute different code, if that condition is false. Like many programming languages, LotusScript uses the "If" statement for this.

There are a couple of different ways to code an If statement, but it is most commonly used like this:

Dim x As Integer
Dim y As Integer
....code that sets x....
If x = 5 Then
y = 10
End If
....more code here...

In this simple example, if the integer value x holds the value of 5, the indented line y = 10 will execute and the variable y will get set to 10.
If the value of x is not 5, the line that sets y will not execute at all, but rather the code execution will jump to the "End If" line of code, and proceed executing with the next line of code after the "End If" There can be as many lines of code between the "If" statement and the "End If" as you want. All the lines between, and including, the "If" and the "End If" is referred to as an "If block", and there can even be loops, or other If blocks, within an If block.

If there is only one line to be executed if the condition is true, the If block can be written all on one line as follows:

If x = 5 Then y = 10

The results are the same as above, in that the part of this line of code after the "Then" will only execute if the condition "x = 5" is True. There is no need for an "End If", because the code to execute is immediately following the "Then" on the same line. In this case, the end of the code line serves as the "End If". But it is most common to code an If block on separate lines, as in the first example, because it makes the code easier to read, and in most cases there are multiple lines of code in the If block anyway.

You can also code the If block to check for multiple possible conditions, using ElseIf and Else statements, like this:

Dim x As Integer
Dim y As Integer
....code that sets x....
If x = 5 Then
y = 10
ElseIf x = 6 Then
y = 7
Else
y = 0
End If
....more code here...

In this example, if x has the value of 5, the line of code that sets y to 10 will execute, and then the code execution will jump to the "End If", If x does not have the value of 5, the line of code "y = 10" will not execute, and the code execution will jump to the ElseIf statement, and the condition "x = 6" will be checked. If this condition is true, then the line y = 7 will execute and set y to 7, and code execution will go to the "End If". If "x = 6" is false, then the code execution will jump to the next ElseIf, if there is one, etc. When all the ElseIf conditions have been checked, if none of them are true, then the code will jump to the Else statement, and any code below it will be executed, so in this example y would be set to 0.

This is a brief summary of the most common ways to use the If statement. To read more on this topic, a good place to start in the Designer Help is LotusScript Language / Managing flow in Scripts / Block statements / Specifying multiple test conditions with the If...Then...ElseIf statement. Follow the links on this page for additional related topics.

Back to top

Part 16: Completing and compiling the code

Video: Part 16 (12 min 23 sec)

Now we have covered the necessary topics on how to get the value from a field in each document in our view, check it to see if it matches the condition for changing the document and, if so, change the value in another field.
Here is the completed sample agent code:


Dim sess As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim doc As NotesDocument
Dim regionValue As String
Set db = sess.CurrentDatabase
Set view = db.GetView("Services and Locations")
Set doc = view.GetFirstDocument
While Not (doc is Nothing)
regionValue = doc.GetItemValue("Region")(0)
If regionValue = "South" Then
Call doc.ReplaceItemValue("Location", "Houston")
Call doc.Save(True, True)
End If
Set doc = view.GetNextDocument(doc)
Wend

A string variable named "regionValue" has been declared to temporarily hold the current value from the "Region" field in each document. As each document is processed within the "While" loop, the "regionValue" variable is set with the NotesDocument.GetItemValue method, in this line of the code:

regionValue = doc.GetItemValue("Region")(0)

The "If" statement checks to see if the value in the "regionValue" variable is equal to "South":

If regionValue = "South" Then

Only if this condition is true will these lines of code execute:

Call doc.ReplaceItemValue("Location", "Houston")
Call doc.Save(True, True)

to change the value in the "Location" field and save the document.

Whether the "If" statement evaluates to True and the current document is changed or not, the "doc" variable is set to the next document with this code line:

Set doc = view.GetNextDocument(doc)

before we get to the "Wend" that marks the end of the "While" loop, at which point the loop condition:

Not (doc is Nothing)

is checked again to determine of the code within the loop will execute again. Remember that when we are on the last document in the view, and we set the "doc" variable to the next document, there will be no next document so the "doc" object variable becomes "Nothing". At this point, the condition

Not (doc is Nothing)

will be False, and the code will exit the loop and go to the next line of code after the "Wend" statement.

One additional thing to be aware of is that text comparison is case sensitive in LotusScript. This means that if we compare "South" with "south", they will not be the same. In our sample code, if the value in the "Region" field is "south", and therefore the value of the string variable "regionValue" is set to "south", the If statement:

If RegionValue = "South" Then

will evaluate to "False" when in fact we would want it to evaluate to "True" so the document will be modified.

There are two ways to deal with this, if we want these two values to be considered equal. First, we can convert both values to upper case or lower case, with the LotusScript UCase or LCase function. Documentation for these functions can be found in the Designer Help:
LotusScript Language / LotusScript Language Reference / LCase
and
LotusScript Language / LotusScript Language Reference / UCase

Second, we can set an option in our agent to make all text comparison case insensitive. To do this, we go to the "Options " section of the agent, and add this line:

Option Compare NoCase

So if we wanted all string comparisons in our agent to be case insensitive, we could use the "Option Compare NoCase" statement; if we wanted only some string comparisons to be case insensitive, we would not use the "Option Compare NoCase statement", and use UCase or LCase to convert strings that we wanted to compare without case sensitivity to all upper or all lower case. Since we are making only one string comparison in our sample agent, we could do it either way. We will use UCase in our example. Since one of our strings that we are comparing is hard coded, we can just hard code it to be all upper case in the "If" statement, so there is no need to convert it with UCase:

If RegionValue = "SOUTH" Then


We will convert the value that we get from the field in the document to upper case for the comparison. We can do this by putting the entire expression that returns the value of the Region field as the argument for the UCase function.

regionValue = UCase(doc.GetItemValue("Region")(0))

Now the value that is returned by

doc.GetItemValue("Region")(0)

will be converted to all upper case before it is stored in the "regionValue" string variable. So when it is compared to "SOUTH", in all upper case, if the field contains the text string "south", regardless if each character is upper or lower case, the comparison in the If statement will evaluate to True, and the code to change the value of the Location field and save the document will execute. If the Region field does not contain the word "south", the If statement condition will be false, and the code in the If block will be skipped for that document, and the document will not be changed.

So now the complete agent code should look like this:

Dim sess As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim doc As NotesDocument
Dim regionValue As String
Set db = sess.CurrentDatabase
Set view = db.GetView("Services and Locations")
Set doc = view.GetFirstDocument
While Not (doc is Nothing)
regionValue = UCase(doc.GetItemValue("Region")(0))
If RegionValue = "SOUTH" Then
Call doc.ReplaceItemValue("Location", "Houston")
Call doc.Save(True, True)
Set doc = view.GetNextDocument(doc)
End If
Set doc = view.GetNextDocument(doc)
Wend


To compile the LotusScript code, either save the agent, or close the agent and click "Yes" when prompted to save the agent. The LotusScript compiler will check the code for syntax and other errors, and save and compile the code only if it passes all the compiler checks. If the code passes the compiler checks, it will be compiled and saved. If there are errors, the compiler will not save and compile the code, and instead will notify you with the following prompt if you tried to save the agent without closing it, such as by using the menu option File - Save:



If you tried to close the agent and clicked "Yes" when prompted to save, and the compiler found errors, you will see this prompt:



If you choose "No" in this prompt, the agent will close and everything you have done since last saving the agent will be lost.

If you choose "Yes", or if you just tried to save the agent without closing it and got the first error, the compiler will indicate what the error or errors are, and what line or lines of code caused the errors. See the Part 16 video for an example and details on how to find errors that the compiler found.

A list of the compiler errors can be found in the Designer Help under LotusScript Language / Compile-time Error Messages.


Back to top

Part 17: Testing the agent using the LotusScript Debugger

Video: Part 17 (9 min 8 sec)

Once you get your code to compile and save, the next step is to test it. A LotusScript agent can change a lot of data very quickly, so it is best to test a new or modified agent in an isolated test environment, or at least in a test copy of the database or databases that the agent will affect. The Part 17 video demonstrates running the sample agent in the debugger.

For general information and a demo on using the LotusScript Debugger, see module 1 of this training.

Back to top
Additional Resources

We hope you have found this course document and the videos to be a useful learning tool. As stated previously, this course is not a comprehensive training in LotusScript, but rather an introduction by example to LotusScript programming. It is intended to get you started so you can learn as you go. You can teach yourself LotusScript using this course and relying on the Domino Designer Help database as a reference. However, a more comprehensive LotusScript training course may be helpful to more quickly learn LotusScript skills. For information on course offerings, go to this URL:

http://www.ibm.com/software/sw-lotus/services/cweeducation.nsf/wdocs/notesdomino

The "course description" links on that page are a good way to get a list of all the courses available, and find the ones for LotusScript.
Back to top

Related information

All-in-one Admin Tool for agent-based troubleshooting &

Document information

More support for: IBM Domino Designer
LotusScript

Software version: 6.0, 6.5, 7.0, 8.0, 8.5, 9.0

Operating system(s): Windows

Reference #: 7010431

Modified date: 08 July 2011