Notes Tips




Notes Tips

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 TypeAll DBsNote RevisionsDB ReplicasNotes DB CopiesOS DB Copies
Database IDuniquen/adifferentdifferentsame
Replica IDuniquen/asamedifferentsame
Unique IDuniquesamesamesamesame
OIDuniquedifferentsamesamesame (w/o revision)
Note IDnot uniquesamedifferentsamesame
GNIDuniquesamedifferentdifferentsame
IIDnot uniquedifferentdifferentdifferentsame (w/o revision)
giiduniquedifferentdifferentdifferentsame (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=1  
NOTES.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 Debug 
Console command. Displays a little more information
about the Notes client users who are currently logged on.

Tell HTTP Show Users  
Console 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.iniStarts the client with an alternate INI file
C:\Notes\Notes.exe dbName.nsfOpens 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.ndlOpens a specified doclink when the client is started
C:\Notes\Notes.exe http://www.nsftools.comOpens 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.comBegins composing an e-mail to the specified address with the Notes mail
client
C:\Notes\Notes.exe MAILOpens the default mail database on the Notes client
C:\Notes\Notes.exe ADMINONLYStarts the Notes Admin client (R5+)
C:\Notes\Notes.exe /DESIGNStarts the Notes Designer client (R5+)
C:\Notes\Notes.exe /DEBUGGERStarts the Notes Remote Agent Debugger (R6+)
C:\Notes\Notes.exe /EMBEDDINGStarts Notes as an OLE server
C:\Notes\Notes.exe /AUTOMATIONStarts 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:



  • notes://servername/databaseName?OpenDatabase or
    notes://servername/__dbReplicaID?OpenDatabase for a database
  • notes://servername/databaseName/viewName?OpenView or
    notes://servername/__dbReplicaID/viewUNID?OpenView for a view
  • notes://servername/databaseName/formName?OpenForm or
    notes://servername/__dbReplicaID/formUNID?OpenForm for a form
  • notes://servername/databaseName/0/documentUNID?OpenDocument or
    notes://servername/__dbReplicaID/0/documentUNID?OpenDocument for a document

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 TypeHex ValueDecimal ValueComments
NOTE_CLASS_DOCUMENT0x00011document note
NOTE_CLASS_INFO0x00022notefile info (help-about) note
NOTE_CLASS_FORM0x00044form note
NOTE_CLASS_VIEW0x00088view note
NOTE_CLASS_ICON0x001016icon note
NOTE_CLASS_DESIGN0x002032design note collection
NOTE_CLASS_ACL0x004064acl note
NOTE_CLASS_HELP_INDEX0x0080128Notes product help index note
NOTE_CLASS_HELP0x0100256designer's help note
NOTE_CLASS_FILTER0x0200512filter note
NOTE_CLASS_FIELD0x04001024field note
NOTE_CLASS_REPLFORMULA0x08002048replication formula
NOTE_CLASS_PRIVATE0x10004096Private design note, use $PrivateDesign view to locate/classify
NOTE_CLASS_DEFAULT0x800032,768MODIFIER - default version of each
NOTE_CLASS_ALL0x7fff32,767all note types
NOTE_CLASS_ALLNONDATA0x7ffe32,766all non-data notes
NOTE_CLASS_NONE0x00000no 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 IDDatabase Element
FFFF0002"About This Database" document
FFFF0004Default form
FFFF0008Default view
FFFF0010Database icon
FFFF0020Database Design Collection (view)
FFFF0040Database ACL
FFFF0100"Using This Database" document
FFFF0800Replication 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鋘ng錼d
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 &lt;
and ">" becomes &gt;). 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:



  • if the agent is run in Debug mode, the new constant is used
  • if the agent is run manually or scheduled, the old constant is used (even if
    you just ran it in Debug mode and saw the new variable)
  • if the agent is opened, saved with CTRL-S (with no changes having been made
    to the agent), and closed, the old constant is still used
  • if the agent is opened, modified, and saved with CTRL-S, the new constant is
    used
  • if the agent is recompiled using the API, the new constant is used

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:



  • An agent that makes an FTP connection to a server, lists files and
    directories, and downloads a file. Using LS2J for this type of thing allows you
    to perform multiplatform FTP client operations (without relying on LotusScript
    calls to Windows DLLs).

  • An agent that allows you to use regular expressions in LotusScript. I wasn't
    intending to teach you how to use regular expressions if you've never used them
    before, so I kept the examples reasonably simple.

  • An agent that can resize, rotate, and otherwise manipulate JPEG image files.
    It also has an example of how LS2J can allow you to use Java multi-threading in
    LotusScript.

  • An agent that displays a Java AWT progress bar to show the progress of a
    LotusScript agent (added in version 1.1) [screenshot]

  • An agent that displays a non-modal dialog with any or all of the following
    elements: a multi-line text message, a scrolling text area, a progress bar, and
    a Cancel button. The dialog can display and be updated while the calling agent
    runs in the background (added in version 1.2) [screenshot]

=> 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:



  • when an agent is run with @Command([ToolsRunMacro]), the documents are
    deselected when the agent finishes

  • when an agent is run with a "Run Agent" simple action, the documents
    remain selected when the agent finishes

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.

RichTextButtonClass.lss






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:



  • an overview of common operations, like adding or updating a file or
    directory, reading the existing entries, and dealing with errors
  • how to routinely back up all the NSF files in your Notes data directory into
    a single zip file, updating any files in the zip file that have changed and
    adding any new files that aren't there yet (and logging everything to a text
    file for your reading pleasure)
  • how to back up all your Domino web server log files (if you have any) into a
    series of zip files -- one per month -- and delete the old files after they've
    been zipped away

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.

ZipStuff.zip






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.

SelectedDocsList.lss (html)

原文地址:https://www.cnblogs.com/hannover/p/2477468.html