Lotus Notes Insufficient Memory Too Many Design Elements
- Lotus Notes Insufficient Memory Too Many Design Elements Desk Design Pool
- Ibm Lotus Notes Insufficient Memory Too Many Design Elements
IBM Lotus Notes/Domino 8.5 Forum (includes Lotus Notes Traveler). Subject: Insufficient memory - too many design elements. 2 years but now we are receiving the. June 11th & 12th, Melbourne, AustraliaMeet.Share.Learn.Connect @AusLUG #@Inform2015 Compact Replication 'Unable To Extend an ID Table - Insufficient Memory” “Insufficient Memory”. Cause: – Many Adds and Deletes from the database Ie: log.nsf or high-touch business application. Usual workaround: – New Replica – New Copy. Lotus Notes access error: 'database is not opened yet' I have written Web services in Lotus Notes Domino R7, but receive the error, 'database is not opened yet' when trying to access the Lotus Notes database from another Domino server. My Web service is signed with the Lotus Notes ID to run a Web service or agent on the specified Domino server. I struggle with the concept of what is 'large' in Notes nsf application design elements as opposed to the amount of data or records stored. For example it is stated that we shouldn't have too many views, but 'too many' does not give any scale whatsoever, is it 10,50,100,500 before it 'slows down'.
Lotus Notes Performance TipsThis page contains a variety of Lotus Notes and Domino related performance tips, with links to additional information where possible. In particular, you should visit the links in the 'Required Reading' section of this page. Those pages and documents have a number of performance tips beyond what I mention here.
This is not supposed to be an exhaustive list by any means. Rather, it's intended to be a quick reference of things to keep in mind as you're designing a Notes application or setting up a Domino server. I also avoided giving any 'step-by-step' instructions on this page. If you need any help understanding the concepts I talk about here, the first place you should look is the Notes help files (both Domino Designer help and Domino Administrator help). If those don't give you enough information, please try searching the LDD forums.
For my general feelings about optimizing programs, please see my blog entry on the subject: 12 Thoughts About Making Code More Efficient.
Subdivisions of this Page
Database Tips
Server Tips
Notes Client Tips
Domino Server Performance Troubleshooting Cookbook (IBM Technote)
Domino 7 Performance Tuning Best Practices (IBM Redpaper)
Good tips in the classic Maximizing Domino Performance White Paper
Performance Considerations for Domino Applications
Some good Appendices in that Redbook:
- View Indexing Comparisons
- Fast Access to Reader Names Protected Documents
- LotusScript Versus Formulas (for simple document updates)
- Execution Order of Notes Form Events and Formulas
Tuning IBM xSeries Servers for Performance
Redbook with good generic information about Win2k and Domino tuning, not just on xSeries. One of the more interesting things they mention is that Domino works best with a disk stripe size of 16KB.
Rob McDonagh's e-Pro articles on improving Domino Performance:
part 1 and part 2
Not strictly about performance tuning, but there's a good technical article on the IBM site called Sizing your IBM Lotus Domino mail servers
Minimize Deletion Stubs
In a database that gets archived frequently, or that has a large number of 'temporary' documents that get removed on a scheduled basis, you can keep your database lean by reducing the number of deletion stubs it maintains.
You can use the 'Remove Documents Not Modified in Last X Days' setting in the database replication options to minimize deletion stubs in databases with a lot of deletions. Deletion stubs get purged at about one half the number of days specified in this setting, regardless of whether or not the setting is active (normally you do not want this setting to be active, but the number of days affects the deletion stub purge interval regardless).
Be Mindful of the Advanced Database Options in R5 and Higher
Notes R5 introduced a number of 'advanced' database options (available by going to the last tab on the 'Database Properties' dialog). Some of these options can affect the performance of your database if they're selected but not needed. The options are:
- Don't maintain unread marks
- Optimize document table map
- Don't overwrite free space
- Maintain LastAccessed property
- Disable transaction logging
- Don't support specialized response heirarchy
- Use LZ1 compression for attachments
- Don't allow headline monitoring
- Allow more fields in database
- Allow soft deletions
- Soft delete expire time
- Limit entries in $UpdatedBy fields
- Limit entries in $Revisions fields
For guidance, see Properties that improve database performance in Notes Designer Help, and Chapter 4 of Performance Considerations for Domino Applications.
Adjust Full-Text Index Options
Adjust the frequency of full-text index updates on large databases with many changes (set it to hourly or scheduled, if the database doesn't use the index very much). Also, skip indexing attachments unless necessary. For large or volitile databases this can alleviate work by the Indexer task.
Obviously, if you don't need to maintain an index on a database, you shouldn't.
Define Anonymous in the ACL
This is a pretty small performance gain, but you should always explicitly define the 'Anonymous' user access in the ACL of a web-enabled database. It's much more efficient for the database to find the Anonymous user directly in the ACL, instead of having to do a nested lookup through all the groups in the ACL to see if Anonymous happens to be defined there (especially if you're using LDAP). It also makes it easier to control the web access to your databases right from the start.
Limit Use of 'Strong Encryption'
Don't use 'Strong Encryption' on databases unless absolutely necessary, especially on high-use server-based databases. It adds a lot of overhead when the client has to keep translating everything in the database. If you must use database encryption, Medium and Low encryption have much less overhead. And you normally shouldn't have to encrypt a server-based database at all.
Minimize the Use of Reader Name Fields When Possible
Using reader name fields on many or all documents in a database with a lot of documents can significantly affect view performance, because the database has to evaluate the reader fields on a number of documents before it can even display a view. There's a good article on the problem and possible solutions on the LDD site.
In short, you should Categorize all your views if you're using Reader fields extensively on a database with many documents (and make sure that 'Collapse all when database is first opened' is checked, as it always should be). In ND6, I think you also need to have the 'Don't Show Empty Categories' option turned off for this to be effective.
In R5 and higher, you can also use 'single category' displays of the view on a Page or Form to help even further. In ND6 and higher, you can use the @SetViewInfo command to dynamically filter a view.
Watch Out for Private Views Stored on the Server
If you have Private on First Use views that are stored on the server, you can spike the server utilization if (A) the indexes are supposed to be refreshed automatically, (B) a lot of users have private views stored on the server, and (C) the database has many documents and gets changed often. This is because every time a change is made, the server will have to reindex all the private views (which could be in the hundreds for many users). The problem can be worse if the view and/or column formulas are complex.
There are also INI settings that will delay index updates, to temporarily alleviate this problem server-wide without having to delete and redesign existing private views (see the Maximizing Domino Performance White Paper for details)
Don't Use @Now or @Today in Views
Don't use @Now or @Today in a view selection or view column formulas if you can help it. This can cause views to be refreshed almost constantly whenever databases get changed or replicated, which can be a big problem on databases with a lot of changes. There is a lot of discussion about working around this issue on the LDD forums.
Create Special Views for Lookups
If you need to create one or more views for looking up data, use hidden views with few columns, no categorization, minimal sorting, and no complex formulas. The key is that you want your lookup views to have as little data (or data manipulation) as possible, and they should reindex very quickly.
Check Your View Index Sizes
For server-based databases, you can use the 'show database [dbname]' command at the server console to see how big the view indexes are. This can come in handy when trying to determine how complex your views really are, and what kind of impact they have on the database (you may be quite surprised at the index sizes on large databases with a lot of categorized views).
Evaluate Formulas Only Once
If many elements on your form rely on the same formula for lookups or hide-when fields, just process the formula once in a single computed (or computed for display) field and use that computed field value for the lookup/hide-when.
Along those same lines, if you have a large section of a form that needs to be hidden under a certain condition, consider using a computed subform instead of using a hide-when formula for all the different paragraphs.
(UPDATE: Andre Guirard wrote an interesting analysis of when using computed fields for this is and isn't a good idea, and also mentions that you can use shared profile documents as a way to improve speed for keyword lookups.)
Avoid WebQueryOpen Agents Whenever Possible
WebQueryOpen agents are notoriously slow, and even simple WebQueryOpen agents can cause a noticable delay in opening a form on the web. Avoid these when possible.
Avoid Large or Complex Tables
Large or complex tables can greatly affect the speed with which a form can be rendered (both in the client and in the browser). In particular, avoid tables with a huge number of rows, a lot of nesting, or a large number of hide-when conditions.
Learn How to Troubleshoot Agents
Before you do anything, you need to read Julie Kadashevich's article: Troubleshooting Agents in Notes/Domino 5 and 6. This has some excellent troubleshooting tips for server-based agents.
Avoid Reader Fields When Possible
Using Reader fields can slow down all of your document processing code across the board, because the database has to evaluate the reader fields for each document before it can even attempt to do anything with them. This is especially true when the agent signer doesn't have access to a large number of documents in the database, because the documents that aren't visible still have to be evaluated before they can be skipped.
Tips on Stepping Through Views
You often have to write code that 'steps through' the documents in a view in order to get something done. Here are some pointers for when you have to do that:
- set autoUpdate = False on the View/NotesView object whenever possible before you start processing
- use getNextDocument instead of getNthDocument
- when you're deleting a large collection of documents, use the removeAll method of DocumentCollection/NotesDocumentCollection whenever possible, even if you have to do a search (make sure the database is full-text indexed) or create a special view to create the collection
- beware using the allEntries property of View/NotesView in ND6, because it can cause crashes (see the LDD forums for evidence)
- when stepping through views in Java, use recycle() to free memory on the Document objects when you're done with them (IBM Technote 1097861 discusses this further)
Turn Off Remote Agent Debugging in ND6
Notes/Domino version 6 and higher gave you the ability to enable remote agent debugging. While this can be useful as a troubleshooting tool, you should make sure it's turned off when you're not testing with it. Remote debugging can cause agents to run much more slowly on the server.
Keep an Eye on Agent Schedules
Reduce the number of scheduled agents that run every 5 minutes or 'When new documents arrive'. For long-running agents that run once a day, don't schedule them at the same time, and don't run them in the middle of the day (when you can help it) or when server backups are taking place, or when nightly maintenance tasks (like Compact or Updall) are taking place.
If you want a quick snapshot of how many agents are currently scheduled on your server, enter a 'tell amgr schedule'
command at the server console.
Use DocumentCollections
If you're working with a large number of NotesDocuments, don't create an array or list of NotesDocument objects -- this uses a lot of memory. Either use a DocumentCollection/NotesDocumentCollection or create an array/list of NoteIDs and access the documents as needed using the NoteIDs.
Share NotesView References
If you need to use a reference to a view multiple times in your code, get the view only once and share the reference (either using a global or static variable, or by passing a NotesView object as a parameter in functions/subs/methods). Accessing views using getView is a very expensive operation.
Use Profile Documents Instead of Environment Variables
You should generally prefer profile documents to environment variables to store and retrieve user-specific information in a database. It's much more efficient (doesn't require file-system access), and the user information can stay persistent across mutiple workstations.
Use @Function Agents For Simple Document Modifications
If you just need to modify, add, or delete one or several [non rich-text] fields in all or selected documents in a view, it is much faster to use an agent with simple @Functions (rather than LotusScript or Java) that runs against all or selected documents.
Don't Use 'Print' So Much
Minimize the use of the Print statement when performing actions in long loops. If you feel obliged to inform the user of your progress, use something like:
to show what's going on. Printing a lot of messages to the status bar or console uses a surprising amount of memory, and it can have a noticible impact on an otherwise fast-running loop. Specifically, the memory used by each Print statement is not released until the entire agent is finished (see IBM Technote 1089676 for details).
Declare Your Variables
Declare all your variables -- and use something other than 'Variant' when possible. If you don't declare your variables, then LotusScript assumes everything is a Variant, which is not only a 16-bit variable (which is large in variable terms) but it has to be internally cast every time you want to access or compare it. For example, the loop:
runs much faster when 'i' is declared as an Integer or Long rather that a Variant.
Resume Out of Your Error Handling Blocks
Don't make your LotusScript error handling blocks GoTo another block unless that other block cleans up and exits the current routine. This is because the error handling block and everything that happens after it until you Resume or Exit actually operates within its own memory space. This can cause stack overflows if there are lots of errors and you end up in the error block multiple times (per Lotusphere session AD104: LotusScript Tips and Tricks)
Resize Arrays Infrequently
ReDim your arrays as infrequently as possible. However, if you have to append data to an array quite often, Redim Preserve is MUCH more efficient than many calls to ArrayAppend:
Try running the code above with and without Arrayappend and you'll see what I mean.
Don't Worry About NotesSession Objects
Don't worry about using:
in several places in your agents. The NotesSession and CurrentDatabase objects are static, so you can make those two calls as often as you'd like within your code without the performance penalty of creating a new object.
Store Values in Variables Instead of Using Extended Syntax Repeatedly
If you have to access an extended syntax value repeatedly, it's often more efficient to store the value in a variable first, and just keep accessing the variable. For example, the Designer Help says to use:
instead of:
if you're stepping through all the views in a database.
For Large Numbers Of String Concatenations, Use Join On An Array Of Strings
If you have to do many repeated string concatenations, you're generally better off storing all of the string fragments in a String array and then joining them all together. Notes 6 introduced the native Join function, which is a very fast way of doing this, although there are still ways you can add some efficiency in R5 and lower. See my LotusScript StringBuffer Class for an example.
Use Generic Java Performance Techniques
When you're optimizing your Java code for Notes/Domino, the first thing to do is to consider the same performance and optimization techniques that are used for generic Java code (like using StringBuffers instead of String concatenation, using Buffered streams and readers when possible, etc.). I won't even try to summarize those types of techniques here; rather, I'll point you to a few web sites that are good references:
Java Performance Tuning site:
http://www.javaperformancetuning.com
Jonathan Hardwick's Java Optimization site (old information, but still useful):http://www.cs.cmu.edu/~jch/java/optimization.html
Java Performance Tips on the Sun site:
http://developer.java.sun.com/developer/technicalArticles/Programming/Performance
Java Urban Performance Legends:
http://www-106.ibm.com/developerworks/library/j-jtp04223.html?ca=dnt-416
Java theory and practice: Garbage collection and performance
http://www.ibm.com/developerworks/library/j-jtp01274.html?ca=dnt-54
Excellent article on the cost of throwing exceptions, with some good links at the end:
http://www-106.ibm.com/developerworks/java/library/j-perf02104.html
Discussions of the performance implications of nullifying objects:
http://www-106.ibm.com/developerworks/java/library/j-perf08273.html
http://www.javaspecialists.co.za/archive/Issue060.html
PreciseJava.com (some good tips, but make sure you verify for yourself -- in particular, I did some testing with file buffering at one point and my results didn't match theirs):
http://www.precisejava.com
Articles on Notes-Specific Java Performance Tips
Here are some articles and discussions about Java performance that are Notes-specific:
IBM Technote about calling recycle():
http://www-1.ibm.com/support/docview.wss?rs=203&uid=swg21097861&loc=en_US&cs=utf-8
Colin Pretorius' findings about the need to recycle() when stepping through a DocumentCollection:
http://www.e-md.co.za/web/colin.nsf/plink/javaperf1.html
Make sure you use recycle() if you make a call to EmbeddedObject.getInputStream:
http://www.nsftools.com/blog/blog-11-2004.htm#11-03-04
Some warnings about being too liberal in your use of recycle():
http://www.nsftools.com/blog/blog-02-2004.htm#02-17-04
http://www.nsftools.com/blog/blog-02-2004.htm#02-20-04
Andrew Pollack's testing of the performance implications of reusing Sessions:
http://www.thenorth.com/apblog4.nsf/0/A653593BE7346C5985256EBC00545560
http://www.thenorth.com/apblog4.nsf/0/92CBF21B1D3AE44E85256EBC00545561
How to reuse Domino Sessions in Java Servlets:
http://www.davison.uk.net/domjavasessions.jsp
Nik Shenoy's comments about using static objects across multiple agents in Notes:
http://nik.shenoy.name/weblog/2004_03_01_thoughts.html#NIK-107817587025345744
How to use AgentRunner to debug your Java agents:
Nik Shenoy
Johan Känngård
Don't Use 'Print' So Much
Minimize the use of System.out.print. If you must output a large amount of data to the console, consider accumulating the data in a StringBuffer and dumping it periodically, or using something like log4j.
Consider Using Servlets
High volume agents that are triggered via HTTP might have better performance as servlets rather than agents. It's not always easy to tell when this will be true, but it's worth a look if performance is a problem.
Read the Server Performance Technote
Read through and understand the Domino Server Performance Troubleshooting Cookbook -- an IBM Technote with a great compilation of information.
Remove Unnecessary Server Tasks, and Tune the Ones that are Left
This is about the first thing everyone will tell you to do, but I'll go ahead and say it anyway. Check the server tasks that run either at startup or on a scheduled basis, and remove the ones you don't need. For example, an application server probably doesn't need to be running Chronos, POP3, IMAP, or LDAP.
With the tasks that are left, make sure they're properly tuned. Do you have an optimal number of Agent Manager or Replicator tasks running? Do you have multiple Mail.Box databases on your high volume mail servers? Is Updall or Compact still running when the users arrive in the morning? Make sure that your nightly maintenance tasks (Updall, Fixup, etc) aren't running while the server is being backed up at night -- that can corrupt your backups and cause the tasks to either fail or run very slowly.
Use Your Drives and Partitions Wisely
Make sure that the server is partitioned in a way that suits your applications. For example:
- Use separate logical drives for the OS, the Notes program directory, and the Notes data directory (when it's feasible, it's great to have your swap file on its own drive too)
- Don't ever put your program or data files on a network drive
- Don't ever put your program or data files in a compressed folder
Don't Virus-Scan Your Databases
Make sure that the virus scanner on your server is set to exclude your database files. Your databases are large and they change quite often, and a virus scanner that's trying to check those files every single time they're accessed or changed can kill your performance.
Some file extensions you might want to consider excluding are: .nsf, .ntf, .ndk, .box, .ndx, .dtf, or anything in a .ft folder.
Index Your Views on a Fast Drive with Lots of Space
You can use the VIEW_REBUILD_DIR setting in the Notes.ini file to specify which drive and directory Domino should use for temporary file creation as it's building view indexes. You should use a fast drive with lots of space.
Use a Fixed Swap File Size
By default, Windows (and maybe Linux) will set your swap file to be a minimum size, and allow it to grow as necessary. This can cause swap file fragmentation, and it's really unnecessary overhead for the OS to have to keep adjusting the swap file size. You're almost always better off specifying the same [large] number for the minimum and maximum size of your swap file, so the OS can use a fixed area on the hard drive for virtual memory management.
If you can, it's also good to defragment the drive your swap file will be on before you make this setting, so the OS can use a contiguous space for the file.
If You Want to Log HTTP, Log to a Text File
If you're logging HTTP access, use text logging instead of logging to a database. You can parse and view the text log files using any number of free and commercial products, and you'll avoid all the overhead of the domlog database.
In order to prevent the files from taking up too much space on your hard drive, you should set the log files to be recreated daily, and use the log file zipping technique in The Unfinished LotusScript Book to keep the old files organized and compressed.
Old Web Caching Tricks May Not Work Anymore
Be aware that many 4.6/R5 server web caching tricks were at least partially if not completely disabled in ND6. It probably won't hurt if you still employ them in your databases, but they may not function the way you think they will when you upgrade to ND6 or higher. There's a good explanation of this on the LDD ND6 forum, along with an IBM Technote on the subject.
Use the Latest ODS Version
Make sure that all the ODS versions of the databases on your server are at the same level as your server (don't worry, older clients will still be able to access them, and older servers will still be able to replicate). This is almost always more efficient.
Fine Tune Your Address Book for LDAP
For servers receiving LDAP requests, there are a few things you can do to make the incoming LDAP request processing a little more efficient:
- reduce the number of groups in the NAB -- especially the number of nested groups (because LDAP requests will have to recursively search through group nestings to determine if users are members or not)
- full-text index the Address Book that is handling the requests
If you're specifically having problems with LDAP, try some of the links on the Domino Directory FAQ.
Disable Reverse DNS Lookups
There's a setting in the server document that enables reverse DNS lookups -- this setting should be disabled. Trying to do a reverse lookup on all the clients that are hitting the server will only slow things down.
Use Network Compression
If your servers are running ND6 or higher, consider using server network compression when possible.
Use Transaction Logging
Using transaction logging can improve the performance of all the databases on your server (especially the high-activity ones), because it allows the server to batch-process all the database updates under certain conditions. See the Domino server administration help for more information.
If you haven't read it yet, you should take a look at the Tuning IBM xSeries Servers for Performance redbook. It's got an entire chapter on setting up Windows NT/2000 servers for Domino.
Only Use TCP/IP
By default, Windows Domino servers are sometimes set up with networking for both TCP/IP and NetBios. You should really only use the TCP/IP protocol on your servers, and disable the NetBios port if it's set (some security people would urge you to disable NetBios completely on your Windows servers, Domino or not).
Disable Services You're Not Using
Check the services that are started on your server, and make sure there isn't anything running that you don't really need. Indexer is a big one that should be disabled. You can also disable things like IIS and proxy server if they're not necessary.
Page File Settings on NT
Instead of repeating it here, I'll just point you to an LDD post that I made long ago with my thoughts on Windows page files:
http://www-10.lotus.com/ldd/46dom.nsf/0/eefe12664088bff585256a5f0067fa66?OpenDocument
Here are some general links for running Domino on Linux:
Also, just a side-note: I've heard before that a very common performance/scalability problem with Domino on Linux has to do with the number of file handles available on the server (both for root and the Domino server user). You can use the 'ulimit' command to adjust this. There should be information on this in at least one of the links referenced above. Otherwise, search the LDD forums.
Make Startup Faster
Here are a few things you can do to make the Notes client startup faster:
- Minimize the number of databases on your Welcome Page (if you're using a Welcome Page)
- Disable 'Check Subscriptions' and 'Scan for Unread' startup options in User Preferences
- Disable 'Replicate When Notes Starts' on Location document
Use Network Compression
If both your client and your server are running ND6 or higher, you can enable network compression to speed up communications. Note that this has to be enabled on both the client and the server.
Use CLIENT_CLOCK to Troubleshoot Database Performance
There is a Notes.ini file setting called CLIENT_CLOCK that shows what kind of Notes RPC traffic is going on between client and server when you're performing operations in a database. This can be very useful when trying to determine exactly what's taking so long when you're doing specific things in a database (like opening the database itself or creating a new document). The available settings are:
See Appendix B-8 of the Performance Considerations for Domino Applications redbook for more information on these settings. There's also a SERVER_CLOCK setting to do this sort of debugging at the server, but you probably don't want to use that -- lots and lots of logging.
Lotus Training Overview LotusScript is a BASIC derivative that uses many of the same statements and function names, so most developers will find it easy to understand and use without too much relearning. While this course teaches the basics of LotusScript, its primary emphasis is not on the language itself, but rather on how to use it to operate on Notes database, view, document, field, and ACL objects. With this knowledge, you will be able to develop powerful custom applications and extend the standard templates such as Mail or Discussion.
Lotus Training Course goals
In this course, you will learn how to: This course will teach you how to:
- use fundamental LotusScript language elements as you program and debug applications using Domino Designer
- use LotusScript in various Notes events to operate on objects in the Domino Object Model
- configure client, server, database, and document security mechanisms to allow LotusScript to operate
- reconcile LotusScript and Notes data types and validate user input
- design error handling routines to gracefully recover from runtime errors
- operate on new and existing documents as well as on collections of documents
- use messaging to send email, documents, and newsletters
- operate on the database ACL and develop an alternative user interface so users can more easily administer database security
- interact with users with both the primitive LotusScript and sophisticated Notes dialog boxes
- use Profile documents to store application and user-specific configuration settings
- develop custom procedures and classes and use Script Libraries to store and share commonly used procedures across design elements and applications
- develop server-based Agents that use LotusScript and Notes objects to process documents
- debug Agents using the Remote LotusScript Debugger, report errors to a log file, profile Agent performance, and work with your server administrator to develop application probes to monitor ongoing Agent performance
- operate on file system based text files
- generate MIME content that can be used to send formatted emails with intact HTML
- parse XML files to extract element data and attributes
- run procedures stored in Windows, Notes, and other product DLLs
- instantiate objects from other products such as Office applications, Windows Script Host, and Windows Management Instrumentation via COM to use their properties and methods.
This course is designed for Notes programmers well versed in using Domino Designer 8. It assumes that you have:
- extensive experience using Notes 8
- thorough knowledge of the Domino Designer 8 development environment, including Form and View design
- mastered the concepts covered in the Domino Designer 8: Basic Notes Applications course.
Though not required, experience in any event-driven or structured programming language is helpful in understanding LotusScript. If you have used LotusScript in other Lotus applications or have built applications using Microsoft® Visual Basic™, you will find that this course won't be repetitive as it focuses mostly on Notes objects.
This course is part of a series of Domino Designer 8 training courses. Follow these paths to master all aspects of developing applications using Domino Designer:
Domino Designer 8: Basic Notes Applications provides the base knowledge for this additional training:
Client Track
- Configure Domino to use DB2 as a database engine and build applications that access relational data, DB2 for Domino 8 Administrators and Developers.
- Specialize in programming Notes applications to respond to built-in user interface features, Domino Designer 8: Special Notes Features.
- Convert an application written for Notes clients to be used in browsers, Domino Designer 8: Basic Browser Applications.
- Provide data to cutting-edge Web applications, Domino Designer 8: Web Agents and Web Services.
Lotus Notes Insufficient Memory Too Many Design Elements Desk Design Pool
- Learn sophisticated application techniques that fully exploit the formula language in Domino Designer 8: Formula Language.
- Develop sophisticated applications and Agents with LotusScript in Domino Designer 8: LotusScript.
- Add powerful client-side scripting to browser applications in Domino Designer 8: JavaScript.
This is a lecture/lab course in which you will closely examine demonstration code and create additional code. You will immediately apply the concepts and techniques as you work in your own project database.
This is not an introductory programming course. Its emphasis is on how to use LotusScript to manipulate Notes objects. All major concepts are reinforced with examples and exercises, during which you will code and debug LotusScript. From this experience you will have the necessary skills to build sophisticated applications.
All code fragments are labeled to make talking about them and reusing them in exercises easier. The intent in labeling them is also to help build a sense of modularity, purpose, and a way of 'thinking' about LotusScript.
Lotus Training Course duration
4 days
Lotus Training Course outline
- Topic 1: LotusScript in Notes and Domino
- What is LotusScript?
Advantages of LotusScript for Notes/Domino
When to use LotusScript
Where the code runs
LotusScript respects security
What LotusScript cannot do
Limits and performance
Other resources
Topic 2: Lotus Notes Events
- Event-driven language
Enter LotusScript code
Automatic code completion
Programmers Pane properties
Print code
Syntax errors
Compile and test the code
Exercise: Create button event script
What is the sequence of events?
Exercise: Experience the event model
What happened? Create document events
Query what? Post what?
Recalculate document event
Save document event
Close document event
Switch modes events
Read document events
Agent events
Database events
View events
Field events
Topic 3: Debugging
- Script errors
Remark code
Script Debugger
Find errors
Debugger Buttons
Debugger tabs
Exercise: Use the Debugger
Exercise: Break points
Persistent breakpoints
Debugging with Msgbox and Print
Topic 4: Language Fundamentals
- Basic language rules
MessageBox parameters and return values
InputBox
Variables
Declare variables
Advantages of explicit declaration
Global variables
Exercise: Global variables
Constants
User-defined data type
Statements and functions
Exercise: Experience LotusScript functions
String functions
Math functions
Date functions
Data type conversion
Boolean operators
How Designer Help helps
Platform considerations
Topic 5: Program Control Structures
- Program structure
Experience control structures
Branching structures
Exercise: Branching structures
Looping structures
Looping performance
Code benchmarking
Exercise: Looping
How to exit a structure
Break out of an endless loop
Exercise: Exit a structure
Topic 6: User Input Validation and Error Handling
- Check for empty variable
Failure to exit loop
Check data type
Other data type tests
Exercise: User input validation
Error handler
Resume after error
Goto after error
Resume 0
Specific error number handling
Reverse engineer Err codes
Error cases
Exercise: Error handling
Multiple error handlers
Error handlers and the Debugger
Topic 7: Domino Object Model
- What is an object?
Object class properties and methods
Domino Object Model
Back-end vs. Front-end classes
Back-end object classes
Front-end object classes
How Designer Help helps
Topic 8: Notes Object Instantiation
- Object instantiation steps
How to instantiate an object
Container objects
Object reference variables
Best practice: Use generic object names
Access current database using back-end methods
Best practice: Use constants
Use Domino Designer 8 Help
Exercise: Object containers
Access other databases using back-end methods
Access other database on server
Exercise: Instantiate object in another database
Best practice: Public declarations of Notes objects
Notes object properties
Read object property
Set object property
Chain/pipe references
'With' statement
Notes object methods
Run Notes object methods
Three types of methods
Exercise: Open method
LotusScript is not a keystroke macro language
Interact with users via front-end methods
Exercise: Open database for user
Delete object reference
Topic 9: NotesSession Object Operations
- Session properties
NotesName object class
NOTES.INI access
Data type assignment from environment
Exercise: Set environment
Topic 10: NotesDatabase Object Operations
- Paths to instantiate NotesDatabase
Select and open database
Ways to create a new NotesDatabase object
Is the database really open?
Open database on servers
Exercise: Database Info
Iterate data to look for a database
NotesReplication class
Exercise: NotesReplication class
Open database for user in UI
Open a database by property
Error handling when opening databases
Exercise: Find database
Create non-replica database copy
Who can create a database?
Copy documents to new database
Exercise: Database Copy
Error handler review
Create replica copy
New database from template
ACL of new database from using template
Delete database
Case Study
Topic 11: New Document Object Operations
- New document (back-end)
Security issues with back-end methods
Document properties
Exercise: Create Document (back-end)
New document using Form (front-end)
Security issues with front-end methods
Exercise: Create NotesUIDocument object
Topic 12: NotesItem Object Operations
- Create a new item Option 1: Extended class syntax
Data type of a new item
Create a new item Option 2: NotesItem object New method
Item properties you can set
Create a new item Option 3: Document object method
Create a new item Option 4: AppendItemValue method
Read item values Option 1: Extended class syntax
Read item values Option 2: NotesItem object Values property
Read item values Option 3: Use GetItemValue method
Modify existing item values
Best practice: Be sure an item exists before using it
Access system fields
Read all items
Remove item
Exercise: Manipulate NotesItem objects
Challenge Exercise I: System Inventory
Objects required for Challenge Exercise
Pseudocode for Challenge Exercise
Topic 13: UI Object Classes
- NotesUIWorkspace object
Close method
NotesUIDocument object
Instantiating the current UI document object
Front-end UI methods
Back-end to front-end interaction
Example of back-end to front-end interaction
NotesUIDocument limitations
Using the 'Source' object reference variable
Instantiating container object
Exercise: Flip-Flop via back-end methods
Exercise: Flip-Flop via front-end methods
NotesUIView object
Refresh a View
Topic 14: Notes Data Validation
- Form translation and validation
Check empty object
Example: Check empty object
Check for empty item (Field)
Example: Check for empty item (Field entry)
Accessing fields in a Form
Field focus
Simple Field validation
Exercise: Item validation
Compute with Form
Continue variable
Example setting Continue I: Stop a Form from closing
Example setting Continue II: Require Action Button clicks
Stop users from deleting documents in folders
Stop users from pasting documents
Topic 15: Multi-Value Items and Arrays
- Array basics
How to declare an array
Assign values to an array
Split
Join/Implode
Read single array element value
Iteratively read array elements
Examples of object properties returning an array of values
Find an array element
Replace values in an array
Replace
Determine the number of elements in an array
Remove blank elements
ArrayUnique
Dynamically sized array
Create copy of an array
Erase array values
Exercise: Dynamic array
Append one array to another array
Multi- dimension arrays
Items and multi-value Fields
Variable assignment
Testing equivalence
Read an array of strings or array of objects?
Get multi-value Field in current document
Set multi-value Field in current document
Append to existing multi-value Field
Exercise: Translate a multi-value Field
More on 'Item' versus 'Field'
Sort array
Challenge Exercise II: System inventory
Arrays and performance
Lists
Topic 16: Date-Time Operations
- How time is handled
Date and time in LotusScript
NotesDateTime object
Date/Time parameter format
NotesInternational object
Topic 17: RichTextItem Object Operations
- Rich Text programmatic issues
Instantiate NotesRichTextItem object
Accessing existing NotesRichTextItem objects
Things you can add to Rich Text item
Append text
Append spacing
Append character styles
Best practice: Style arrays and subs
Append doclink
Exercise: Formatted Rich Text
Append file attachment
Detach attachment
Append another NotesRichTextItem
Abstract text
Navigate through the elements in a Rich Text item
Insert object into existing Rich Text
Example: Append and populate table
Reopen document to show Rich Text
NotesUIDocument techniques to work with Rich Text Field
Validate Rich Text entry
NotesRichTextItem object Update and Compact methods
Challenge Exercise III: System inventory
RTF versus MIME
Topic 18: Collections of Document Objects
- Work on existing document(s)
NotesDocumentCollection object
Security issue
GetNextDocument requirements
Exercise: Loop through NotesDocumentCollection
Solution: Loop through NotesDocumentCollection
Add or remove documents from a collection
AddDocument and DeleteDocument method tricks
Bulk changes to document collections
Security issues with StampAll and RemoveAll
Other collections of document objects
Sort a collection
Collections and performance
Topic 19: View-Based Document Object Collections
- NotesView object
Exercise: Loop through NotesView
Solution: Loop through NotesView
NotesDocument object ColumnValues property
Primary key and View concerns
Get a document or document collection by View key
Example: Build a collection by View key
Process descendent documents
Iterate all levels of a document hierarchy
Sibling documents
Access a documents parent document
View.EntryCount property
NotesViewEntryCollection object
NotesViewEntry and NotesDocument objects
Exercise: Status summary
Solution: Status summary
NotesViewNavigator object
Topic 20: Search-Based Document Collections
- Collection from GetModifiedDocuments method
Collection by Full Text Search
The query
Search items using [FIELD]
Search on special items
Full Text Search options
Use the results
About the accuracy of Full Text Search
Refine an existing collection
Exercise: FTSearch Summary
Solution: FTSearch summary
Collection by ordinary Search
Change a View Selection Formula
Exercise: Search summary
Solution: Search summary
Search method performance
Switch search methods on-the-fly
Domain Search
Code the FTDomainSearch method
Topic 21: Unprocessed, Selected, Unread Documents
- Unprocessed documents
Unprocessed documents and user interaction
Efficient processing by Agents
Unprocessed flag and Agents
Unprocessed search accuracy
Exercise: Unprocessed documents
Documents highlighted and/or selected in a View
Unread documents
Topic 22: Existing Document Object Operations
- Make a copy of the current document
Delete a document
Security issues
Exercise: Archive selected documents
Delete open document
Test for locked document
Lock document
Does the document really need to be saved?
IsDeleted and soft deletes
IsValid document? IsDeleted document?
Is document open in the UI?
Open user-selected document
Put document in Folder (back-end)
Put document in Folder (front-end)
Exercise: Put document(s) in Folder
Remove document(s) from Folder
Remove all Folders
Remove only personal Folders
Make Response document
Topic 23: Newsletter Object
- NotesNewsletter object
Create newsletter object
Exercise: Newsletter report
Case study: Custom search Form
Optional exercise: Order report
FormatDocument method
Topic 24: Messaging
- Send document
Example Agent
Send method parameters
Source database
Read the Directory for user mail information
Change the apparent sender name from Notes
Change the apparent sender name from an Agent
Prevent Agent mail 'ping-pong'
Exercise: Send message
Optional properties and Fields
Exercise: Status Checker Agent
Solution: Status Checker Agent
Challenge Exercise IV: System inventory
Programmatically send Sametime instant messages
Topic 25: Evaluate @Functions
- Which @Functions cannot be used?
Why evaluate @Functions in LotusScript?
Evaluate syntax
Sum two Fields
String functions
Uppercase Field
@Functions outside of object context
Sum an array
Lookups
Exercise: Using @Functions
Performance implications
Topic 26: Dialog Boxes
- OpenFileDialog
SaveFileDialog
Prompt
Choose Database dialog box
PickListCollection
PickListStrings
Exercise: PickListStrings
Free Time dialogs
Folder dialog
DialogBox
From where you can call the DialogBox method
Status information
Case study: Bring the data here
Topic 27: Database Access Control List
- Minimum access requirements
Best practices
Find a known ACL entry level
Name storage in the ACL
ACL level constants
Iterate ACL entries
Other ACL permissions
Resolve group or Organization wildcard name
Why control the ACL with LotusScript?
Add an ACL entry
When to save ACL changes
-Default- special handling
Exercise: Set ACL
Change the level of an entry
Rename an entry
Delete an entry
Exercise: ACL control
Set permissions
Set entry type
Add a Role
Associate an entry with a Role
Role resolution
Disassociate entry from Role
Rename Role
Remove a Role
ACL and replication
ACL, your Domino administrator, and company policy
Topic 28: Profile Documents
- What Profile documents are used for
The nature of Profile documents
Profile document security and replication
Create Profile document
Back-end method to access Profile document
Read profile Fields
List Profile documents
Delete Profile document
Topic 29: Procedures and Script Libraries
- Advantages of using procedures
How/where to define procedures
Function procedures
Call a function
Single function argument
Pass an array as an argument
Multiple function arguments
Example: ConvertTemp function
Example: ReplaceSubstring function
Exercise: Value translation
Exit a procedure
Sub procedures
Example: Sub procedure
Pass argument by reference
Pass argument by value
Script Libraries
Use 'LibraryName' statement in Options
Exercise: Use a Script Library
Resource strings
Script Library tips
Recursion example: Process all child documents
Recursion example: Find root parent document
Recompile all LotusScript
%Include LSS file
Topic 30: Custom Classes
- Custom classes
Derived classes (inheritance)
Memory management
Example: Custom helper class
Advantages of object-oriented programming
Learn more about custom classes
.LSO files
.LSX files
Topic 31: Server-Based Agents
- Create new Agent
Trigger
Target
Document selection 'event'
Unprocessed documents
Before New Mail Arrives trigger
Agent security
Handling UI method errors in Agents
DelayUpdates property for Agents
Pass arguments at run time
Work queue architecture
Usage guidelines
Topic 32: Agent Logging, Profiling, and Debugging
- Domino Server Log
Private Agent log
Custom Agent Log
Agent performance and Agent Profiling
DDM Application Probes
Remote LotusScript Debugger
Topic 33: Text File Operations
- Write to a text file (Output)
Read lines from a text file (Input)
Read performance
Delete a file
Example: List Databases to File
Exercise: Append to text file
Export records to text file
Easy comma delimited export
Import records from text file
NotesStream class
Open, write to, and close NotesStream object
List databases example
MIME in email messages
Agents and MIME/HTML
Topic 34: XML Processing
- What wont be covered
NotesDOMParser and NotesDOMDocumentNode classes
Example XML file
Walk DOM Tree
Exercise: Correlate XML file to walkTree report
Create Notes documents from XML
Open a NotesStream to a URL
Topic 35: Call DLL Procedures
- Declare DLL procedure
Call the DLL Procedure
Caveats and tips
Win API: GetFolderName
Win API: Read/Write INI file
Win API: Get registry value
Notes API: Close any Notes window
Notes API: Run file from Notes
Other DLL examples
Resources
Topic 36: Use Other Product Objects
- Component Object Model (COM)
Instantiate Excel objects
Start and stop an application
Product object hierarchy
Access the object methods and properties
Where to find object data files
Example 1: Create Excel object from file
Example 2: Create new Excel object and set formula
Example 3: Create new Excel chart object
Example 4: Export View to Excel
Example 5: Create new Word object
Example 6: Create new Word object (labels)
Compound Document Container
Example 7: Work with embedded object
Notes and OLE
Example 8: Create OLE object in PostOpen event
Troubleshoot OLE problems
Example 9: Operate on attachment
Windows Script Host (WSH)
Windows Management Instrumentation (WMI)
COM access to Notes objects
Buy versus build
Lotus Symphony