Chapter 5
An Introduction to
Formula Language
Chapter Overview
T
his chapter will introduce you to the Lotus Formula Language. There are many books
on the market that teach syntax and how to program. However, this chapter is
intended to be a general introduction to facilitate learning and to help you understand
the projects provided in this book. Additional information can be found in the Domino
Designer help database that is included with the Designer software.
By the end of the chapter you will have learned
• What Formula Language is
• What @Functions are
• What @Commands are
• The basic syntax structure
• How to assign values to variables
• How to construct multi-line formulas
• How to use formulas to calculate a field value
• Frequently used @Functions
• Frequently used @Commands
93
Elliott_05.qxd 9/14/06 2:27 PM Page 94
Then, in 2002, Lotus decided to completely rewrite the underlying processor (or engine)
used to interpret the formula language source code. This significantly improved its per-
formance and expanded its capabilities. Using a few simple Formula Language commands
and functions, you can build a robust database application.
What Is a Formula?
In the simplest terms, formulas are used to produce a data value or action. This value or
action is derived by using one or more commands, functions, or statements to create a main
expression. All formulas must have a main expression that equates to a result. If the formula
does not produce a value or action, the Designer client will not allow you to save the
formula.
For example, the following illustrates an invalid formula. Here, the text value “Happy New
Year” is assigned to a temporary variable called message. Although the formula does per-
form a calculation, there is no main expression. This formula does not produce a result.
For this example to be valid, the formula must do something to produce a result. This sec-
ond example illustrates a valid formula. Looking at this formula, you’ll notice that the first
line performs a computation by assigning a text value to a temporary variable. The state-
ment is terminated with a semicolon, which separates the first statement from the second.
The formula then ends with the main expression, which defines the value for the field.
message := "Happy New Year";
message
In this case, the main expression is assigned the contents of the variable message.
Alternatively, the same result could have been achieved by setting the text string to be the
main expression, as illustrated next.
TIP
Now let’s take a look at the basic syntax rules for working with variables. There are two types
of variables that can be utilized in formulas—temporary variables and field name variables.
Elliott_05.qxd 9/14/06 2:27 PM Page 95
Temporary variables, as the name implies, are used to temporarily store a value associated
with the formula. Temporary variables cannot be referenced outside of the formula and only
contain a value for the duration of the formula’s execution. In other words, the value stored
in a temporary variable is not saved when the document or form is saved and cannot be ref-
erenced by other formulas.
The syntax for creating a temporary variable is VariableName and the assignment operator
:= followed by the data value and semicolon. For example, the following assigns "January"
to the temporary variable called month.
month := "January";
Conversely, field name variables reference actual fields on a document or form. When used
in a formula, you can reference or change the value stored in the field name. In other words,
by using formulas, you can use field names to calculate the main expression or modify the
value already stored in the field.
There are three ways to reference an existing field. The FIELD keyword is used to assign a
value to an existing field. Using this keyword, the contents of the field are permanently
changed and will be stored in the field when the document is saved. The syntax for setting
a field value in a form or document is FIELD FieldName and the assignment operator :=
followed by the new value and a semicolon. For example:
It’s important to note that if the field exists on the form, the new value will replace the exist-
ing data value. If the field does not exist on the form, Notes will create the field and assign
the value. Alternatively, you can also use the @SetField function. This function works just
like FIELD with one exception: @SetField can be imbedded within other Formula
Language functions.
Finally, to acquire the value of an existing field, you can use the @GetField function. Using
this function, you can use the value stored in field inside another formula. For example, the
following will create the text string "Your project is due in: January", assuming
the Month field contains a value of "January".
"Your project is due in: " + @GetField ( "Month" );
NOTE
As with any programming language, Formula Language includes a number of reserved key-
words that have special meanings. These keywords are used to perform special functions and
cannot be used as variables. For example, the following table describes the current list of
Formula Language reserved keywords.
Keyword Meaning
DEFAULT Used to define the initial or default value for a field. For example,
let’s say you have a field called Status. Using the following
formula, the field will be set to a value of "New Request" when
the document is created. This field will continue to hold this
value until either the user or the Notes application changes the
value. After the stored value is changed and the document is
saved, the new value will be stored in the field.
DEFAULT Status := "New Request"; Status
Keyword Meaning
By default, reserved words are always the first word in a statement. Reserved words may be
entered in lower, upper, or mixed case. However, Designer will automatically convert lower
or mixed case words to uppercase when the formula is saved.
Operators are used to compare or equate values and for mathematic calculations. The fol-
lowing table lists the primary operators used in formulas.
* Used in multiplication
/ Used in division
| Represents a logical OR
continues
Elliott_05.qxd 9/14/06 2:27 PM Page 98
= Represents equal
The Formula Language syntax rules are quite simple. All formulas must adhere to the fol-
lowing five rules.
Rule 1: A semicolon must separate all formulas that contain more than one statement. It’s
important to understand that multiple statements can reside on a single line, pro-
vided that a semicolon delineates each statement. For example, the following are
valid multi-statement formulas.
Example 1
DEFAULT status := "New Request"; status
Example 2
DEFAULT status := "New Request";
status
Rule 2: At least one space must follow all reserved keywords. Otherwise, any number of
spaces—from none to many—may be used to separate operators, punctuation, and
values. For example, the following are valid and equivalent statements (with regard
to spacing):
output := "Today's date is: " + @Today;
output:="Today's date is: ” + @Today;
FIELD output:= "Today's date is: " + @Today;
Rule 3: Two values, variables, or strings must be separated by at least one operator. For
example, the following are valid statements. In the first example, the plus sign is
used to sum the two numbers and divide the result by 2. In the second example,
the plus sign is used to concatenate two values together. Finally, the third example
shows three @Functions separated by the plus operator.
output := (100 + 200)/2;
output := "The sum of the two numbers is: " + total;
output := @Month+@Day+@Year;
Elliott_05.qxd 9/14/06 2:27 PM Page 99
Rule 4: You must use the := assignment operator to assign a value to a variable, whereas
the equal sign = is used to compare two values when used in a conditional state-
ment (such as the @IF, @WHILE, or @FOR functions).
myVariable := "This is a valid assignment";
Rule 5: All formulas must contain a main expression that either produces a value or per-
forms an action. For example, the following are valid main expressions.
The following returns today’s date.
@Today
The following checks if the value stored in the result variable is equal to one. If
the condition is true, then the formula returns the text string "Yes". Otherwise,
the formula is set to a text string "No".
@If ( result = 1; "Yes"; "No")
continues
Elliott_05.qxd 9/14/06 2:27 PM Page 100
@DeleteDocument Agents
@DocMark Agents
NOTE
Commands are used to perform an action related to the application interface. For the most
part, commands mimic menu options and tend to be used primarily in action buttons,
hotspots, agents, and events. For example, commands can be used to
• Compose a new form
• Edit, save, or close a form
• Jump to a field and insert text
• Attach a file
• Send an email
• Open the database help document
Elliott_05.qxd 9/14/06 2:27 PM Page 102
NOTE
The following table represents some of the most frequently used commands. In most cases,
these commands would be placed in an action button for a given form.
Many formulas are used to manage and manipulate text strings. Using functions, you can
parse information, implement data validation, and enforce consistency across data values. For
example, the following are some of the more common functions used to manage text strings.
The primary method to manage conditional branching is the @IF function. As with most
programming languages, this function tests an equation and then branches to the appro-
priate action. The following describes the syntax for this function.
If the condition equates to true, then action1 is performed. Otherwise, if the condition
equates to false, then action2 is performed. It’s important to note that you can also nest
@IF statements inside @IF statements. For example:
@If (@Created = @Today; "Document created today.";
@If (@Created = @Yesterday; "Document created yesterday."; "Document created in
past."));
In this example, the first condition compares the document creation date with today’s date.
If the two values match, then the formula executes action1 and returns the text string
"Document created today." If the values do not match, then the formula executes
action2, which is the nested @IF statement. Here, the creation date is compared with yes-
terday’s date. If the values match, then the formula returns the string "Document created
yesterday." Finally, if the document was not created yesterday, the string is set to
"Document created in the past."
The following are functions that can be used to manage loops. To implement these func-
tions, you must be running Lotus Notes release 6 or greater.
@For Executes one or more statements while the The following loops through
specified condition remains true. After the elements of a keyword field
each execution, the condition is rechecked called Options. With each
to verify that the statement remains true. iteration, a counter called
Syntax: cntr is incremented and the
@For ( initialize; condition; keyword element is displayed
increment; statement); to the user.
initialize—The starting value for the @For(cntr := 1;
loop counter. cntr <=
condition—A true or false condition. @Elements(Options);
increment—A statement that changes cntr := cntr + 1;
the counter. @Prompt([OK]; "Item "
statement—A formula language statement + @Text(cntr) " is ";
to execute. Up to 254 statements can be Options[cntr]))
specified.
Elliott_05.qxd 9/14/06 2:27 PM Page 105
@While Executes one or more statements while the The following loops through
specified condition remains true. Syntax: the elements of a keyword
@While ( condition; statement ); field called Options. Each
condition—A true or false condition. element is displayed and a
statement—A formula language statement counter is incremented with
to execute. Up to 254 statements can be each loop.
specified. cntr := 1;
Note: There is also a @DoWhile statement, @While(cntr <=
which was introduced in release 6. @Elements(Options);
@Prompt([OK]; "Item "
+ @Text(cntr) " is ";
Options [cntr]);
cntr := cntr + 1)
@DBColumn Returns a list of values from a view or The following returns a list of
folder column. Syntax: values from column number
@DBColumn( class : cache ; one for the "By Category"
server : database ; view ; view.
columnNumber ) class := "";
class—The type of database being cache := "NoCache";
accessed. server := "";
cache—Specifies if the results should db := "";
be cached. view := "By Category";
server—Server name. Defaults to colnum := 1;
current server if set to "" in the statement. @DBColumn (class:cache;
database—Database name. Defaults to server:db; view;
current database if set to "" in the colnum);
statement.
view—The view name or alias name.
columnNumber—The column number
to return values.
continues
Elliott_05.qxd 9/14/06 2:27 PM Page 106
@DBLookup Returns a field value from a specified The following searches the view
document in a view or folder. Syntax: "By Last Name" for the key
@DBLookup( class : cache; value. If found, it returns the
server : database; view; first name for the document.
key; fieldName; keywords ) class := "";
-or- cache := "NoCache";
@DBLookup( class : cache; server := "";
server : database; view; db := "";
key; columnNumber; keywords) view := "By Last Name";
class—The type of database being key := "Elliott";
accessed. fieldName := "firstname";
cache—Specifies if the results should @DBLookup (class:cache;
be cached. server:db; view; key;
server—Server name. Defaults to fieldName);
current server if set to "" in the
statement.
database—Database name. Defaults
to current database if set to "" in the
statement.
view—The view name.
key—Unique key.
fieldname—Value to return.
columnNumber—The column number
to return values.
TIP
Best practices suggest that you should create temporary variables for
functions that require multiple parameters. This helps with formula
readability and helps ensure that you change the correct parameter if
the formula needs updates. Otherwise, you’ll need to remember (or
look up) what each parameter means and count semicolons to find the
parameter.
Where possible, you should limit the number of lookup functions included on a form.
Multiple lookup functions can affect the overall performance of the form.
However, if you need to retrieve multiple field values, consider creating a hidden view. Set
the first column to a unique key (such as a document number). In the second column, cre-
ate a formula that contains all data fields separated by a delimiter (such as the tilde ~). Then
using @DBLookup in conjunction with @Word, you retrieve multiple field values for a single
document using a single lookup.
Elliott_05.qxd 9/14/06 2:27 PM Page 107
For example, let’s say you have a service request form that requires the user to select their
immediate manager. Then, after the user selects a name, the manager’s email address,
department name, and phone fields automatically populate with the correct information.
In this scenario, you would do the following:
1. Create a form that contains manager name, email, department, and phone number.
2. Create a hidden view, such as (MgrLookup).
3. Set the view formula for column1 to MgrName.
4. Set the view formula for column2 to MgrEmail+"~"+MgrDept+"~"+ MgrPhone.
5. Next, add a hidden, computed field (such as MgrData) to the service request form.
Set the field formula to the following @DBLookup formula. This field will store a
"~"delimited list of values based on the selected manager name.
Class :=""
Cache:=""
Host := "";
View := "(MgrLookup)";
Key := MgrName;
Colnum := 2;
output := @DbLookup( class : cache ; host ; view ; key ; colnum );
@If(@IsError(output);"";@If (MgrName=""; ""; output ))
6. Finally, create the Email, Department, and Phone fields on the service request form.
Make each field computed. Using the @Word function, set the field formula for each
respective field. Be sure the form property is set to Automatically refresh fields.
@Word ( MgrData; "~"; 1);
@Word ( MgrData; "~"; 2);
@Word ( MgrData; "~"; 3);
Using this approach, three individual field lookups were replaced with one @DBLookup
function call. Note that Automatically refresh fields can also affect performance if there is
a significant number of computed fields on the form.
The following table summarizes the common functions used to manage dates.
continues
Elliott_05.qxd 9/14/06 2:27 PM Page 108
continues
Elliott_05.qxd 9/14/06 2:27 PM Page 110
The following describes several functions that can be used to display information to the
user. These functions will display a dialog box window. In some cases, information is static.
In other cases, the user can interact with the dialog box, and data values are returned to the
underlying form.
[AUTOHORZFIT]—Auto-set horizontal
size.
[AUTOVERTFIT]—Auto-set vertical size.
[NOCANCEL]—Do not display Cancel
button.
[NONEWFIELDS]—Do not create new
fields on underlying form if the field
does not already exist.
[NOFIELDUPDATE]—Do not update
fields on underlying form.
[READONLY]—Disable the ability to
edit content in the dialog box.
[SIZETOTABLE]—Auto-set size based
on the table.
[NOOKCANCEL]—Do not display the
OK and Cancel buttons on the dialog
box.
[OKCANCELATBOTTOM]—Place the OK
and Cancel buttons at the bottom of
the form. If parameter is omitted,
buttons will display on right side of
window.
title—The title of the dialog box
window.
@Prompt Displays a popup dialog box to the The following are several
user. This function can be used to examples.
capture data values or to capture the @Prompt ([OK]; "Warning";
result of a clicked button (i.e., OK or "You must specify a
Cancel). Syntax: request date");
@Prompt( [style] : [ NOSORT ] ; @Prompt ([YESNO];
title ; prompt ; defaultChoice ; "Continue?"; "Do you
choiceList ; filetype ) want to save this
style—A keyword that indicates what form?");
the dialog box should look like. Valid @Prompt ([OKCANCELEDIT];
keywords include the following: "Input"; "What is your
[CHOOSEDATABASE] name?"; );
[LOCALBROWSE] FIELD filename :=
[OK] @Prompt([LOCALBROWSE];
[OKCANCELCOMBO] "Select a file.";"");1
[OKCANCELEDIT]
[OKCANCELEDITCOMBO]
[OKCANCELLIST]
continues
Elliott_05.qxd 9/14/06 2:27 PM Page 112
[OKCANCELLISTMULT]
[PASSWORD]
[YESNO]
[YESNOCANCEL]
NOSORT—An optional keyword. Values
are sorted if this parameter is omitted.
title—The title of the dialog box
window.
prompt—The text to be displayed
within the dialog box.
defaultchoice—The default button
or choice in the dialog box.
filetype—The type of files to be
displayed. This parameter is only
required for the [LOCALBROWSE] style.
Formula Language unfortunately does not provide a user interface that allows developers to
debug or examine variables as a formula executes. However, the Designer client does auto-
matically check the formula syntax, which in many cases resolves problems with the
formula.
So the question then becomes, how do you debug a formula that meets the language syn-
tax requirements but that fails to produce the correct result? There are several approaches to
consider—periodically display values as the formula executes (using @Prompt) or periodi-
cally check results as the formula executes (using @IfError or @IsError).
NOTE
Links to developerWorks
A.5.1 Polly, Mark. Keyword magic for the Web. IBM developerWorks, October 2003.
http://www.ibm.com/developerworks/lotus/library/ls-keyword_pt1/index.html.
Elliott_05.qxd 9/14/06 2:27 PM Page 114