Locking-Down Your Domino Web Environment
-
Upload
dominion -
Category
Technology
-
view
648 -
download
4
description
Transcript of Locking-Down Your Domino Web Environment
© 2006 Wellesley Information Services. All rights reserved.
The Essentials of LotusScript
Debbie LyndWellesley Information Services
2
What We’ll Cover …
• Introducing LotusScript• Comparing LotusScript with the Formula Language
(@Functions)• Understanding and using LotusScript Domino classes• Using the LotusScript debugger• Writing the code• Where to put your code• Handling errors
3
The Hello World Program
• Objective:Write a program that displays:
Hello world.The LotusScript code:
Print "Hello world."• Result:
"Hello world." will show in the status barNot much, but it’s a start
4
The Program Explained
• Print "Hello world."This is a Print statement
• The word "Print" is also a LotusScript keywordA keyword has a reserved meaning within LotusScript that stands for a statement, built-in function, constant, or data type
• "Hello world." is a parameterIt tells the print statement what to printIt is just like the parameters used in @functions
Example: @StatusBar("Hello world.")
5
LotusScript Has Rules
• Just like the formula language, you can’t write LotusScript any way you want
• There are rules for the parameter you use with Print• From Designer Help you can see the syntax of all
LotusScript elements
6
Follow Print with an Expression List
• An expression is a valueIt can be a single value like 1, 2, or "Single Value"Or it can be a value that is calculated like (1 + 2) * 3.Or text can be combined like "Single" & " Value"
Note: When combining values in LotusScript,an ampersand is used; in the formula language,a plus sign (+) is used
7
LotusScript Also Has Functions
• A function is very much like an @functionIt takes some information, does something to it, then gives you (returns) a value
• For example, on my machineEnviron("CLASSPATH") returns the value:
C:\Program Files\Documentum\Shared\dfc.jar;Environ is the name of the function"CLASSPATH" is the parameterThis says: Tell me what the ClassPath is on this PC
8
EnvironmentInfo Agent
9
Variables Are Temporary Storage Areas
• With @functions, you often write code that isonly one line long
With LotusScript, you will probably never do this• Variables hold values in a storage area temporarily for
use in other statements and functions• This is the same in the formula language, but assigning
values works differentlyFormula language
TmpVar := “some value”LotusScript
TmpVar = “some value”
10
• A more flexible environment programEnvironmentVarName = "CLASSPATH"Result = Environ(EnvironmentVarName)Print Result
• This says:Store the word "CLASSPATH" in a temporary holding area called EnvironmentVarNameUse the value stored in EnvironmentVarName as the parameter for the Environ function, and store the result of the Environ function in a temporary holding area called ResultPrint the value stored in the Result holding area
Using Variables
11
Using Variables (cont.)
• Variables make it a lot easier to debug LotusScriptWith the LotusScript debugger, you can easily determine whether a variable contains the correct value
12
Rules for Naming Variables
• The first character must be a letter The rest of the name can be letters, digits, or an underscore
But NO spaces in the name• The maximum length is 40 characters
Case doesn’t matterEnvironmentVarName is the same as ENVIRONMENTVARNAME
Do not use any of the LotusScript keywords
13
What If You Forget and Use a Keyword?
• Designer won’t let you use a keyword as a variable name
When you try to save the code, it will raise an errorThe line with the error shows in redThe error message says "I didn't expect to see an = signafter the word Print. I was expecting either an expressionor nothing at all."
14
Use Descriptive Names
• When naming variables:iNumberOfUsers is better than "x"sUserName is better than "un"
• Some people like underscoressUser_Name
• Many people use a form of Hungarian NotationiVarName – integers start with isVarName – strings start with s and so on ...
• The choice is yours, but, whatever you choose, it’s important for you to be consistent and descriptive
15
Variables Have Types
• Variables hold the result of expressions• Expressions return different types of values• A variable must be prepared to hold the type of
value given to it• This is different from the formula language
With formulas, a variable can hold any type of data
16
What Types Can Variables Hold?
• Variable types include:NumericString (text)Boolean (true or false)There are many more, but these will do for now
• There is also the Variant typeThis is a special type of variable that can hold any typeof data – you need to use this type when you don’t havea clue what type of data will be returnedDon’t overuse as it consumes more memory
In the formula language, all variables are variants.
17
Setting Variable Types
• Use the DIM keyword to define a variable to holda certain type
The first line says: "Create a temporary holder called EnvironmentVarName and allow it to only hold data of the string type – just data that’s text."
Dim EnvironmentVarName as StringDim Result as StringEnvironmentVarName = "CLASSPATH"Result = Environ$(EnvironmentVarName)Print Result
18
DIM(ension) Statement Syntax
• DIM VariableName as typeType can be:
String (text)Integer (whole numbers only)Long, Single, Double (can have decimals)Variant (anything)
• Technically, you don’t need to use DIMIf you don’t, when you assign a value to a variable, LS creates the variable on the flyAll unDIMmed variables are variants
Variants take more memory
19
Using Option Declare
• Place Option Declare in Options section
• This will force you to always declare your variableswith a DIM statement
This will help you by catching typos in variables
In ND6, you can make Option Declare automatically appear in your code.Set in the Programmers Pane Properties.
20
Option Declare Is Your Friend
• Here’s why to use Option Declare:Note the typoBut here it is typed correctly
• Without Option Declare, you could get away with this (but your result would be wrong)
sEnvironmentVraName = "CLASSPATH"sResult = Environ(sEnvironmentVarName)
21
Let Designer Check Your Work
• With Option Declare, LotusScript will not let you save this code:
• You will see the following when you try to save:
22
Without Option Declare
• Without Option Declare, LotusScript will let yousave this code
• But when you run it, you’ll get:
• The typo would cause sEnvironmentVar tohave no value
• Environ expects one, so it chokes• Option Declare would catch the typo
23
Getting Input from the User
Sub InitializeDim sEnvironmentVarName As StringDim sResult As StringDim sPrompt As StringDim sTitle As StringDim sDef As StringsPrompt = "Enter environment variable name."sTitle = "Enter Name"sDefault = "CLASSPATH"
sEnvironmentVarName = Inputbox(sPrompt, sTitle, sDef)
sResult = Environ(sEnvironmentVarName)Print sResult
End Sub
24
Getting User Input: Agent UserInput1
25
Checking for a Blank Entry
• The code states that if there is nothing in sEnvironmentVarName
tell the userotherwise (else)
set sResult to result of Environ function
sEnvironmentVarName = Inputbox(sPrompt, sTitle, sDef)If sEnvironmentVarName = "" Then
sResult = "Variable name cannot be blank."Else
sResult = Environ(sEnvironmentVarName)End IfPrint sResult
26
If Statement Syntax
• The code below explained:1. "Something is true" is a condition
It is usually a comparison between two expressions2. This line is what happens if the condition is true
This can be, and often is, several statements3. This line begins the "otherwise" part (optional)
It says, if the condition is false, do the following4. Same rules apply as in #2
if Something is true thenDo something here.
elseDo something different here.
end if
27
If the Environment Var Doesn’t Exist?
• If the user types the name of an environment variable that doesn’t exist, no errors will be generated
sResult will simply contain a blank, which will be printedWhich is the same as nothing happening at all
• Let’s change sResult to give a slightly kinder message if the environment variable doesn’t exist
28
Getting a Little Friendlier
• The new lines with a red box around them place an if statement inside the original else clause
• This is perfectly legal and very common
sEnvironmentVarName = Inputbox(sPrompt, sTitle, sDef)If sEnvironmentVarName = "" Then
sResult = "Variable name cannot be blank."Else
sResult = Environ(sEnvironmentVarName)If sResult = "" Then
sResult = sEnvironmentVarName & " has no value."End If
End IfPrint sResult
29
Turning a "" into Friendly Text
• This says: If there is no value in sResult, make its value be what’s in sEnvironmentVarName plus "has no value."
• It’s okay to first look at and use the value in sResult, and then change it
If sResult = "" ThensResult = sEnvironmentVarName & " has no value."
End If
30
Making Input Friendlier: Agent UserInput2
31
Learning from Mistakes
• In programming with LotusScript, you can havethree types of errors:
Syntax errorsRun-time errorsLogic errors
32
Syntax Errors
• Syntax errors are the easiest to handle• A syntax error means you broke a basic rule
of LotusScriptDesigner will catch it and will not allow you to save your work
33
Sample Syntax Error
• The syntax error will be in red• The “Errors” box describes the error
String is missing quote at the end
34
Run-Time Errors
• Run-time errors are a little harder to catch• In a run-time error, basic syntax rules have
not been broken• Designer will not catch this kind of error and will
let you save your work• You won’t see the error until you run the program
Issue
35
Sample Run-Time Error
• Here is an error waiting to happenTest is a string and 10 is an integer
You can’t add two different data typesSame as the formula language
• This one is obvious but ...Type mismatches happen a lotThey can be difficult to debugMismatches happen a lot with Notes fields
Here’s the code:
vResult = "Test" + 10
Here’s the result when run:
36
Logic Errors
• Logic errors are truly your faultThe program runs exactly the way it is supposed to run
The problem is, the result is incorrectThese can be the most difficult to catch becausethey are often subtle
• Logic errors occur because you have incorrectly calculated something or have incorrect data
37
Sample Logic Error
• This code will run perfectly every timeBut, the result will be wrong twice a weekSunday is the first day of the week – day 1So, Friday is day 6, not day 5
Sub InitializeConst iFriday = 5Dim iDayOfWeek As IntegeriDayOfWeek = Weekday(Today)If iDayOfWeek = iFriday Then
Print "Hooray! It's Friday"Else
Print "Oh, it's not Friday"End if
End Sub GOTCHA!
38
Commenting Your Work
• It’s very good practice to use commentsYou don’t have to comment as much if you use descriptive variable names, but …
Commenting is very useful when you come back to your code after some time awayOr if someone else needs to modify your code
Do not fall into the trap of saying “Oh, this is just for my use.I don’t need comments.”Comments always save you time in the long run
39
Comments in LotusScript
• Commenting is simple – just put a single quote (') in front of something you want to comment
Example:' Last Edited By: Debbie Lynd' Date Created: 01/17/2005' Date Modified: 05/10/2005' Function: Day of Week Agent' Purpose: Shows day of week
Something like this is often put at the beginning of code
Best Practice
40
Where to Place Comments
• Comments can be on a line by themselves or can be placed at the end of any line of code
A block of comments before some complex code is often helpful:
' Find the number of users with more than' 100 hours of use' Then send nasty email
• Also consider commenting at the end of lines of codeDim iOverUsers as Integer ' Number of usersDim sUserName as String ' Individual user name
• You cannot put comments in the middle of a lineof code – only at the end
41
What We’ll Cover …
• Introducing LotusScript• Comparing LotusScript with the Formula Language
(@Functions)• Understanding and using LotusScript Domino classes• Using the LotusScript debugger• Writing the code• Where to put your code• Handling errors
42
The Major Differences and Similarities
• Assignment operators are different• Combining text is the same
But it can be a little different• If statements are executed in a different manner• LotusScript comments are easier• LotusScript code does not have to return a value• LotusScript allows looping
But, so does the formula language in ND6• You can’t use LotusScript with formula language• You can use some @functions in LotusScript
43
Assignment Operators
• Formula LanguagesTemp := "Test"
• LotusScriptsTemp = "Test"
44
Combining Text
• Formula LanguagesTemp := "Test " + "Run"
• LotusScriptsTemp = "Test " + "Run" orsTemp = "Test " & "Run"
• You can combine text with a + just like in the formula language, but …
Use of the & is considered better programmingIt makes it easier to see when you’re doing arithmetic or combining strings
45
If Statements – Very Different
• Formula Language @If@if(cond1;result1;cond2;result2;else result)
Allows several conditions to be tested with different results for each conditionReturns a value
• LotusScript IfIf condition then result else alternate resultOnly allows one condition to be tested at a timeHowever, result can be multiple lines without having to use something like @DoDoes not return a valueAlso, the else in LotusScript is optional
46
@If Compared with LotusScript If
REM "Formula Language";x := 10;sTemp := @if(x = 5; "Got It!"; "Try Again.");sTemp
' LotusScriptx = 10If x = 5 then
sTemp = "Got It!"Else
sTemp = "Try Again."End If
47
LotusScript Comments Are Easier
• Formula LanguageREM "sTemp := \"Test\""Have to escape the quotes
• LotusScript' sTemp := "Test"No escapes necessary
• Note: With the formula language in ND6 you can:REM {sTemp := "Test"}
48
Why Care About Comments?
• LotusScript makes it much easier to commentout your code
• If a block of code is giving you problems, justinsert ' in front of each line
That code won’t run• This is much harder in formula language
Although ND6 now makes commenting out your codeeasier by allowing braces to surround comments
Best Practice
49
Looping
• LotusScript allows you to perform many statements several times in the same code (looping)
• ND6 has looping in the formula language• We’ll examine LotusScript looping later
50
LotusScript in Formula Language?
• You cannot use LotusScript inside of an @function formula
• The closest you could come is to do an @Command([ToolsRunMacro] … and run a LotusScript agent
51
@Functions in LotusScript?
• You can use @Functions inside of LotusScript• Use the Evaluate LS function
vValue = Evaluate(|@Explode("one two")|)Msgbox vValue(0)
• Above example would show a message box with "one" as the message
52
The LS Evaluate Function
• Evaluate expects a parameter that is a valid @Function• The @Function has to be a LotusScript string (text)• The @Function is executed and returns its
value to Evaluate• The value is returned as a variant – which means it may
not be just one value, but a list• To read the first value, use vValue(0)
This is an array, which we’ll talk about later
53
What Can You Put in Evaluate?
• Evaluate will accept any valid @Function except:@CommandsAnything that actually shows a dialog box to the user (so no @Prompts)
• The @Function must be a valid LotusScript string so the | is often used for @functions that contain quotes:
Evaluate(|@Explode("one two")|)• The pipe symbol (|) can delimit LotusScript strings
54
Evaluate – Is It Worth It?
• There is almost always a LotusScript equivalent for what you want to do, but what’s easier
Learning how to write it with script, or using what you know?You want to use @DBLookup to find all values in a view that match a certain keyEvaluate would work, but so would db.searchin LotusScript
If pressed for time, don’t hesitate to use Evaluate, but you may find it is more trouble than it’s worth
It’s a lot harder to create the string to properly pass through than you think!
55
What We’ll Cover …
• Introducing LotusScript• Comparing LotusScript with the Formula Language
(@Functions)• Understanding and using LotusScript Domino classes• Using the LotusScript debugger• Writing the code• Where to put your code• Handling errors
56
LotusScript Domino Classes
• Allow access to all of the objects in an NSFViewsFormsAgentsEtc.
57
Some Demo Domino Class Code
' This code will print the common name of the ' current Notes user in the Status bar.
Dim sUserName as String
Dim session as New NotesSession
sUserName = session.CommonUserName
Print sUserName
58
Demo Code Explained
• Dim sUserName as String saysCreate a variable called sUserNameOnly allow string values to be placed in this holder
• Dim session as New NotesSession saysCreate a special variable called session
This kind of variable is called an objectWe don’t "put" anything in objects – instead, objects:
Already have things in them called propertiesCan also have things done to them called methodsCan also contain other objects
59
Introducing the Domino Classes
• Dim session as New NotesSessionNotesSession is a special variable type called a classA class is like a blueprint; it contains the plans for:
Other objects, properties, and methods When you create a new object based on the NotesSession class, it’s like you’ve added a whole lot of new parts you can use with LotusScript – these parts allow you access to Notes/Domino elements
60
Using New Parts of the Class
• A NotesSession object contains other objectsHas things you can do to it (methods)Holds certain information (properties)For example – A NotesSession object knows who is using the machine that is running the current script:
sUserName = session.CommonUserNameCommonUserName is a property of NotesSessionAccess it with: object.CommonUserName (dot syntax)
61
The NotesSession Class
• The NotesSession Class contains objects that deal with information that is not shown through the UI – it’s your portal to the back end
For example: You access a Notes document and its fieldsby starting with the NotesSession ClassCan’t you see a Notes document?
No – you view the data in a Notes documentthrough a formThe document is considered "raw" dataYou can create a new document without using the UI (without using a form)
62
Creating a New Document – No Form Needed
' This code will create a new Notes document.Dim session As New NotesSessionDim db As NotesDatabaseDim doc As NotesDocument
' Use the open database to create a document.Set db = session.currentdatabaseSet doc = db.createdocument
' Set the field values.doc.replaceitemvalue "Form", "SimpleDocDemo"doc.replaceitemvalue "FirstName", “Debbie"doc.replaceitemvalue "LastName", “Lynd"
' Save the document.doc.save True, True
63
Dissecting the Code
• The NotesDatabase Class – these lines say:Create an object called DB that will hold NotesDatabase stuff – just create a holder for the NotesDatabase for nowNow set the DB object to the database that is currently running this script – this makes all the objects, properties, and methods of this database available through the DB object
1. Dim db as NotesDatabase...2. Set db = session.currentdatabase
64
Dissecting the Code (cont.)
• The NotesDocument Class – these lines say:Create an object called "doc" that will be used to hold NotesDocument stuff – again, don’t put anything in the document yet – just create the holderSet doc to a brand new document by using the createdocument method in DB (NotesDatabase)
1. Dim doc as NotesDocument...2. Set doc = db.createdocument
65
Dissecting the Code (cont.)
• The ReplaceItemValue Method – these lines say:Create three fields on the new documentPut these values in the fields
Form: SimpleDocDemoFirstName: LarryLastName: Palm
All of these fields are created and filled with the ReplaceItemValue method of doc (NotesDocument)
doc.replaceitemvalue "Form", "SimpleDocDemo"doc.replaceitemvalue "FirstName", "Larry"doc.replaceitemvalue "LastName", "Palm"
66
Dissecting the Code (cont.)
• The Save method of NotesDocumentSave the new document using the Save method of doc (NotesDocument)For now, don’t worry about the true, true – they are parameters required by the doc.save method but don’t concern us here
doc.save(true,true)
67
Agent: SimpleDocumentCreation
68
Understanding the Object Model
• LotusScript is an object-oriented procedural programming language
Consists of classes …Which contain properties and methods …Which allow you to access and manipulate objects
69
Understanding the Object Model (cont.)
• Classes are divided into front-end and back-endFront-end classes access and manipulate objects in the UIBack-end classes access and manipulate objects from disk
• Classes are in a hierarchical containment modelYou MUST start at the top and work your way down
To open a view, you must first open the database that contains the viewTo modify a field, you must first open or create the document that contains the field
70
The Domino Classes Object Model
71
Domino Classes Use an Object Model
• You get to different Domino objects througha series of classes
To access a Notes document in the “back end,” youmust start with a session
NotesSession
NotesDatabase
NotesDocument
72
One More Example
• The NotesUIWorkspace deals with things yousee – the user interface
This code opens the Employees view
' This code will open the view called' "Employees" in the database the user is ' currently viewing.
Dim ws as New NotesUIWorkspaceDim db as NotesUIDatabase
set db = ws.currentdatabasedb.openview "Employees"
73
Two Main Portals into Notes
• NotesSessionAllows access to the back-end classesAllows you access to "raw" data and information notnormally viewed on the Notes workspace
• NotesUIWorkspaceAllows access to the front-end classesAllows access to what the user can seeYou can open forms and views and do many thingsyou can do from a keyboard
74
What We’ll Cover …
• Introducing LotusScript• Comparing LotusScript with the Formula Language
(@Functions)• Understanding and using LotusScript Domino classes• Using the LotusScript debugger• Writing the code• Where to put your code• Handling errors
75
Using the LotusScript Debugger
• The debugger is a great tool not just for debugging,but also for learning LotusScript
Don’t underestimate the debugger as a tool to help you learn Seeing how things are stored can be a great help while you are learning to program in LotusScript
76
Enabling the Debugger
• To enable the debuggerClick File --> Tools --> Debug LotusScript
• Turn it off the same way
You don’t see the debugger until you run a LotusScript routine.The message box only appears in ND6 – not before or after!In Release 7, the message appears in the status bar.
77
A Sample Debugger Screen
1. Run the script until it hits a bug2. Run the current line3. Run the current line and step over next line if it
calls a subroutine
78
A Sample Debugger Screen (cont.)
4. Run all the lines left in current subroutineUntil you hit an error
5. Stop running the script6. The current line
you are running7. The values of
variables in the script
79
Debugging Session
80
A Final Word on Debugging
• Disable the debugger when not usingOtherwise, the debugger will run when it sees any LotusScriptThis is very annoying – especially when you open help or mail
Heads Up
81
What We’ll Cover …
• Introducing LotusScript• Comparing LotusScript with the Formula Language
(@Functions)• Understanding and using LotusScript Domino classes• Using the LotusScript debugger• Writing the code• Where to put your code• Handling errors
82
Examples Using Domino Classes
• The rest of the session will be examples Sending mailPutting more than one item in a variable (arrays)Making work more readable with subroutines
Solutions
83
The First Domino Classes Example
• The first example will display:Notes User NameNotes VersionNotes Build VersionOperating System Platform
Solution
84
Set Up Constants
• Constants are variables that won’t changeYou can’t change them once they are defined
• Great for labels that will stay the sameMakes code more readableCode will be easier to maintain
' Set up some constants for labels.Const sTitle = "User Information"Const sUserNameLabel = "User Name: "Const sNotesVersionLabel = "Notes Version: "Const sNotesBuildVersionLabel = "Notes Build Version: "Const sPlatformLabel = "Platform: "
85
Set Up Variables
' Prepare variables for use.Dim session As New NotesSessionDim sUserName As StringDim sNotesVersionDim sNotesBuildVersion As StringDim sPlatform As StringDim sLine1 As StringDim sLine2 As StringDim sLine3 As StringDim sLine4 As StringDim sNewLine As StringDim sPrompt As String
*
*At first, the code in the box may seem like a lot of extra effort.Use of temporary variables like this will make your code more readableand easier to maintain in the long run.
86
Define the Newline Character
• This creates the code equivalent of pressingthe Enter key
Chr is a LotusScript functionParameter is ASCII code of the characterNew line character can be represented as a carriage return (ASCII Code = 13)
' Define a newline character for use in the msgbox.
sNewLine = Chr(13)
87
Get the Information
• The current session knows a lot about theuser and machine
• You can access session properties to get this information
• These are only four – there are lots more
' Grab the information from the session object.sUserName = session.UserNamesNotesVersion = session.NotesVersionsNotesBuildVersion = session.NotesBuildVersionsPlatform = session.Platform
88
Build the Lines to Show the Info
• The message gets put together hereNote the use of constants like sUserNameLabelLast line uses temp holders for code readability
' Put the information together in separate lines.sLine1 = sUserNameLabel & sUserName & sNewLinesLine2 = sNotesVersionLabel & sNotesVersion & sNewLinesLine3 = sNotesBuildVersionLabel & sNotesBuildVersion & sNewLinesLine4 = sPlatformLabel & sPlatform' Now put all the lines together.sPrompt = sLine1 & sLine2 & sLine3 & sLine4
Best Practice
89
Display the Information
• Msgbox is used all the timeBetter than Print (forces OK click)sPrompt = actual info in boxsTitle = title of dialog boxSecond parameter is optional
Leave a place for it (, ,).Controls look and message box behavior
' Show the information in a message box.
Msgbox sPrompt, , sTitle
90
You Won’t Find Msgbox in Help
• The actual LotusScript statement is:Messagebox
• You could use it in place of MsgboxHowever
Msgbox also works fine (it’s like an alias)Msgbox is more "standard" (that’s what VB uses)VB developers will laugh at you and kick sand in your face if you use Messagebox
Tip
91
Collecting User Information: Agent UserInfo1
92
Work a Little Smarter – Use With
' This code:sUserName = session.UserNamesNotesVersion = session.NotesVersionsNotesBuildVersion = session.NotesBuildVersionsPlatform = session.Platform
' Is identical to this code:With session
sUserName = .UserNamesNotesVersion = .NotesVersionsNotesBuildVersion = .NotesBuildVersionsPlatform = .Platform
End With
Functionality
93
The With Statement
• "With session" means everything between it and the "End With" will be using the session object
So, if a period (.) starts a property or method, assume that "session" is in front of the periodThe End With line is required and means:
Stop assuming "session" is in front of every period that starts a property or method
94
Mailing the Information
• A message box doesn’t do you much good. How doyou get the info?
You could:Have the user press Alt + PrintScreenCreate a mail memoPaste the screenshot in the memo(Right, that’ll work!)
Or you could:Have the information mailed right to you
Solution
95
Mailing the Information – The Main Code
' Important part of the new code. It creates a new Notes ' document, sets four field values to the information' that was either gathered from the session or set ' up in the code, and then mails the document.' Pay attention to this code, you will use it ' all the time.
Set db = session.currentdatabaseSet doc = db.createdocumentWith doc.replaceitemvalue "Form", "Memo".replaceitemvalue "From", sUserName.replaceitemvalue "Subject", sSubject.replaceitemvalue "Body", sPrompt.send False, sSendTo
End With
Reuse
96
Doc.ReplaceItemValue
• Once you have a Notes document object:doc.ReplaceItemValue, FieldName, Value sets the value of FieldName to Value
It’s like FIELD FIELDNAME := VALUEBut what if the document doesn’t have that field on it?This is a common question, but:
By using ReplaceItemValue, you have put the field on the document – it doesn’t need to be there ahead of timeThis is a way to create a document without using a form
97
Documents vs. Forms
• Document info can be shown with a form – a document is independent of the form in which it was created, so ...
When programmatically creating a doc you will often use:doc.ReplaceItemValue "Form", "Name of Form"
This is automatically done when a form is used tocreate a documentIt tells Notes what default form to use when the documentis actually opened for viewing or editing
98
Mailing a Document – More Details
• To mail a document, use:doc.send false, SendToFirst parameter is almost always false
Only set to true if you want to send the form with the document
The second parameter (SendTo) may be more than one person
Note
99
Mailing User Information: Agent UserInfo2
100
Working with More than One Object at a Time
• So far, we’ve looked at "straight-line" programmingLine 1, Line 2, Line 3, … Last Line
• Now, we’ll look at how to work with several Domino objects using the same code using a collection and looping
• We are going to write an Agent that looks at all databases on a local machine and returns the name and size of each database
Solution
101
Database Report – Set Up the Variables
' Set up variables.' NotesDbDirectory holds info on all DBs. ' Use "" to look at local machine.
Dim dbFiles As New NotesDbDirectory("")Dim db As NotesDatabaseDim lSize As LongDim sSize As StringDim sTemp As StringDim sDBFileName As StringDim sTitle As StringDim sLine As StringDim sNewLine As StringDim sTab As StringsNewLine = Chr(13)sTab = Chr(9) ' Chr(9) is a TAB character.
102
Database Report – The Main Code
' Put a blank value into sTemp. ' This will be used to "build" the information.sTemp = ""
' Get the first database in the dbFiles object.Set db = dbFiles.GetFirstDatabase(Template_Candidate)
' Cycle through each database, ' recording the needed information.While Not(db Is Nothing)lSize = db.sizesSize = Format(lSize, "###,###,###,###")sDBFileName = db.filenamesTitle = db.titlesLine = sFileName & sTab & sTitle & sTab & sSize & sNewLinesTemp = sTemp & sLineSet db = dbFiles.GetNextDatabase
Wend
103
sTemp = ""
• sTemp is a a temporary variableWe’ll use it to hold the info for all Databases It must start with a value, which we set to blankThen, we’ll add a line to it every time we get informationfor a new databaseThis technique is very common – you will use it all the timeNote: In pre-ND6 versions, you couldn’t do something like this with @functions, but in ND6 you can use the same technique
Reuse
104
Get the First Database in dbFiles
• dbFiles holds info about all DBs on the local machine• To get information for the first database in dbFiles:
set db = dbFiles.getfirstdatabase(Template_Candidate)This says: "Set a NotesDatabase object called db to the first database in the dbFiles object. We will then use the database to get information about it."Template_Candidate is a special constant – using it as a parameter will return all Notes databases, both .nsfs and templates on the user’s machine
dbFiles is called a collection, because it holds morethan one object
105
The While Loop Explained
• A While loop says:As long as this condition is true
Perform the statements below until you getto the W(hile)end
This particular loop says:As long as there is a database left to find, get the information about it and then repeat
While Not(db Is Nothing)' Get the information needed here ... ' Then get the next database in dbFiles
Set db = dbFiles.GetNextDatabaseWend
106
The Code Inside the While Loop
• This code is executed inside the while loop
lSize = db.size ' Get the size of the database.sSize = Format(lSize, "###,###,###,###") ' Put commas in number.sDBFileName = db.filename ' Get the full path and db name.sTitle = db.title ' Get the title of the database.
' The next line creates the info line. Data is separated by tabs and a carriage return (sNewLine is put at the end.sLine = sFileName & sTab & sTitle & sTab & sSize & sNewLinesTemp = sTemp & sLine ' Add info line to what's already in sTemp.Set db = dbFiles.GetNextDatabase ' Get the next DB in dbFiles.
107
Send the Email
• SendMail is a subroutineA subroutine is code you have written somewhere else that you can use later by writing one line
• sTemp is the list of database names and sizes created in the previous code
' Now send the e-mail.sSendTo = “Debbie Lynd"sSubject = "Local Database Info For: " & sUserNameSendMail sSendTo, sSubject, sTemp
108
Subroutines
• You never have to write subroutines• You can place all your code in the initialize event (or
whatever event you are using)There is nothing wrong with this if the code is fairly short
• However, subroutines …Break your code into manageable chunksAllow you to more easily reuse code
Reuse
109
SendMail Subroutine
Sub SendMail(sSendTo As String, sSubject As String, sBody As String)Dim session As New NotesSessionDim db As NotesDatabaseDim doc As NotesDocumentDim sCurrentUser As StringsCurrentUser = session.CommonUserNamesSubject = sSubject & sCurrentUser
' Rest of the code is the same code that sent the mail in other routines.' Clean up your objects.Set session = nothingSet db = nothingSet doc = nothing
End Sub
110
SendMail Subroutine (cont.)
Sub SendMail(sSendTo As String, sSubject As String, sBody As String)' ...' Clean up your objects.
Set session = nothingSet db = nothingset doc = nothing
End Sub
1. Start with Sub NameOfSubRoutine, then in parens, define the parameters that will be passed to the subroutine. The parameters are like Dim statements, just without the Dim.2. Set all objects created in the subroutine to nothing. (More on next slide.)3. End the subroutine definition with "End Sub."
111
Cleaning Up for Later Visitors
• Remember, objects already have a whole lot of other objects
When you create an object, all its elements areloaded into memoryWhen finished with the object, give the memory backSet session = Nothing says:
I no longer need this session object, so whatever memory was used by it can be used by others – this also means that it can’t be used in your script anymore
Insurance
112
If You Don't Set Objects to Nothing
113
Mailing Local Database Information: Agent DatabaseReport
114
Using Arrays
• So far, our variables have held only one value:
• But what if you wanted to do this:
sSendTo
"Debbie Lynd"
sSendTo
"Debbie Lynd and Russ Maher"
115
Using Arrays (cont.)
• Think of an array as one variable withseveral compartments:
• Compartments are numbered – start at 0• Refer to compartment as sSendTo(num)
sSendTo(0) = “Debbie Lynd"sSendTo(1) = “Russ Maher"
116
Setting Up an Array
• Dim sSendTo(3) as StringThis says: Set up a variable that can hold up tofour string valuesWhy four? Arrays start at zero
• Compartments in arrays can only hold the same type of data
For example, you couldn’t do this:sSendTo(0) = 3sSendTo(1) = "Debbie Lynd"
117
Sending Mail to Several People
• Just make sSendTo an array:Dim sSendTo(1) as String*sSendTo(0) = "Debbie Lynd"sSendTo(1) = "Russ Maher"...doc.send False, sSendTo
* Make the number be the number of people youwish to send to (minus 1)
Tip
118
What We’ll Cover …
• Introducing LotusScript• Comparing LotusScript with the Formula Language
(@Functions)• Understanding and using LotusScript Domino classes• Using the LotusScript debugger• Writing the code• Where to put your code• Handling errors
119
Branching out of Agents
• So far all code has been in Agents• But there are many more places where you can
put LotusScript code:ButtonsForm and View ActionsEvents
DatabasesFormsViews
Script Libraries
Decision Point
120
Creating a LotusScript View Action
• We’ll create a view action that:Reads fields and field values in the currently selected documentShows the fields and their values in a message box
• Create a view action normally• Select LotusScript for the language• Write your LotusScript code
121
Set Up the Variables
Dim session As New NotesSessionDim db As NotesDatabaseDim col As NotesDocumentCollectionDim doc As NotesDocumentDim sNewLine As StringDim sName as StringDim sValue as StringDim sTemp As String
122
The Main Code
Set db = session.CurrentDatabaseSet col = db.UnprocessedDocuments
If col.Count = 0 Or col.Count > 1 ThenMsgbox "Just select one document.",,"Select One Document."
ElseSet doc = col.GetFirstDocumentsTemp = ""Forall v In doc.ItemsSet vItem = vsName = vItem.namesValue = Cstr(doc.GetItemValue(sName)(0))sTemp = sTemp & sName & ": " & sValue & sNewLine
End ForallMsgbox sTemp,,"Fields on Document"
End If
123
Determining Which Doc Is Selected
• set db = session.currentdatabaseThe database where script is running
• set col = db.unprocesseddocumentsIn a view, this is all selected documents
• set doc = col.getfirstdocumentFinds first document in col collection
124
The Forall Loop – Something New
• Forall v in doc.Items says cycle through all items (fields) on the doc
v is a variant – becomes each individual itemAn item has a name (vItem.vname)doc.GetItemValue(sName)(0)
Finds the value of the item (field)Why the zero? Items are arrays – even single value onesCstr converts the value to a string so we can display in the message box
Forall v In doc.ItemsSet vItem = vsName = vItem.namesValue = Cstr(doc.GetItemValue(sName)(0))sTemp = sTemp & sName & ": " & sValue & sNewLine
End Forall
125
Forall Loop – A Little More Info
• Forall v in doc.itemsThe "v" is a variantIt was not DIMed – this is not a mistakeYou cannot DIM a variable you are going to use in a Forall loop – LS won’t let you
• Think of the v as an all-purpose holder that will become each individual element in the collection as you cycle through the Forall loop
• You can name v anything you want – v is traditional
126
Quick Info Action in the All View
127
Events
• Notes elements have things done to them• These things are called events• For example:
Databases, forms, and views are openedDocuments are deletedDocuments are pasted into views
• In many cases, you can write code to respond to:Before an event occurs (query)After an event occurs (post)
128
Database Events
• These are database events you can use:PostopenPostdocumentdeleteQuerycloseQuerydocumentdeleteQuerydocumentundeleteQuerydragdropPostdragdrop
• Remember:Query = beforePost = after
129
Database PostOpen Event
• Suppose you wanted to give a personal greeting to anyone who opens a database
You can:Place code in the Postopen eventCapture the user nameDisplay a friendly message box
This is just an exampleYou could have code selectively email to interested parties
130
A Friendly Greeting in PostOpen
Sub Postopen(Source As Notesuidatabase)' Note: You don't write the above line. It's automatic.Dim session As New NotesSessionDim db As NotesDatabaseDim sUser As StringDim sMsg As StringDim sTitle As StringSet db = session.CurrentDatabasesTitle = db.TitlesCurrentUser = session.CommonUserNamesMsg = "Hello, "&sUser&". Thanks for using this database."Msgbox sMsg,,sTitle
End Sub
131
Where to Find the DB Events
• R5 • ND6 and R7
132
Database Script Area
• Click on Event, then Write Code
133
Database PostOpen
134
Views and Forms Have Events, Too
• ViewsQueryopenPostopenQueryopendocumentQueryrecalcQueryaddtofolderQuerypastePostpasteQuerydragdropPostdragdropQuerycloseQueryentryresizePostentryresizeInviewedit
• FormsQueryopenPostopenQuerymodechangePostmodechangeQueryrecalcPostrecalcQuerysavePostsaveQuerysendPostsendQueryclose
Checklist
135
Denying a Paste Into a View
• Use the QueryPaste eventSub QueryPaste(Source As Notesuiview, Continue As Variant)
This line is written for youSource is the view you have openContinue allows the paste to complete or not – Set trueto complete, false to not complete
Solution
136
Denying the Paste
• The QueryPaste codeSetting Continue to False makes sure the pastedoes not succeedThe message box is just a courtesy to the user
Sub Querypaste(Source As Notesuiview, Continue As Variant)Const sTitle = "Cannot Paste Here"Const sPrompt = "Please don't paste into this view."Msgbox sPrompt ,, sTitleContinue = False
End Sub
137
An ND6 Extra – Editing in a View
• ND6 has the inviewedit event for views• Good news: You can add data without opening
the documentBad news: It’s not automatic
138
What We’ll Cover …
• Introducing LotusScript• Comparing LotusScript with the Formula Language
(@Functions)• Understanding and using LotusScript Domino classes• Using the LotusScript debugger• Writing the code• Where to put your code• Handling errors
139
Handling Errors
• LotusScript allows you to check for errors whilethe script is running
• This is good, for three reasons:Makes debugging easierAllows you to give friendlier error messagesYou can actually deal with errors that might be anticipated
Example: You might want to delete a file on the hard drive, but it might not be thereWith error trapping you can easily handle this – just ignore the error you get if the file isn’t there
140
On Error Goto XXX
• On Error Goto ErrorTrapTells LS, when you encounter an error, go to the areaof the script called ErrorTrap
• ErrorTrap:You designate the start of the area by typing the name you want followed by a colonEverything after that is considered in the ErrorTrap sectionErrorTrap: Is called a label
141
A Simple Error Trap Agent
• This code will try to delete a file called errtest.txton the C: drive
• If the file isn’t there, the code will be rununder ErrorTrap:
Sub InitializeOn Error Goto ErrorTrapDim sNewLine As StringDim sMsg As StringsNewLine = Chr(10) & Chr(13)Kill "c:\errtest.txt"Exit Sub
ErrorTrap:sMsg = "Error: " & Error & sNewLine & _"Line: " & Cstr(Erl) & sNewLine & _"Number: " & Cstr(Err)Msgbox sMsg,,"ErrorTrapDemo"Exit Sub
End Sub
142
Handling the Error
• If the file isn’t there, this code will ignore error:Sub Initialize
On Error Goto ErrorTrapDim sNewLine As StringDim sMsg As StringsNewLine = Chr(10) & Chr(13)Kill "c:\errtest.txt"Exit Sub
ErrorTrap:sMsg = "Error: " & Error & sNewLine & _"Line: " & Cstr(Erl) & sNewLine & _"Number: " & Cstr(Err)If Err = 75 Then
Resume NextElse
Msgbox sMsg,,"ErrorTrapDemo"End IfExit Sub
End Sub
143
LotusScript Error Functions
• ErrorReturns the current error messageIf no error, returns ""
• ErlReturns the line in which the error occurredIf no error, returns 0
• ErrReturns the error numberIf no error, returns 0
Functionality
144
Resources
• THE VIEW articleGary Devendorf, LotusScript for the Terrified — An Introduction for Non-Programmers(THE VIEW, June 2002).
• Steven Kern and Deborah Lynd, Lotus Notes and Domino 6 Development (IBM Press, 2003).
• MSDN.comMicrosoft, but has lots of coding examples for VB that are applicable
• Designer HelpTry this before you go anywhere else
Where to
FINDit
145
7 Key Points to Take Home
• You can use techniques from Visual Basicin LotusScript
• Don’t forget the LotusScript assignment operator is = (not the := of @Functions)
• Use Option Declare to ensure variables are spelled correctly
• Use the LS debugger to catch your errors andto learn about LotusScript
146
7 Key Points to Take Home (cont.)
• Use Arrays for related sets of variables• Place code in events in forms, views, and databases
to take advantage of built-in functionality• Use On Error Goto to trap your errors