Note ID Uniqueness
Tracking Notes Users at the Notes Server Console
Setting Up Web Server Logging
JS32.DLL Error Upgrading Domino Server
Notes Client Command-Line Options
Reporting a Bug in Notes
Modifying $FormulaClass in Views
Getting Default Elements in the Database
Notes Debug Flags
Exporting Notes Documents and Rich Text Fields in RTF Format
Encryption Techniques in LotusScript
How to Extract LotusScript from a DXL Document
Java Server Addin for Domino
Java Sample Code Database
Automatically Restart Domino When It Crashes
Format LotusScript as HTML, RTF
Display Views in "Tree View" Format on the Web
Java RichTextOutputStream Class
LotusScript Agent to Convert HTML Tags
Recompiling Agents When Script Libraries Change
Performing a Stubless Delete Using LotusScript
Games for Lotus Notes/Domino
Export Docs From An MS Office Library
Convert Notes Documents and Rich Text Fields to HTML
Play a WAV File in a Rich Text Field
Output Your Notes Calendar As A Web Page
Convert CSV Files To XML
Check For Valid XML Characters
LotusScript StringBuffer Class
Lotus Notes Web Datepicker
Setting Up Repeating Dates In Notes
Converting Winmail.dat Files In Your Mail
Using AWStats To Report On Domino Web Logs
LS2J Examples Database
Google Suggest-type Lookups In Notes
LotusScript Class To Get Unread Docs In A Database Or View
Running a View Action Against Selected Docs
Append a Button to a Rich Text Field
How to write a LotusScript Singleton
Managing Zip Files in Lotus Notes
Get Selected Docs in a View Using the Notes API
Note ID Uniqueness
August 31, 2002
Here's a nice little table showing the way that the various Note and Database IDs change for a given Note or Database across different versions:
ID Type | All DBs | Note Revisions | DB Replicas | Notes DB Copies | OS DB Copies |
---|---|---|---|---|---|
Database ID | unique | n/a | different | different | same |
Replica ID | unique | n/a | same | different | same |
Unique ID | unique | same | same | same | same |
OID | unique | different | same | same | same (w/o revision) |
Note ID | not unique | same | different | same | same |
GNID | unique | same | different | different | same |
IID | not unique | different | different | different | same (w/o revision) |
giid | unique | different | different | different | same (w/o revision) |
This originally came from the NotesPeek help file (you can get NotesPeek from the Notes.net Sandbox) -- I added information about DB IDs and Replica IDs, and the columns about Notes copies and OS copies of databases. The NotesPeek help file also provides a nice reference to what the different Note IDs actually are (check the Help Glossary for more interesting info on Notes internals). I'd copy that for you here as well, if I didn't think I'd get in trouble for it. The C-API documentation also has similar information (C API User Guide, Appendix 1, "Anatomy of a Note ID").
This knowledge can come into play if you're relying on one of the Notes IDs to be a reference number to a Note, like if you're synchronizing information between Notes and a relational DB. Based on this table, the Notes UNID is the only thing that will remain constant across all replicas and copies of a database (watch out for the copies!).
One related little tidbit from the NotesPeek help file: the term "UNID" is supposed to be pronounced "un-I.D.", as in "try to UNderstand your I.D. file". I always thought it was pronounced "you-nid". Shows you what I know. I probably pronounce Linux wrong, too.
Tracking Notes Users at the Notes Server Console
August 31, 2002
I can't remember where this came from...I think it was from the Lotus Notes KnowledgeBase. Anyway, it's a couple of NOTES.INI parameters that allow you to see the IP adresses of the people who are hitting your Notes server:
Debug_Outfile = [path to a text/log file] DEBUG_TCP_ALL = 1
You'll have to restart your server for this to take effect. The information doesn't show up in the normal Notes log, so that's why you have to send console output to the Debug_Outfile (NOTE: the Debug_Outfile setting behavior changed in ND6 -- read here for more information). Here are some other useful logging settings and commands:
Log_Sessions=1NOTES.INI setting. Logs to the console whenever a Notes client establishes a session with the server. Tells you who the user is, and on R5 also tells you what version of the client they're using.
Show Users DebugConsole command. Displays a little more information about the Notes client users who are currently logged on.
Tell HTTP Show UsersConsole command. If session-based tracking is enabled on an R5 server, this command shows the web users who are currently logged on.
Setting Up Web Server Logging
September 29, 2002 (updated November 19)
Enabling HTTP logging allows you to track the hits that your Domino web server gets. You can either log to a database (DOMLOG.NSF) or a text file, and while the DOMLOG database is sometimes easier to get quick stats from, the text files take less server resource and are easier to archive. I generally like to log to text files, especially because I've had several instances of my DOMLOG database getting corrupted. There are also a lot of tools available to analyze the text files, since they're in a standard web server log format, so you have good reporting options for the boss (see the accesslog database on this site for more information).
Here's how I usually set up my web server logging:
1. In your server document in the NAB, go to the Internet Protocols tab, and the HTTP sub-tab below that
2. In the "Enable Logging To" section, set the "Log Files" entry to "Enabled" (keep the default "Common" log format)
3. Some good exclusions to add (to make the log files smaller) are "*.gif*; *.jpg*; *.ico*" in the URL Exclusions, and "image" in the MIME Type Exclusions
If you change any of the logging settings, you have to restart the HTTP task for them to take effect. Because the log files can start taking up a lot of space after a few weeks or months, you should make sure you keep an eye on them, and zip up or delete the old log files regularly (you can do this with an agent or a batch file).
You can also get some debug information about HTTP activity by setting up HTTP thread logging. To set this up, you need to:
1. Open the HTTPD.CNF file (in your Notes Data directory) in a text editor
2. At the end of the file, add the line "debugthreadlogging on" (all lowercase, without the quotes), followed by a blank line
3. Save and close the HTTPD.CNF file, and restart the HTTP task
This should cause the HTTP task to create a number of REQ###.LOG files in your Notes Program or Data directory (depending on your OS). There will be a separate file for each thread that the HTTP server uses. These log files can grow large very quickly, so you should automate the process of either deleting or archiving the REQ###.LOG files every night (after the files are deleted they will be automatically recreated, so you can even do it in the middle of the day if you want to).
Also, here's a link to some good information on HTTP Thread Logging/Request Logging in ND6, from the IBM site.
JS32.DLL Error Upgrading Domino Server
September 3, 2002
Sometimes when you're trying to upgrade a Domino server (say, from 5.06 to 5.07), the installation will fail with the error:
c:\lotus\domino\js32.dll error number -115
If you have any tools to determine what process is using that DLL (like Process Explorer from SysInternals), you may notice that the WINLOGON process is the one using the DLL. Unfortunately, you can't really kill the WINLOGON process and expect your server to operate properly, and without killing the process, you can't delete, move, or rename the JS32.DLL file.
The problem is that NoteStat (the Notes Performance Monitor extension) is running, and it attaches to JS32.DLL. So why would WINLOGON appear to be using that DLL? Well, it turns out that Windows NT architecture stipulates that any extensible performance counters added by a service will run in the context of the WINLOGON process. NoteStat is a Notes performance counter, so that's what's going on.
To fix this problem, run "unlodctr notestat" at the command line, and try again. In some cases, you'll have to remove NoteStat from the registry (Notes KnowledgeBase Doc #174802) and reboot for the installation to run successfully. And when you're reinstalling, do yourself a favor and do a Custom install with "Notes Performance Monitor" unselected -- unless you really feel like you need it.
Notes Client Command-Line Options
September 3, 2002
Here are some command-line options you can use when starting the Notes client. Many of these were taken from docs in the Notes KB. Substitute the path for your Notes.exe file for "C:\Notes\Notes.exe" in the list below.
C:\Notes\Notes.exe =C:\Notes\MyNotes.ini | Starts the client with an alternate INI file |
C:\Notes\Notes.exe dbName.nsf | Opens a specified local database when the client is started |
C:\Notes\Notes.exe server!!dbName.nsf |
Opens a specified database on a specified server when the client is started |
C:\Notes\Notes.exe doclink.ndl | Opens a specified doclink when the client is started |
C:\Notes\Notes.exe http://www.nsftools.com | Opens a specified web page when the client is started |
C:\Notes\Notes.exe notes://... | Opens a specified database, view, form, or document using its Notes URL when the client is started (*) |
C:\Notes\Notes.exe mailto:you@something.com | Begins composing an e-mail to the specified address with the Notes mail client |
C:\Notes\Notes.exe MAIL | Opens the default mail database on the Notes client |
C:\Notes\Notes.exe ADMINONLY | Starts the Notes Admin client (R5+) |
C:\Notes\Notes.exe /DESIGN | Starts the Notes Designer client (R5+) |
C:\Notes\Notes.exe /DEBUGGER | Starts the Notes Remote Agent Debugger (R6+) |
C:\Notes\Notes.exe /EMBEDDING | Starts Notes as an OLE server |
C:\Notes\Notes.exe /AUTOMATION | Starts Notes minimized |
(*) In Notes 6 and higher, the notes:// URL of a database, view, form, or document can be determined using the NotesURL property of the element when it's accessed in LotusScript as a NotesDatabase, NotesView, NotesForm, or NotesDocument. If you want to construct a notes:// URL manually, it's of the structure:
You can leave the server name blank (so the protocol starts with notes:///) if you want to access a local database, view, etc.
Reporting a Bug in Notes
September 5, 2002
The LDD site has a downloadable form you can use if you want to report a bug in Notes. However, the form is in WordPro format, and I know that lots of people (even us Notes users) don't have SmartSuite handy. Well I do, so I converted the form to MS Word format, in case that's better for you. Please visit the link above for instructions.
=> DefectReport.doc <=
Modifying $FormulaClass in Views
September 8, 2002
I mentioned this in one of my blog entries, but I figured it should live here in the Tips section, too. The $FormulaClass field in a view determines what types of documents show up in the view. Normally, the documents that show up are regular note documents, although if you modify the $FormulaClass field in the right way, you can also make design elements show up in your view.
All this is described quite well in the Fun with $FormulaClass article by Dan Velasco that appeared in DominoPower Magazine a few years back. There were a couple of holes in his $FormulaClass values, and if you do a little looking in the Notes API, you'll notice that the $FormulaClass values correspond to the NOTE_CLASS values in the NSFNOTE.H file. Here are the values from that header file (in hex and decimal -- use the decimal value in your view), along with their header file comments:
Note Class Type | Hex Value | Decimal Value | Comments |
---|---|---|---|
NOTE_CLASS_DOCUMENT | 0x0001 | 1 | document note |
NOTE_CLASS_INFO | 0x0002 | 2 | notefile info (help-about) note |
NOTE_CLASS_FORM | 0x0004 | 4 | form note |
NOTE_CLASS_VIEW | 0x0008 | 8 | view note |
NOTE_CLASS_ICON | 0x0010 | 16 | icon note |
NOTE_CLASS_DESIGN | 0x0020 | 32 | design note collection |
NOTE_CLASS_ACL | 0x0040 | 64 | acl note |
NOTE_CLASS_HELP_INDEX | 0x0080 | 128 | Notes product help index note |
NOTE_CLASS_HELP | 0x0100 | 256 | designer's help note |
NOTE_CLASS_FILTER | 0x0200 | 512 | filter note |
NOTE_CLASS_FIELD | 0x0400 | 1024 | field note |
NOTE_CLASS_REPLFORMULA | 0x0800 | 2048 | replication formula |
NOTE_CLASS_PRIVATE | 0x1000 | 4096 | Private design note, use $PrivateDesign view to locate/classify |
NOTE_CLASS_DEFAULT | 0x8000 | 32,768 | MODIFIER - default version of each |
NOTE_CLASS_ALL | 0x7fff | 32,767 | all note types |
NOTE_CLASS_ALLNONDATA | 0x7ffe | 32,766 | all non-data notes |
NOTE_CLASS_NONE | 0x0000 | 0 | no notes |
Getting Default Elements in the Database
September 16, 2002
An interesting corollary to the tip above is that you can use a modification of the NOTE_CLASS type values to get some of the default items in a database. Here's a list, followed by an explanation:
Note ID | Database Element |
---|---|
FFFF0002 | "About This Database" document |
FFFF0004 | Default form |
FFFF0008 | Default view |
FFFF0010 | Database icon |
FFFF0020 | Database Design Collection (view) |
FFFF0040 | Database ACL |
FFFF0100 | "Using This Database" document |
FFFF0800 | Replication Formula |
You'll notice that the last 4 numbers of the Note IDs are the hex values of the corresponding design elements in the previous tip. What's neat about this (and it makes sense if you think about it) is that these Note IDs are the same for every Notes database, so if you call:
db.GetDocumentByID("FFFF0002")
you will always get the "About This Database" document, if one exists. Now, getting some of these elements as Notes documents may not do you a whole lot of good on the surface, but some of them hold interesting qualities (as coding superhero Rod Whiteley mentions in this post on LDD, the database icon can hold many strange and random bits of information -- search for the "Icon note item names" section in STDNAMES.H).
Notes Debug Flags
October 2, 2002 (updated October 16, 2002)
A few years ago, this post on the Notes.net forum (now the LDD forum) outlined a way to pull all the debug flags from the various Notes DLL and EXE files. Virtually all of these flags are undocumented and some may not be useful at all, but it's pretty neat information anyway.
The original post used a PERL script to extract the information, and I played around a little to see if there was an easy way to batch the process, since I didn't have PERL installed on my machine. Here's what I did:
1. Go to the SysInternals site and download the STRINGS.EXE program (I think it's listed as a "Miscellaneous" application)
2. Copy STRINGS.EXE to your Notes program directory
3. Run the following commands at the DOS prompt, from the Notes program directory:
strings -a *.exe | find "DEBUG" > nDebug.txt strings -a *.dll | find "DEBUG" >> nDebug.txt
The resulting file (nDebug.txt) should give you the same debug flags as the PERL script does, plus a couple extra ones (the PERL script actually searches for "DEBUG_", and I searched for "DEBUG"). Again, most of these flags are totally undocumented, so all you can do with the resulting list is experiment. The DRC Consulting site may have some information to help you out -- there's a good list of NOTES.INI settings there.
(Updated text) I've tried this with both the "findstr" command (on Windows NT/2000) and the "find" command, which should be equivalent in this case. It looks like "find" produces more results on my NT box. I have no idea why.
Exporting Notes Documents and Rich Text Fields in RTF Format
October 23, 2002 (updated January 1, 2004)
Here's a database I wrote with some code that allows you to export the information in a Notes rich text field to an RTF file, while retaining most or all of the rich text field formatting. It also demonstrates how to write multiple things to a single RTF file (including multiple rich text fields), if that's something you're interested in doing. Additionally, the techniques involved should allow you to export rich text fields that are greater than 64k in size.
UPDATE: on January 1, 2004 I added functionality to allow you to export an entire Notes document to an RTF file, in addition to just exporting the individual fields. Please be aware that Notes doesn't always do a good job of converting documents from Notes format to RTF format, so documents that have a lot of tables on them (for example) may not export perfectly. The function I wrote that lets you export a document also allows you to specify an alternate form to use for exporting though, so you can always design a special form to use just for sending the doc to RTF.
The RTF file format is the one supported natively by Microsoft Word, so this can also allow you to create your own Word documents from Notes without even needing to have Word installed on your machine! For more information on the RTF format, please check the search engines. Microsoft used to have the version 1.4/Word97 spec available as the file GC0165.exe, although the last time I looked I could only find it buried in the GC1039.exe file here. At the time of this writing, you can also download the version 1.6/Word 2000 spec as the W2KRTFSF.exe file here.
This database was written and tested on an R5 client, and it uses a possibly undocumented API call to "ExportRTF" (which I first saw in this post on the LDD forums). I have no idea what other versions of Notes it will run on, or whether or not this is supported functionality. It is much faster than using OLE to make calls to the Microsoft Word objects to create a DOC file manually, though.
=> Rtftest.zip <=
Encryption Techniques in LotusScript
October 25, 2002 (updated December 28)
Base64 Encoding
Okay, this one's not really encryption in the sense of securely transforming data into something illegible, but it's a good place to start. Base64 (described in RFC 2045, among others) is a "classic" way of encoding binary data into text strings, and it's been used for transferring e-mail attachments for years. It's also used in conjunction with things like basic HTTP authentication and PGP signatures. The ability to encode and decode Base64 data is a good thing to have in your toolbox, because you'll run into it in lots of places.
Here's a LotusScript implementation of how to encode and decode Base64 strings. I haven't tested it recently , but it should work in many (all?) of the 4.x versions of Notes as well as R5 and R6 -- and heck, it ought to work in Visual Basic, too. (Udpated December 28: fixed TrimBytesFromFile function)
=> Base64v14.lss <=
(Note: Johan Känngård rewrote this code very nicely as a LotusScript class, if you're interested. I also have an example of using Java to encode/decode Base64 here, which would also work in a Notes agent.)
MD5 and SHA-1 Hashing
MD5 and SHA-1 are one-way hash algorithms that allow you to (essentially) garble text in such a way that it's very difficult to unscramble. While it's not encryption in the sense that it can be decrypted, it's useful for storing things like passwords (think about the Internet passwords in the Notes NAB, or PIN numbers for your ATM card).
You can find a full implementation of the MD5 algorithm in the Riddle.nsf database, which is zipped up with the sample databases from LotusSphere 2000 Presentation AD106: LotusScript Tips and Techniques Samples (I originally mentioned this in my blog). It was written by Damien Katz at Iris/Lotus/IBM, and it's good solid code. I'm not sure that I can re-post the code here at this site, so please use the links to get to it.
I do have a LotusScript implementation of SHA-1 that you can download here, though. It's an adaptation of a VBScript implementation written by one Ray Harris (I originally saw the reference at this post on the LDD forums). I did some optimizations to his original functions to make it quite a bit faster.
=> sha1.zip <=
By the way, if you want to validate the results of these or other hash functions, a nice utility to use is the free Hash Calculator from slavasoft.com
AES (Rijndael) Encryption
AES Encryption, which was actually "Rijndael" Encryption before it was adopted as the AES standard in the U.S., is a symmetric encryption algorithm that supports reasonably large key sizes (like 256-bit). This is more of what people think about when they think encryption, because it can be used to both encrypt and decrypt data.
I don't have a LotusScript implementation of the whole algorithm, but I did find a place where you can get both a C-implementation and a Windows DLL that can be called from LotusScript. That's probably faster anyway. You can either get the code and the DLL from Brian Gladman's page, or you can download the DLL here (the AesScript.zip file below), along with an example of how to call the DLL from LotusScript.
Please keep in mind that I've only done some light testing with this DLL, so I can't speak for it's total reliability. Also, if you're on a non-Windows platform I guess you'll have to download the C code from Brian's site and compile a library on your platform. At least it's available out there for you, though.
=> AesScript.zip <=
By the way, if anyone does anything with this on other (non-Windows) platforms, please send me a note -- I'd like to know how it works.
How to Extract LotusScript from a DXL Document
November 7, 2002 (updated January 13)
Here's a Java class that allows you to extract the LotusScript elements from a DXL document that's been created using the tools and functions in the Lotus XML Toolkit (available in the downloads section of the LDD site).
When design elements are exported to DXL, agents and script libraries that contain LotusScript have the script Base64 encoded. This program finds all the LotusScript elements, decodes them, and writes the decoded script to either the console or a text file. It's a good example of how to decode Base64, as well as how to recursively search through elements in an XML document.
For XML parsing functionality, I'm using the open-source JDom package and the Apache Xerces package (Xerces is included with the JDom distribution). Make sure these things are in your ClassPath when you compile and run the program. Additional information about the way this Java class works are included in the source code.
Update: there are now two versions of the class that you can look at/download. DxlScript.java is the original code, which uses JDom to parse the XML. DxlScript2.java is a new version, in which I modified all the methods to use native Node functionality to parse the XML (which allows you to paste the code directly into a Notes agent and use it from there without having to include any external packages like JDom or Xerces).
=> DxlScript.java <=
=> DxlScript2.java <=
Java Sample Code Database
January 25, 2003
This is an R5 Notes database that contains some sample Java code to help you start using Java in your Notes applications. It's got code snippets, methods, reference information, and a few Java agents that might serve as good examples. It's also a good framework for keeping track of your own Java code and tips.
=> JavaScraps.zip <=
I also mentioned in this database that the JavaDocs for XML4J and LotusXSL are on this site. Here they are:
=> xml4j_2_0_15_docs.zip <=
=> lotusxsl_0_18_5_docs.zip <=
If anyone has the LotusXSL 0.19.1 JavaDocs, please tell me. I'd really rather post that version here, because that's the version that ships with R5. I could only find the 0.18.5 version...
Format LotusScript as HTML, RTF
March 12, 2003 (updated March 27)
Here's a LotusScript script library that has functions to convert raw LotusScript code to formatted HTML -- useful if you're posting your code on the Internet or in an e-mail. By default, it will attempt to format the code using a color-scheme similar to that used by the Notes/Domino Designer IDE, although you also have the ability to define your own custom styles for the output.
I just updated the keyword list to include new classes and functions in ND6. Please tell me if I missed anything. Also, you visit some online databases that use this code to convert your LotusScript on the web at Joe Litton's site and Chris King's site.
=> ls2html.lss <=
=> ls2html.lss.html (the HTML version of this code, as an example) <=
=> FormatLS.nsf.zip (a database that formats LotusScript code that you type or paste onto a web page) <=
I also wrote a version of this script library that converts LotusScript to NotesRichText, if you need that functionality:
=> ls2rtf.lss
(HTML version) <=
Display Views in "Tree View" Format on the Web
April 2, 2003
This is a sample database (R5 format) that demonstrates a technique to display an ordinary Notes view in a Windows "tree view" type format on the Web. It just relies on a little CSS and JavaScript, and a couple of images that are attached to the database as image resources.
I actually came up with the technique a while ago, but never really did anything with it. Maybe you'll find some good uses. Instructions and source code comments are included in the database, although it's really pretty simple once you start looking at it.
=> TreeView.nsf.zip <=
Java RichTextOutputStream Class
April 9, 2003
This is a Java class you can use in your Notes agents and libraries (or stand-alone applications, if you choose) that allows you to use a Notes RichTextItem as a standard Java OutputStream. There are also some additional convenience methods that let you use styles and write entire InputStreams and the like. The entire code is JavaDoc enabled, so usage should be fairly straightforward.
=> RichTextOutputStream.java <=
LotusScript Agent to Convert HTML Tags
May 15, 2003 (updated May 17)
This is an agent I wrote to parse the HTML tags in a String, keeping a set of "desirable" tags (like <b> or <i>), and converting all the rest by changing the angle brackets to their HTML equivalents ("<" becomes < and ">" becomes >). There is also some logic for automatically converting http:// references to <a href> links, and converting linefeeds to <br> or <p> tags.
I originally wrote this as an experiment in parsing blog comments, so you could easily allow certain HTML tags in the comments, but there are probably plenty of other uses as well. If you decide to use this on a production system, please add some error checking!
Also, you can find code that performs similar tasks by Colin Williams, Laurent deWalick, and Dave Meehan.
=> ConvertTags1_1.lss (HTML version) <=
Recompiling Agents When Script Libraries Change
July 28, 2003
If you make changes to a script library, it's sometimes difficult to know when you have to recompile all the agents that call the script library and when you don't. Here are some observations I've made.
If you change the signature (i.e. -- the name, the parameters, or the return value) of a function, sub, or class method, you have to recompile.
Constant values are tricky. If an agent uses a constant value from a script library (defined in the Declarations section as a Const), and a constant in a script library is changed:
I think the reason why the old constants stick around is because when the LotusScript is compiled, the LotusScript bytecode contains the translated value of the constant, not a reference to the constant. This is good programming as far as bytecode optimization is concerned, but bad if you change the constant in the script library, because the agent never looks back at the script library to check the value of the constant.
You're okay as far as changing code in the functions and subs in the library are concerned, because I think the bytecode just contains references to their signatures, not the content of the functions/subs themselves. In other words, whenever an agent wants to run a function or a sub from a script library, it always runs it from the script library. So if you change the content of a function or sub in a library (and leave the signature alone) and don't re-save your agent, your code changes will still be recognized.
Here's a little trick for using constant values in script libraries. The Initialize sub of a script library runs before the Initialize sub of an agent. Because of this, you can always make a script library variable global (but not Const) and then set the value of the variable in the Initialize section of the script library, instead of setting it as a Const value. This will allow your script library global variable values to be propogated to agents even if the agents aren't resaved/recompiled. Be careful doing this with nested script libraries, though (where one script library uses another one), if the libraries need to call the global variables in their own Initialize scripts -- nesting can get strange sometimes.
As for the other elements that you might find in the Declarations section of your scripts, Type definition changes generally require you to recompile agents, and Class changes generally do not, unless you change the parameters that are used in a method call or modify a public member variable. The only thing I've ever had to watch out for with Classes (and it's obscure enough that it might not be worth mentioning, but I will anyway) is an issue with inherited Classes in script libraries. Let's say you have the following classes set up in a script library:
Class SuperTestClass '//stuff... End Class Class TestClass As SuperTestClass Function returnNumber () As Integer returnNumber = 1 End Function '//other stuff... End Class
and you have a bunch of agents that use TestClass and call the TestClass.returnNumber() method. Then you decide to move the returnNumber method up to the SuperTestClass and just allow TestClass to inherit the method, like this:
Class SuperTestClass Function returnNumber () As Integer returnNumber = 1 End Function '//stuff... End Class Class TestClass As SuperTestClass '//other stuff... End Class
If you don't recompile all your agents, then they'll get "Cannot find external name: RETURNNUMBER" errors if they try to call the function. This may have been fixed in ND6...I haven't tried it there yet.
Interestingly enough, if the method already existed in the super class and then you just decided to override it, no recompile is necessary, and the overridden class is used.
Games for Lotus Notes/Domino
October 18, 2003 (updated October 20)
This is a database that has some examples of how to write simple games using a Notes database. Well okay, there's only two games in there right now (Tic-Tac-Toe and a dice rolling game), but I'm trying to be optimistic about adding other games in the future. The examples are pretty basic, but it should give you some ideas of your own, and show you some examples of how to interact with a user without having to save all sorts of data to the database.
I wrote and tested this using R5. I have no idea how well it works with other versions of Notes.
=> Games.zip (version 1.2) <=
Export Docs From An MS Office Library
November 28, 2003 (updated December 3)
Here's an agent you can use to export the documents from a Notes database that's been built using the Microsoft Office Document Library template. When you create a new Office document in an MS Office Library, the document is stored as an embedded OLE object. This makes it easy to edit in-place, but it also makes it difficult to programmatically move the Office document somewhere else.
The answer is to use OLE to open the embedded Office document in the background and save it to a file, and then store the file wherever you want it. In the example below, I used this technique to save the selected documents in an MS Office Library to another database that uses the regular Document Library template. The script should be easy to modify for your own purposes.
=> ExportMsOfficeLibrary.lss (html) <=
Convert Notes Documents and Rich Text Fields to HTML
January 11, 2004
This database has a script library that describes a technique allowing you to get the contents of a regular Rich Text field as MIME/HTML, even if that field isn't set to store contents as MIME. There is also a function that will allow you to convert the contents of an entire Notes document as MIME/HTML using the same technique.
This does not require any extra DLLs or special configurations. While it works with R5, you should really use ND6 or 6.5, because R5 has a bug that truncates large MIME parts like graphics. Also, the MIME/HTML that is produced is the same as the HTML that would be produced if you sent the rich text or document as an e-mail, which may be slightly different than the HTML that is produced if you rendered it on a web page using Domino (notably, some elements like buttons won't show up). See the database and code comments for more detail.
=> RT2HTML.zip <=
Play a WAV File in a Rich Text Field
June 27, 2004
If you want to play a sound from the Notes client, you can use the NotesUIWorkspace PlayTune method. However, this method requires you to already have the sound file that you're playing on your hard drive, in a specific location. Because this is not always possible or convenient, here's another way to do it, using OLE:
1. Open a document in edit mode and put the cursor in a rich text field (if this is an e-mail, anywhere in the body will do)
2. Choose the menu option Create - Object
3. Choose the "object from a file" option, browse to the wave file, and click OK
4. [OPTIONAL] Right-click the attached file (which should have an icon like a stereo speaker), and choose the option "Object Properties". Give the object a descriptive name.
5. Add a space after the attached file icon and choose the menu option Create - Hotspot - Button
6. Give the button a meaningful label, like "Play Sound"
7. The formula editor for the button should be visible on the bottom part of the screen (if it's not, right click the button and choose the option "Edit Button"). Change the language type to LotusScript, and enter the following piece of script:
Dim ws As New NotesUIWorkspace Dim doc As NotesDocument Set doc = ws.CurrentDocument.Document Forall obj In doc.EmbeddedObjects '** this will attempt to play all Sound Recorder objects If (obj.Class = "SoundRec") Then Call obj.DoVerb("&Play") End If '** this will attempt to play a specific object (use '** whatever name you used in step 4 above) 'If (obj.Name = "MySound") Then ' Call obj.DoVerb("&Play") 'End If End Forall
8. Click somewhere else on the document to get out of the script editor, and either save the document, or (if this is an e-mail) send the mail message
As far as I know, this will only work on Windows machines, and I'm not sure what happens if you have another application registered to edit WAV files. This technique should also work if you embed a WAV file onto a form (as opposed to attaching it to a rich text field on a document). And as a general technique, it's a common way to access and make calls to embedded OLE objects on a form. If you want to see all the "verbs" associated with an embedded object, you can use the Verbs property of the NotesEmbeddedObject class (as described in the Notes Designer Help).
Output Your Notes Calendar As A Web Page
July 24, 2004
This is a LotusScript agent you can drop in your Notes e-mail file that allows you to send your calendar to a web page, like this:
In this way, you can use it as an Active Desktop component or a part of a web page. See this blog entry for more details.
=> MiniWebCal.lss <=
Convert CSV Files To XML
August 8, 2004 (updated August 9)
This is a LotusScript class that converts CSV files to XML. You can also use it as a basis for parsing CSV (or other types of delimited files) directly.
=> CSVtoXMLv1_2.lss <=
Update: if you just want some basic parsing of a comma-delimited file, here's a simple reader class you can use:
=> CSVReader.lss <=
Check For Valid XML Characters
August 9, 2004
Here's a class that produces strings of valid character types, as defined in several places in the official XML spec. You can use these strings to check the validity of the characters in a string that you might be processing.
=> XMLChars.lss <=
LotusScript StringBuffer Class
August 9, 2004
This is a class that provides minimum StringBuffer functionality in LotusScript. It's much more efficient to use this technique when concatenating a large number of strings than it is to simply combine them all together.
=> StringBuffer.lss <=
Lotus Notes Web Datepicker
September 4, 2004 (updated December 4, 2005)
This is a database that contains a JavaScript library (DatePicker.js) and an associated style sheet (DatePicker.css) that allow you to easily add drop-down date picker functionality to your forms when they're used on the web, without having to rely on a Java applet. All you have to do is include the script library and style sheet with your forms, and add a small bit of computed text next to each date field. There's an example form in the database (DatePickerTest) that demonstrates how this works.
The database is in Notes 6 format, because it's a lot easier to use and share JavaScript libraries and CSS files in Notes 6 and later. If you're stuck on an older version of the client and can't open the database, you can see a working example of the code at the other link below (I'll leave it up to you to determine the best way to include the code in your pre-Notes 6 databases).
I've lightly tested the code in Internet Explorer 6 and Mozilla Firefox. I have no idea how well it works on other browsers.
=> DatePicker.zip <=
=> DatePickerTest.htm <=
Setting Up Repeating Dates In Notes
October 17, 2004
Have you ever set up a repeating event on your calendar in Notes and thought to yourself, "I sure would like to use that functionality in my custom applications"? I have, and I spent a lot of time trying to figure out how it all works.
Essentially, there's a hidden LotusScript class called NotesCSEventOwnerDocument that generates the list of repeating dates, based on rules that are specified in the dialog box that allows you to choose your repeat rules. This class is undocumented and probably completely unsupported outside of the standard Notes calendar, but it's such nice functionality that I did a lot of experimentation to try to understand it.
The database below is the result of my "hacking" efforts. It has a modified copy of the (RepeatForm) subform from the Notes 6.5 iNotes.ntf template, free of dependencies on external script libraries and with example usage; a slightly more modified copy of the (RepeatForm) subform that you can use inline directly on your forms (instead of as a dialog box), also free of dependencies on external script libraries and with example usage; and a script library and two agents that describe how you can use the NotesCSEventOwnerDocument class in your backend agents, completely separate from any forms or documents in the UI.
I will warn you again that this is undocumented and unsupported functionality, so please test first and use at your own risk.
=> RepeatDates.zip <=
Converting Winmail.dat Files In Your Mail
October 20, 2004
At times, e-mails you receive from users of Outlook/Exchange will be plain-text messages with a large attachment at the end called either "Winmail.dat" or "ATT0001.dat". The reason why this happens is described fairly well in Microsoft Technote 241538.
However, you as a Notes user must now do something with that .dat file, especially if there are file attachments trapped inside. While there are stand-alone freeware and shareware applications that will read those files for you (as long as you save the file to your hard drive), I wrote a Notes agent that you can use to extract the information from the .dat files right from your mail file. You just add it as an agent that runs against "selected docs" in your mail database, and it will convert the .dat file and make a new copy of the message in your Inbox with the extracted files attached at the bottom. You can download the agent code below. Instructions for setting up the agent are in the code comments.
=> ExtractWinmail.java <=
I have also made this code available in a mail-in database, which is often a lot easier to implement in a corporate setting. You just copy the database to your server, set it up as a mail-in database, and when users forward their e-mails with Winmail.dat attachments to it the files inside are extracted and mailed back to the sender. The database is available as a project on the OpenNTF site, at:
=> The WinmailExtractor Database <=
Please note that this agent makes use of the open-source and GPLed JTNEF library by Amichai Rothman. Please visit his site if you have any questions about the underlying TNEF conversion code, or the licensing of his library.
Also, this code was tested using the 1.2.2 version of the jTNEF library. If you have issues compiling the agent, you might want to try using that version, as it seems that version 1.2.3 might be making at least one call to a method that's not available until Java 1.4 (which is Notes 7 to me and you). The older version is available at:
http://www.freeutils.net/source/jtnef/jtnef-1_2_2.zip
LS2J Examples Database
November 19, 2004 (updated December 6)
This is a database with a few agents and script libraries that demonstrate some interesting ways to use the LS2J technology that was introduced in Notes 6. LS2J allows you to call Java classes and methods from LotusScript. The examples in this database include:
=> LS2JExamples.zip <=
Google Suggest-type Lookups In Notes
December 22, 2004 (updated January 9, 2005)
This database demonstrates how to use XmlHttp requests to make dynamic lookups on a Notes web page, using the same technique that is found on the Google Suggest page. I made heavy use of Chris Justis' Google Suggest Dissection article in writing this example code.
=> NotesSuggest.zip <=
I also have a live example of the JavaScript code I'm using on this page, if you want to see it: Enter A Zip Code Using Google Suggest-Type Lookups
LotusScript Class To Get Unread Docs In A Database Or View
April 15, 2005
While you can access the unread docs in a view using a front-end agent that runs against "All unread documents in a view", there doesn't seem to be a good built-in way (as of Notes version 6) to access them from a backend agent, or an agent that isn't running in the context of that specific view open in the Notes client UI.
The following class will return an array of NoteIDs for all unread docs in a view/folder or database, using the C-API.
=> UnreadDocListClass.lss (html) <=
Running a View Action Against Selected Docs
August 8, 2005
You know how when you have a view action that calls an agent to run against selected documents in the view, sometimes the docs are deselected after the action finishes and sometimes they're not? Well according to IBM Technote #1101841, here's why:
It's a subtle difference, but sometimes you want one thing to happen and sometimes you want the other.
Append a Button to a Rich Text Field
August 31, 2005 (updated September 2)
If you want to add a button to a Notes Rich Text field using LotusScript, a common technique is to create the button manually ahead of time and save it all by itself in the rich text field of a profile document, and then copy and append the pre-created button whenever it's needed.
While this works well if the label or the underlying code of the button is static, it's not a solution if you need to dynamically change the label or the code at the time you're adding the button.
Below is some code for a class that will allow you to create and append buttons to a NotesRichTextItem, with the ability to specify your own custom LotusScript or @Functions at runtime. It uses DXL to create the button on a temporary document first, and then the new button is copied over. The code should work on Notes 6.5 and higher.
How to write a LotusScript Singleton
December 26, 2005
This is a technique for creating a singleton (one of the classic GOF design patterns) using LotusScript.
The trick is, if you declare a class as PRIVATE in a script library, it's not accessible outside the library. However, if you have something inside that script library (class method or function) that returns an instance of that Private class as a VARIANT, then suddenly you can call all the methods of that PRIVATE class and use it just like it's a regular Public class.
See the code link below for more information:
LotusScriptSingleton.lss (html)
Managing Zip Files in Lotus Notes
December 28, 2005
This is a Notes database that uses a Java class I wrote (ZipFileManager) to create, read, and update zip files from LotusScript. There are only a few example agents in the database (no pretty forms or views). They are:
The examples are all in LotusScript because that's what most people seem to understand, but it's trivial to move the code over to Java if you're so inclined.
All of the comments and explanation about the code are either in the agents themselves or in the JavaDocs that are packaged with the ZipFileManager JAR file and source code, which is included in the zip file that contains the database and is attached to the "About this Database" document as well.
Get Selected Docs in a View Using the Notes API
December 29, 2005
The SelectedDocsList class provides a way to programmatically access the list of selected docs in a view that's currently open in the Notes client (open in a tab, a frame, or as an embedded view), without relying on an agent to be running against "Selected docs" in a view.
I originally wrote this to get a handle on the docs that were selected in an embedded view on a page or form. Please note that it does not seem to work on embedded views that have a selection filter applied -- I have no idea why. Please see the code itself for more comments and information.