lotusphere 2007 ad506 intermediate lotusscript
DESCRIPTION
TRANSCRIPT
®
AD506 - Intermediate LotusScript
Exploiting the power of LotusScript to deliver real world solutions
John P M Dillon
Software Application Architect
Teledyne Scientific & Imaging, LLC(and crazy rally codriver, Widget Rally Team LLC)
Slides revised 1 Jan 7
22
AgendaIntroduction and definition of bonus material
Start your evaluation now
Working with objects using the object modelProperties, methods, and events
Working with collections of stuff
Lists
Script Libraries
Questions
(Demo: Turn off cell phone)
33
About the Speaker
“New timer” compared to some folks here!
First used Notes version 3Led deployment team for Notes 4.5Began developing applications in Notes 4.6Our current environment is ND6.5 (Wintel)
We are not just what we do, but what we’re passionate about, so you’ll see pictures of me in a race car throughout the presentation
NOT directly related to the material, but the cars are pretty!
Rally racing is like Lotus Notes – it’s collaboration and teamwork in remote places with excellent performance
44
Shameless Plug:Please Visit Our Team’s SponsorsMost speakers are consultants and advertise themselves
I’m an employee, so I’ll advertise our team’s sponsors instead!
Perforce Software: www.Perforce.com/wrt
Shults Dot Com: www.shults.com
Porterfield Brakes: www.porterfield-brakes.com
Scott Roofing Company: www.scottroofingco.com
Widget Rally Team: www.WidgetRacing.com
55
Bonus Slides and Demos
There’s more information here than can be presented in a single session
Slides marked as “BONUS” will not be covered during the presentation but are included here as—well, as a bonus—for your benefit
Think of it as getting more than what you paid for
If there is time at the end or during Q&A I’ll answer questions about the bonus material
Or ask me at one of the lunches or social gatherings
66
BONUS: What We Advertised, What We Promise
This is the session description as shown on the Lotusphere site
As a newer programmer, you understand the basics of LotusScript and application development. Now you want to go the next level, learning how to read and effectively use the object model, how to exploit the power of lists, how to work with various types of collections, and how to take advantage of many different events and objects. This session covers it all, and in conclusion you'll see how you can package your code into script libraries for better configuration management.
77
Understanding the Object Model
The object model is key to writing useful, efficient, effective code
It looks really confusing but …
You can actually follow it pretty easily if you know where to start
We’re talking about the LotusScript model today, but these techniques work for other models as well
88
BONUS: Object Model (poster)
99
BONUS: Object Model (on line)
1010
How to Read It
Each box represents a type of object
Example: Here’s aNotesDocument (from Help)
This shows connection points to the object
If you’re using the electronic version, clicking on the box will describe the properties, methods and events
1111
Additional Features of the Paper Copy
The wall chart shows additional information
Properties
Methods
Events
Parameters and return values
1212
Properties
What are properties?
In the simplest form, they are pieces of information associated with the object
Ex: Database has a “Title” property, which is a string value containing the database’s title
Properties are sometimes read-only, but often editable
1313
Methods
Methods describe things you can do to, with, or from the objectExample: the NotesDocument class has a ReplaceItemValue method which defines the value of a field within the document
Methods often require parametersExample: the ReplaceItemValue method takes two parameters
The name of the field (as a string)The value to be placed in the field (any type)
1414
Events
Properties and Methods are heavily used – we’ll see a lot today
Events can be thought of as “triggers” associated with a particular object
Examples: Field object has an Exiting eventForm object has a QuerySave event
Events can be useful places to put code
Many objects don’t have events associated with them
1515
Sounds Cool, But How Do I Use It?
The model helps you understand what objects you’ve got to define (instantiate) in order for your code to work
As you poke around the model, you’ll also discover other features you might not have considered
1616
What to Instantiate?
Question: How do I know what things I need instantiated when looking at an object?
Answer: Follow the container stream until you get to a session oruiworkspace object
Example: Given that you need a handle to a NotesDocument
1717
Step 1: Locate the Object
1818
Step 2: Examine “Contained By”
In on-line help, see that a NotesDocument is “contained by” a database, doc collection, etc
This means you need one of these in your code
1919
Step 3: Pick the Parent Container
What are our choices again? database, newsletter, ui doc, view, view entry
How do we choose which one?Depends on how we expect to locate the document
Are we seeking it by key or search?Are we processing all docs in a view?
For our example, let’s assume we’re working with a document in a view
2020
Step 4: Examine the Parent’s Containers
We’ve decided we’re getting our doc from a view, so we need to instantiate a NotesView object
Go back to the chart and find its parent containers
Views are contained by databases and ui views
2121
Step 5: Keep Repeating Until You Encounter a Session or Workspace
In our example, we’ll choose a NotesDatabase
From database we’ll choose NotesSession
2222
Step 6: We Reach the Top
In this case we selected a NotesSession
Notice the documentation doesn’t show “contained by”
2323
So Now What?
For our example, we’ve determined we needNotesDocumentNotesViewNotesDatabaseNotesSession
Start by declaring variables for these objects
Next, instantiate them from the top downSessionDatabaseViewDocument
2424
Example code – nothing fancy here
Dim db As NotesDatabase ' it’s goofy, but these are sorted
Dim doc As NotesDocument ' just a personal preference to help
Dim session As NotesSession ' find variables in the debugger
Dim view As NotesView
' instantiate our variables from the top down
Set session = New NotesSession
' get a handle to this database
Set db = session.CurrentDatabase
' get a handle to the view
Set view = db.GetView( "Dept" )
' get a handle to the document
Set doc = view.GetFirstDocument()
(Object Demo 1)
2525
A Quick Comment About Scope
Global scope – variable is visible across the entire agent
Local scope – variable is visible only within the function, subroutine or class
Whenever possible, use local variables
Beware of global and local variables with the same name – you’ll get tangled up for sure, and have unpredictable results
A good reason to identify global variables with a “G” prefix
2626
Front End and Back End Classes
The “Front End” classes represent UI objects, such as the current workspace, the current document, etc
“Back End” classes are the underlying elements and can be handled without user interaction
Front end objects offer handles to their back end equivalents, such asuidoc.Document
You can get tangled up, but if you keep your eyes open for a “ui” prefix you’ll be okay
2727
Testing for UI capability
If you’ve got multi-purpose code that might sometimes run in a scheduled agent, test for ui, as in this “InitGlobalVariables” function
Set session = New NotesSession
GboolLocal = Not session.IsOnServer
If GboolLocal Then ' if running local, set UI stuff
Set uiws = New NotesUIWorkspace
Set uidoc = uiws.CurrentDocument
End If
' if a uidoc was open, point doc to it
If Not ( uidoc Is Nothing ) Then
Set doc = uidoc.Document
End If
2828
Events
You might think of them as “triggers” for code
2929
Using Events to Trigger Actions
Lots of events are available in Notes
Here are a few useful ones
Forms:QueryOpenPostOpenQuerySavePostSaveQueryModeChangePostModeChange
Fields:EnteringExiting
3030
Events – Simple Example
If someone clears a check box, you want to erase a bunch of related valuesDim uiws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Set uidoc = uiws.CurrentDocument
' if we're shipping to the billing address, clear
' the shipping fields
If uidoc.FieldGetText( "ShipToBillingAddress_TX" ) = "Yes" Then
Call uidoc.FieldSetText( "ShipToAddress_TX", "" )
Call uidoc.FieldSetText( "ShipToCity_TX", "" )
Call uidoc.FieldSetText( "ShipToState_TX", "" )
End If
(Demo: Create Form CR0)
3131
Exiting Event – Fancy Example
Given a names field, you want to auto-populate several fields based on person’s name in NABSub Exiting( Source As Field ) ' some code missing for clarity
' custom class for handling person objects
Dim coP As co_Person
Set coP = New co_Person( Gdoc.Employee_NA( 0 ), GcoNABInit )
Call Gdoc.ReplaceItemValue( "Phone_TX", coP.OfficeExtension )
Call Gdoc.ReplaceItemValue( "Dept_TX", coP.Department )
Call Gdoc.ReplaceItemValue( "IAddr_TX", coP.InternetAddress )
Call Gdoc.ReplaceItemValue( "Manager_NA", coP.Manager )
End Sub
Anyone see a potential problem with this approach?
(Demo: Create Form CR1)
3232
So What’s the Obvious Problem?
If they save the doc without exiting the field, the updates don’t happen!
So how do you work around it?
Consider using the code in the Form’s QuerySave event too
But wait, doesn’t that mean we’re maintaining code in two places?
Ah hah! A segue to script libraries!
(Demo: Create Form CR2)
3333
Store Most of Your Code in Script Libraries
Storing the guts of your code in a script library makes it accessible from multiple agents and events
It also makes configuration management simpler
(Demo: Create Form CR3)
3434
Script Libraries and Agents
Most of my agents are stored in script libs
Usually we have timed/manual versions of the agents
This reduces the effort of signing agents after enabling, since all the code can be signed without affecting a scheduled agent
3535
Script Libs – Great for Scheduled Agents
REMEMBER – Scheduled agents can’t use front end classesThere is no “front end”, e.g., no user interaction
Get rid of references to uidoc, uiws, etc
OR
Set a flag variable to detect whether running locally or on a server and handle ui variables accordingly (like GboolLocal shown earlier)
3636
Scheduled Agents – Suggestions
Put the guts of the agent in a script library, leaving the agentonly with a single call
Create a manually triggered version of the agent (again using a single call)
Suppress most print statements except for debugging –these can flood the log
Use your GboolLocal variable to selectively enable print statements (provides ui pacifier)
3737
Collections
Let’s face it, we like to collect stuff!
3838
Collections
There are a lot of “collections” out there
Document collections
View Entry collections
Access Control Lists (ACL)
Even fields are arrays of values, e.g., collectionsYou can get even more complicated, with multiple items mapped toa single array value
3939
Basic Document Collections
Let’s look at a simple collection firstExample: We want to process all the docs in db
' Dims and initialization skipped for clarity
' a collection of everything in the database
Set dc = db.AllDocuments
' get handle to first doc in the collection
Set doc = dc.GetFirstDocument()
' Now need to examine each one, so loop through collection
Do While Not (Doc Is Nothing)
' do real work here, but for now just show us the UNID
' working with all docs you'd probably use conditionals too
Print doc.UniversalID
' get handle to next doc (note it requires current reference)
Set doc = dc.GetNextDocument( doc )
Loop
(Collection Demo 1)
4040
Creating a Collection of Fewer Docs
The previous example works, but could take a while and is usually unnecessary
If we only want some documents, there are better ways
Get all the documents in a view (rather than the database)Get selected documents in a view Get data from a view entry collectionUse search method to get all docs based on criteria
4141
Working With All Docs in a View
' get a handle to the view
Set view = db.GetView( "Company" )
' get handle to first doc in the view
Set doc = view.GetFirstDocument()
Do While Not ( doc Is Nothing)
' do real work here, usually with function
Print doc.LastName_TX( 0 )
Set doc = view.GetNextDocument( doc )
Loop
NOTE: Avoid using GetNthDocument()
(Collection Demo 2)
4242
Getting a View Entry Collection
Better still, use a ViewEntryCollection
Useful if the view contains all the data you need No need to open the document
NOTE: Multiple values in a field can be more problematic
4343
Using a View Entry Collection
' get a collection of all entries in the view
Set vc = view.AllEntries
' get handle to first entry in the collection
Set ve = vc.GetFirstEntry()
' Now need to examine each one
Do While Not (ve Is Nothing)
' as before, do real work here
Print ve.ColumnValues( 0 )
Set ve = vc.GetNextEntry( ve )
Loop
(Collection Demo 3)
4444
Comparing Doc Collections to View Entry Collections
Document CollectionsWorks with database and other objectsRarely in the order you expectGets you directly to the documentsDon’t necessarily require intermediate views
View Entry CollectionsWorks with viewsPreserves current sort orderFaster – IF the document data you need is in the view (in columns)Problematic if dealing with multi-value data
4545
Lists
Not only do we like collecting stuff, we like making lists of the stuff we have
or want
4646
Lists – Useful Bits
To assign (or reassign) a value to an item in a list, specify the item with a tag, then the value
strMyList( “JOHN” ) = “Today’s Speaker”
To empty a list completely, use EraseErase strMyList
To delete one entry from list, also use EraseErase strMyList( “JustThisOne” )
To get the list’s tag (index), use ListTag()strTag = ListTag( varSomeListValue )
4747
List – Usage
Assigning a value to a listDim strInstrumentList List As String
strInstrumentList( "JOHN" ) = "Rhythm Guitar and Keyboards"
strInstrumentList( "PAUL" ) = "Left-handed Bass Guitar"
strInstrumentList( "GEORGE" ) = "Lead Guitar"
strInstrumentList( "RINGO" ) = "Drums"
Reading a valuePrint strInstrumentList( "GEORGE" )
returns "Lead Guitar“
(List Demo 1)
4848
Working with Lists
By themselves, useful, but ….
Real value is working with batches of values
Example – show all tags and their values:Forall strI In strInstrumentList
' get the tag associated with this value
strName = Listtag( strI )
' show it on the status bar
Print strName & ": " & strI
End Forall
(List Demo 2)
4949
Working with Lists – Error Handling
Often you need to check that a list and/or a tag exists before calling it
IsList() : used to see if the variable is a list
IsElement() : used to see if the specific tag is in the list
Example: See if the job list has a value called “default”If Iselement( strJobList( "default" ) ) Then
Print "Default job is " _
& strJobList( "default" )
End If
5050
Using Lists for Counting
Counting bins of unpredictable data
Given:Person docs in NAB has department numberNumber and makeup of department numbers keeps changingYou want to know how many people are in each department
(List Demo 3)
5151
Working with Lists (Example 3)
Dim lngDeptList List As Long ' list of longs
' get handle to first document
Set doc = view.GetFirstDocument()
' for each doc in view
Do While Not doc Is Nothing
' get the dept value -- assume only one
strDept = doc.Dept_TX( 0 )
' ===============================================
' Here's the important bit
' ===============================================
' increment counter for this specific dept
lngDeptList( strDept ) = lngDeptList( strDept ) + 1
' get handle to next document so we can repeat process
Set doc = view.GetNextDocument( doc )
Loop
5252
Lists of Objects
Lists don’t have to contain “ordinary” things like strings and numbers
You can have a list of objects
The list tag, however, is still a string
(Maybe Skip: List Demo 7)
5353
Lists – Example Using Lists with Field Names
Wanted: custom button for “cloning” an existing document
Creates a new document, with selective fields copied over
Example: Purchase Requisition, where you want to buy more of the same stuff but need to reset purchasing information
5454
Lists – Cloning Example
' Copy the field values from old to new doc
Forall strF In strXfrFieldList
' get the field name as the tag, though it could be as a value
' if that's how you chose to set up the list
strFieldName = Listtag( strF )
' copy the field value from current to new
If docCurrent.HasItem( strFieldName ) Then
Call docNew.ReplaceItemValue( strFieldName, _
docCurrent.GetFirstItem( strFieldName ) )
End If
End Forall
(List Demo 8)
5555
Lists - Positives
An intuitive alternative to arrays in many ways
Don’t need to predefine size
Uses text “tags” for indexing instead of numeric subscripts
Usually easier to read
5656
Lists - Negatives
Single-dimension only – arrays can be multidimensionalThere is a trick using Split() to work around it, sort of
Text tags can complicate things when you’re looking for numbers
Don’t work directly in fields – must convert to array first
Lists aren’t sorted, but are stored in tag creation order
5757
What We Covered
Objects, the object model, properties, methods, and events
Working with collections of stuff
Lists
Script libraries
Lots of code
5858
Please Fill Out an Evaluation Form – Thank You!
Session: AD506
Title: Intermediate LotusScript
Speaker: John Dillon
But wait, there’s more!
Bonus MaterialOther relatedsessions this weekReferencesQuestions
5959
Related Sessions Still AheadAD301 – How to Use IBM Lotus Notes and Domino Calendar and Scheduling in your Applications
Youcef Bennour – Wed 11:15
AD505 - DevBlast - 30 LotusScript TipsBill Buchan – Wed 1:30
AD507 - Leveraging the Power of Object Oriented Programming in LotusScript
Jens-B. Augustiny and Bill Buchan – Wed 4:15
AD303 – Extreme Makeover – IBM Lotus Domino Application EditionRay Bilyk – Thu 8:30
6060
6161
Useful References and Utilities
Debugging LotusScriptwww-128.ibm.com/developerworks/lotus/library/ls-DebuggingLotusScript_1/
ClipMate – www.ClipMate.com
Ytria – www.Ytria.com
Teamstudio – www.TeamStudio.com
Using the object-oriented features of LotusScriptwww-128.ibm.com/developerworks/lotus/library/ls-object_oriented_LotusScript
6262
Contact the Speaker
John @ WidgetRacing.com
www.WidgetRacing.com
jdillon @ teledyne.com
www.teledyne-si.com
There may be updates to these slides. If so, find them here:
www.WidgetRacing.com/ls2007/ad506.zip
6363
Bonus Material – Classes
This information was added during the presentation at the request of the audience, so I’m adding a few slides here to match
We like that “Object Oriented” thing
6464
Creating Your Own Class
Classes are odd puppiesLive in the declarations sectionClass-related functions/subs also live here, not easily visible like regular code
Start by defining the Class with a Class statement
Then define any class-wide variables
Then define subroutines and functions within the class
6565
Creating Your Own Class
Remember to include:
“New” sub (for creating new objects based on the class)
“Delete” sub (for handling the destruction of the object)
Functions to return the attributes
Note: Unlike some other languages, you can’t overloadLotusScript classes
6666
Class Example
We have a co_Person class in the demo db
When you instantiate an object of this class, you pass in a person’s name and a custom co_NAB_Initializer object
The object then has several attributes you can use, such asManager’s nameName in Last, First formatDepartmentPhone numberFoundInNAB flag – very useful!
6767
Without the Gory Details
Here’s how to use this custom class' some code missing for clarity, including coNABInit definition
Dim coP As co_Person ' an object using custom class
strName = Gdoc.Employee_NA( 0 )
Set coP = New co_Person( strName, coNABInit )
Print "Looking up phone number and other information for " & coP.Common & " ... "
If coP.FoundInNAB Then
Print "Name in Last, First format: " coP.LastFirst
Else
Messagebox strName & " not found in NAB", 64, db.Title
End If
6868
But Where Do Custom Classes Live?
Generally in a script library
In declarations for agent or form using the class, add:
Use “Person Lookup Class"
6969
Bonus Materials – Collections
7070
BONUS: Getting A Collection by Searching
All docs by search
strReturn = “BROWN”Set dc = db.FTSearch( strReturn, 0 )
Caveats:Full Text Indices are useful and usually requiredNo pacifier is displayed while searchingOften you’ll want to build a dialog box, then build your search string from the user’s input
(Collection Demo 4)
7171
BONUS: Getting A Collection by Key
All docs in a view by key
strReturn = “BROWN”Set dc = view.GetAllDocumentsByKey( strReturn, False )
Caveats:Same as before, plus…View-specific, not database-wideLooks in first sorted column (unless multiple-value key array is used)
(Collection Demo 5)
7272
BONUS: Getting Selected Documents
If you want to manually choose which docs to process, use db.UnprocessedDocuments() method
Note that it’s a database method, not a view method
Note the agent target must be set to “All Selected Documents” as shown
7373
BONUS: Getting Selected Documents (code)
' yes, “UnprocessedDocuments” means “SelectedDocs”
Set dc = db.UnprocessedDocuments
Set doc = dc.GetFirstDocument()
Do While Not (doc Is Nothing)
' do real work here
Print doc.LastName_TX( 0 )
Set doc = dc.GetNextDocument( doc )
Loop
(Collection Demo 6)
7474
BONUS: Deleting a Document While Looping Through a Collection
What happens when you attempt to delete a document while
walking through a
collection?
ADT error as shown
Work around is to get a handle to the next document before deleting the current
(Collection Demo 7 and 8)
7575
Bonus Materials – Lists
7676
BONUS: Lists – Setup
Initialize with Dim statementDim strValueList List as String 'list of strings
Dim varValueList List as Variant ' variants
' a list of rich text style objects
Dim styleValueList List as NotesRichTextStyle
etc
NOTE: variable naming is up to you – our naming convention says to append “List” to the variable name so we can tell what it is at a glance
7777
BONUS: Variations on the Bin Counters
Instead of using documents, use view entries(List Demo 4)
Instead of using documents, use categorized view entries(List Demo 5)
Instead of using view entries, use view navigator(List Demo 6)
7878
BONUS: Lists – Converting to Arrays
Sometimes you need to convert a list to an array
Usually for storing the values into a multi-value field
Function CreateArrayFromInput() in demo database you can use
7979
Bonus Materials – Objects
8080
BONUS: A Couple of Shortcuts
You can dim and instantiate some objects in one step, most commonly session and uiworkspace
Dim session As New NotesSession ' note New constructor
8181
BONUS: Object Variable Not Set
We hate these, don’t we?
Run in debugger to see which object is not set
Usually it’s a sequence problem, like trying to get a view before you’ve defined the database
Whenever possible, include your own error trapping
(Object Demo 2)
8282
BONUS: One More Very Common Error
Field values are generally arrays, even if there’s only one
This error comes from a lotof different ways, but verycommon problem is forgettingthe subscript to a field value
strValue = doc.LastName_TX
often should be
strValue = doc.LastName_TX( 0 )
(Object Demo 3)
8383
BONUS: When Do I Need to Use “Set” for Assigning a Value to a Variable?
Rules of thumb:
If you’re working with an object itself, use Set
If you’re working with an object’s property, don’t
If you’re working with a “regular” variable (strings, integers, etc), don’t
Set view = db.GetView( "Dept" )
db.Title = "Advisor Examples"
lngCount = 4903
strMsg = "Okay, I’m done"
8484
BONUS: UI or not UI?
When working with a document, view, database or workspace currently presented to the user, you’re working with UI objects like uidoc,uiview, etc
LS methods for manipulating UI (front end) objects rarely match those for back end objects
Each has value
Often we work with both simultaneously
8585
Bonus Materials – Script Libraries
8686
BONUS: Creating a Script Library
Look under Shared Code – Script Library
Insert the functions and subroutinesMy personal preference, everything
is a function
If necessary, use global variables in declarations, but this can bite you if you’re not careful
Try to avoid it
If you must, then document thereasons
8787
BONUS: Using a Script Library
Add a “Use” statement in the declarations
Try to keep the libraries stand-aloneNot always possibleIf one library requires another, it must be listed in the library’s declarations just as if it were an agentExample: Notifications lib needs DBObjectVariables
Agent has two declarations, in this order
Use "DBObjectVariables"
Use “Notifications“Notifications library has one declaration
Use "DBObjectVariables"
8888
Bonus Materials – Arrays
8989
BONUS: Arrays
Collection of values stored in a single variable, numerically indexed
Can be static or dynamic
Can be multi-dimensional (3 x 3 array, for example)
Most values in a field are stored as an array, even when there’s only one value
9090
BONUS: Working with Arrays
Dim them firstI usually dim them without size, then redim them to the size we need when we know it
Redim changes size
Redim Preserve is useful, but can be slow with large arraysConsider whether it’s really the right approachMost useful for small numbers of elements
(Array Demo 1 and 2)
9191
BONUS: Creating Arrays with Split()
Useful for taking a well-formed string of multiple values, such as a comma-separated string, and putting them into an array
Most commonly used when importing data from flat files
Syntax: Split( string, separator )
(Array Demo 3)
9292
Please Fill Out an Evaluation Form – Thank You!
Session: AD506
Title: Intermediate LotusScript
Speaker: John Dillon
Questions?(and maybe answers!)
9393
© IBM Corporation 2007. All Rights Reserved.
The workshops, sessions and materials have been prepared by IBM or the session speakers and reflect their own views. They are provided for informational purposes only, and are neither intended to, nor shall have the effect of being, legal or other guidance or advice to any participant. While efforts were made to verify the completeness and accuracy of the information contained in this presentation, it is provided AS IS without warranty of any kind, express or implied. IBM shall not be responsible for any damages arising out of the use of, or otherwise related to, this presentation or any other materials. Nothing contained in this presentation is intended to, nor shall have the effect of, creating any warranties or representations from IBM or its suppliers or licensors, or altering the terms and conditions of the applicable license agreement governing the use of IBM software.
References in this presentation to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. Product release dates and/or capabilities referenced in this presentation may change at any time at IBM’s sole discretion based on market opportunities or other factors, and are not intended to be a commitment to future product or feature availability in any way. Nothing contained in these materials is intended to, nor shall have the effect of, stating or implying that any activities undertaken by you will result in any specific sales, revenue growth or other results.
Performance is based on measurements and projections using standard IBM benchmarks in a controlled environment. The actual throughput or performance that any user will experience will vary depending upon many factors, including considerations such as the amount of multiprogramming in the user's job stream, the I/O configuration, the storage configuration, and the workload processed. Therefore, no assurance can be given that an individual user will achieve results similar to those stated here.
All customer examples described are presented as illustrations of how those customers have used IBM products and the results they may have achieved. Actual environmental costs and performance characteristics may vary by customer.
IBM, the IBM logo, Lotus, Lotus Notes, Notes, Domino, Domino.Doc, Domino Designer, Lotus Enterprise Integrator, Lotus Workflow, Lotusphere, QuickPlace, Sametime, WebSphere, Workplace, Workplace Forms, Workplace Managed Client, Workplace Web Content Management, AIX, AS/400, DB2, DB2 Universal Database, developerWorks, eServer, EasySync, i5/OS, IBM Virtual Innovation Center, iSeries, OS/400, Passport Advantage, PartnerWorld, Rational, Redbooks, Software as Services, System z, Tivoli, xSeries, z/OS and zSeries are trademarks of International Business Machines Corporation in the United States, other countries, or both.
Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.
Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both.
Intel and Pentium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries.
UNIX is a registered trademark of The Open Group in the United States and other countries.
Linux is a registered trademark of Linus Torbvalds in the United States, other countries, or both.
Other company, product, or service names may be trademarks or service marks of others.
All references to Acme, Renovations and Zeta Bank refer to a fictitious company and are used for illustration purposes only.