Leave Code in the state you would like to find it in.

It’s been one of my principles since I started being an independent developer. Much of my work is maintaining old codebases, and there are many horror stories that I could recount.

The temptation is there to do a quick-and-dirty modification, a quick patch, but one should resist the temptation.

Customers generally do not understand the concept of refactoring and I have to this date never been able to persuade any customer of parting with cash for refactoring. Arguments about less work down the line just fall on deaf ears.

So the refactoring is included in my normal style of coding – on-the-fly refactoring, if you will. I generally find that it’s well worth refactoring badly written code as you are trying to read it.Renaming variables is my first step at reading the code, then creating subfunctions that have a clear purpose in separate functions. If the code is complex I’ll generally do the step of converting it to object-oriented code. It might seem like a waste of time or even overzealousness, but on the long run it’s well worth it, also for your client, for his maintenance costs are going to go down.

So, whenever I am within a function that I need to update or correct, I make sure that I leave the code in a state that won’t make me cringe. This usually means renaming variables (naming them for what the content is, not the container – i.e. docPurchaseOrder instead of doc), adding error trapping, and deleting stuff.

I love deleting stuff. The fewer design elements, the fewer functions there are, the better, if you ask me.

In the past, if you were a Notes developer without access to third-party tools, coding was very much an accretive process. Need a lookup view? Create a new one. Need a slightly different function? copy-paste. Since we had no visibility about dependencies, it was really dangerous to remove things – so the convention was just to add things.

Over the years this results in a terrible mess.

Thankfully there are some tools one still can use. One of my favourites is Teamstudio’s lscalls, a small exe that lists out functions that are no longer called by any other function. This is a really powerful and safe way to identify functions ready for deletion.

Teamstudio no longer posts it on their website (too legacy-ish, presumably) but they will send you the file if you e-mail them and ask nicely.

Just for me, here is an example of the syntax.

C:\Program Files (x86)\IBM\Notes>lscalls “C:\Program Files (x86)\IBM\Notes\Data\Development\eFSR\eFSR3_0\Efsr_(3_0)_Field_Service_Local_Dev.nsf” -o “c:\temp\lscallsoutput.csv”

You will need to place lscalls.exe in your notes program directory.

A little caveat: if a function is shared between multiple databases with inherited script libraries, you might want to make a check on all databases sharing the common code.

Finding comments from Tim or Jens in forums and blogs

Every now and then, on my searches in the interwebs, I find a comment or an answer by Tim or Jens, and different emotions hit me:

There is a moment of shock, a ‘speaking from the dead’ frisson, then sadness at their deaths, and then, also, gratitude and a sense of wonder that they are still helping me out.

Jens never missed an event, be it in Switzerland or abroad (where the both of us were sometimes the only attendees coming from Switzerland). I found him to be exact, friendly, helpful and in the last few years he had been a driving force within SNOUG, the Swiss notes user group and had organised a few weeks before his death a very enjoyable day for us locals.

I only met Tim in person once, at the ILUG in Cardiff (where he delivered his infamous Star-Wars themed session with Paul Withers). Blattschuss. What a wonderful session.

I regularly read his blog, and I was always impressed about his creative energy, always pushing at the boundaries of what is possible, and I always wondered – Where does he find the time for all of this?

We had a long chat walking to the restaurant and I discovered that he also sung in his spare time – a hobby that I share with him, and Julian Woodward. I had imagined us singing a trio together, for a laugh and hopefully for a bit of a surprise. He was enthusiastic about the idea. It would have been lovely, he had such a deep bass voice, almost effortless, Julian is a Tenor, and I am a baritone, so it would have been perfect.

Tim was also surprisingly accessible, and, his evident acumen notwithstanding, never made me feel silly. His explanations always left me thinking ‘so that’s how you do it’ instead of the unfortunately far more common ‘that went miles over my head, I’d better just nod as if I understood’.

At the moment I just feel grateful to have such a wonderful job, to have so many talented persons pooling their knowledge without any financial reward, to work in an environment that is so fast-paced, and being able to discover such persons as Jens and Tim.

calling Word’s Find and Replace using LotusScript

There are two syntaxes to call OLE objects, one is using := like this:

Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:="hi", ReplaceWith:="hello", Replace:=wdReplaceAll

Unfortunately LotusScript does not know how to deal with this, so you have to list the arguments exhaustively and in their correct order, including arguments which one does not really need.

Usually I can figure the syntax pretty quickly, but this one was really fiddly, so here is my function in all its glory.

I’ve tested it on Notes 9.0.1 and Word 2010, German version – YMMV.

'/*************************************************************************************
' * Function FindAndReplaceWithinWordOLEObject:A function to find and replace some string within an inputted word document.
' * This function has been written because the OLE Call to the function is complicated and LotusScript does not 
' * allow this syntax : .Execute FindText:="hi", ReplaceWith:="hello", Replace:=wdReplaceAll
' * @param varWordDocument a Word Document. (e.g. Application.ActiveDocument)
' * strFindThis the string I want to replace
' * strReplaceWithThis the replacement string
' * @return true if successful.
' * @author Andrew Magerman/Magerman/NotesNet
' * @version May 9, 2014
' *************************************************************************************/
Function FindAndReplaceWithinWordOLEObject(varWordDocument, strFindThis As String, strReplaceWithThis As String) As boolean
	
	On Error GoTo ErrorHandling

	Print "version 7"

	'documentation of these values at end of function	
	Dim FindText As Variant
	Dim MatchCase As Variant
	Dim MatchWholeWord As Variant
	Dim MatchWildcards As Variant
	Dim MatchSoundsLike As Variant
	Dim MatchAllWordForms As Variant
	Dim Forward As Variant
	Dim Wrap As Variant
	Dim SearchFormattting As Variant
	Dim ReplaceWith As Variant
	Dim ReplaceZeroOrOneOrAll As Variant
	
	FindText = strFindThis
	MatchCase = True
	MatchWholeWord = False
	MatchWildcards = False
	MatchSoundsLike = False
	MatchAllWordForms = False
	Forward = True
	
	'The folowing are the valid constants for Wrap
	'Const wdFindStop = 0
	'Const wdFindAsk = 2
	'Const wdFindContinue = 1	
	Wrap = 1
	
	SearchFormattting = True	
	ReplaceWith = strReplaceWithThis
	
	'The folowing are the valid constants for ReplaceZeroOrOneOrAll
	'Const wdReplaceAll = 2
	'Const wdReplaceNone = 0
	'Const wdReplaceOne = 1
	ReplaceZeroOrOneOrAll = 2 
	
	FindAndReplaceWithinWordOLEObject = varWordDocument.Content.Find.Execute(FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward, Wrap, SearchFormattting, ReplaceWith, ReplaceZeroOrOneOrAll)
	
	Exit Function
Errorhandling:
	Call LogError()
	FindAndReplaceWithinWordOLEObject = false
	Exit Function
	%REM
	expression .Execute(FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward, Wrap, Format, ReplaceWith, Replace, MatchKashida, MatchDiacritics, MatchAlefHamza, MatchControl)
	expression Required. A variable that represents a Find object.
	
	Parameters
	
	FindText
	Optional
	Variant
	The Text To be searched for. Use an empty String ("") To search For formatting only. You can search For special characters by specifying appropriate character codes. For example, "^p" corresponds To a paragraph mark And "^t" corresponds To a Tab character.
	
	MatchCase
	Optional
	Variant
	True To specify that the find Text be Case sensitive. Corresponds To the Match Case check box In the Find And Replace dialog box (Edit menu).
	
	MatchWholeWord
	Optional
	Variant
	True To have the find operation locate only entire words, Not Text that Is part of a larger word. Corresponds To the Find whole words only check box In the Find And Replace dialog box.
	
	MatchWildcards
	Optional
	Variant
	True To have the find Text be a special search operator. Corresponds To the Use wildcards check box In the Find And Replace dialog box.
	
	MatchSoundsLike
	Optional
	Variant
	True To have the find operation locate words that sound similar To the find text. Corresponds To the Sounds Like check box In the Find And Replace dialog box.
	
	MatchAllWordForms
	Optional
	Variant
	True To have the find operation locate all forms of the find Text (For example, "sit" locates "sitting" And "sat"). Corresponds To the Find all word forms check box In the Find And Replace dialog box.
	
	Forward
	Optional
	Variant
	True To search forward (toward the End of the document).
	
	Wrap
	Optional
	Variant
	Controls what happens If the search begins at a point other than the beginning of the document And the End of the document Is reached (Or vice versa If Forward Is Set To False). This argument also controls what happens If there Is a selection Or range And the search Text Is Not found In the selection Or range. Can be one of the WdFindWrap constants.
	
	Format
	Optional
	Variant
	True To have the find operation locate formatting In addition To, Or instead of, the find text.
	
	ReplaceWith
	Optional
	Variant
	The replacement text. To Delete the Text specified by the Find argument, Use an empty String (""). You specify special characters And advanced search criteria just As you Do For the Find argument. To specify a graphic object Or other nontext item As the replacement, move the item To the Clipboard And specify "^c" For ReplaceWith.
	
	Replace
	Optional
	Variant
	Specifies how many replacements are To be made: one, all, Or none. Can be Any WdReplace constant.
	
	MatchKashida
	Optional
	Variant
	True If find operations match Text With matching kashidas In an Arabic-language document. This argument may Not be available To you, depending On the language support (U.S. English, For example) that you have selected Or installed.
	
	MatchDiacritics
	Optional
	Variant
	True If find operations match Text With matching diacritics In a right-to-left language document. This argument may Not be available To you, depending On the language support (U.S. English, For example) that you have selected Or installed.
	
	MatchAlefHamza
	Optional
	Variant
	True If find operations match Text With matching alef hamzas In an Arabic-language document. This argument may Not be available To you, depending On the language support (U.S. English, For example) that you have selected Or installed.
	
	MatchControl
	Optional
	Variant
	True If find operations match Text With matching bidirectional control characters In a right-to-left language document. This argument may Not be available To you, depending On the language support (U.S. English, For example) that you have selected Or installed.
	
	MatchPrefix
	Optional
	Variant
	
	True To match words beginning With the search string. Corresponds To the Match prefix check box In the Find And Replace dialog box.
	MatchSuffix
	Optional
	Variant
	True To match words ending With the search string. Corresponds To the Match suffix check box In the Find And Replace dialog box.
	
	MatchPhrase
	Optional
	Variant
	True ignores all white Space And control characters between words.
	
	IgnoreSpace
	Optional
	Variant
	True ignores all white Space between words. Corresponds To the Ignore white-space characters check box In the Find And Replace dialog box.
	
	IgnorePunct
	Optional
	Variant
	True ignores all punctuation characters between words. Corresponds To the Ignore punctuation check box In the Find And Replace dialog box.
	
	Return Value
	Boolean
	
	%END REM
	
	
	
End Function

Installing OpenNTF Essentials with local web preview

This took some time (OK, it took me day and it was painful), so here are some hints :

  • If you have uploaded the updatesite-runtime.nsf from openntf.org, you MUST sign all the plugins (Actions/Sign all).
  • In order for the Web preview to work, you will need to manually copy the plugin and feature files found respectively in

    C:\Program Files (x86)\IBM\Notes\Data\workspace\applications\eclipse
    to
    C:\Program Files (x86)\IBM\Notes\Data\domino\workspace\applications\eclipse\features

  • finally, when you read ‘restart http’ the command you want is

    Restart Task HTTP

    not

    Tell HTTP Restart

And here are the most useful articles and ressources I found on the interwebs:

Deploy an Eclipse update site to IBM Domino and IBM Domino Designer by John Dalsgaard

Extension Library deployment

XPages beyond the basics by Ulrich Krause

Notes Client Performance optimization with Notes RPC Parser: new Version 1.0.13 available

A new version of the Notes RPC is now available for download. Have a look here:

Lars Bentrop-Bos contacted me last week with a couple of bugs he had found in the application. Since I was already updating things, I made a large release, with many small improvements that I had been thinking of:

New function: Clear cache.ndk

Screen Shot 2014-04-07 at 10.08.41
NRPC Calls are logged only for calls between the server and the client. As a performance booster, Notes caches design element information on a local file called cache.ndk (in the notes data directory). If the file already exists in the local cache, it’s not downloaded by the server. The new button clears the local cache, so that you can simulate the kind of response times that first-time users have of your application.

New Navigation: using unread marks

Screen Shot 2014-04-07 at 10.12.34

I have cunningly made the particularly slow transactions unread documents, so that the end-user can jump from one to another.

Jump to Note
Screen Shot 2014-04-07 at 10.14.37
If a particular transaction concerns a particular note, you can now jump to that note. If it’s a data note, the client is opened, if it’s a designer note, the designer client is opened.

New UI:
1995 came by and took the old UI back. I have spruced things up and added new icons, including a nifty application icon showing some lightning

 

NSF/NIF transactions : Names which appear in the Debug_Outfile.

Buried deep inside neterr.h is this gem of a table:

/* Strings which are the names of the various NSF/NIF transactions.
Used to display them for debugging (CLIENT_CLOCK). */
#define STR_GET_MULT_NOTE_INFO_UNID_RQST PKG_NETWORK+144
stringtext(STR_GET_MULT_NOTE_INFO_UNID_RQST,"GET_MULT_NOTE_INFO_BY_UNID")
#define STR_ASYNC_NIFOPENNOTE_RQST PKG_NETWORK+145
stringtext(STR_ASYNC_NIFOPENNOTE_RQST, "ASYNC_NIF_OPEN_NOTE")
#define STR_ASYNC_READ_ENTRIES_RQST PKG_NETWORK+146
stringtext(STR_ASYNC_READ_ENTRIES_RQST, "ASYNC_READ_ENTRIES")
#define STR_ASYNC_CANCEL_RQST PKG_NETWORK+147
stringtext(STR_ASYNC_CANCEL_RQST, "ASYNC_CANCEL")
#define STR_ASYNC_OPEN_NOTE_RQST PKG_NETWORK+148
stringtext(STR_ASYNC_OPEN_NOTE_RQST, "ASYNC_OPEN_NOTE")
#define STR_ASYNC_READ_OBJECT_RQST PKG_NETWORK+149
stringtext(STR_ASYNC_READ_OBJECT_RQST, "ASYNC_READ_OBJECT")
#define STR_OPEN_DB_RQST PKG_NETWORK+150
stringtext(STR_OPEN_DB_RQST, "OPEN_DB")
#define STR_CREATE_DB_RQST PKG_NETWORK+151
stringtext(STR_CREATE_DB_RQST, "CREATE_DB")
#define STR_CLOSE_DB_RQST PKG_NETWORK+152
stringtext(STR_CLOSE_DB_RQST, "CLOSE_DB")
#define STR_CLOSE_DB_RQST_ALT PKG_NETWORK+153
stringtext(STR_CLOSE_DB_RQST_ALT, "CLOSE_DB")
#define STR_GET_SPECIAL_NOTE_ID_RQST PKG_NETWORK+154
stringtext(STR_GET_SPECIAL_NOTE_ID_RQST, "GET_SPECIAL_NOTE_ID")
#define STR_ITEM_DEF_TABLE_RQST PKG_NETWORK+155
stringtext(STR_ITEM_DEF_TABLE_RQST, "ITEM_DEF_TABLE")
#define STR_OPEN_NOTE_RQST PKG_NETWORK+156
stringtext(STR_OPEN_NOTE_RQST, "OPEN_NOTE")
#define STR_DELETE_NOTE_RQST PKG_NETWORK+157
stringtext(STR_DELETE_NOTE_RQST, "DELETE_NOTE")
#define STR_GET_NOTE_INFO_RQST PKG_NETWORK+158
stringtext(STR_GET_NOTE_INFO_RQST, "GET_NOTE_INFO")
#define STR_SET_SPECIAL_NOTE_ID_RQST PKG_NETWORK+159
stringtext(STR_SET_SPECIAL_NOTE_ID_RQST, "SET_SPECIAL_NOTE_ID")
#define STR_DB_INFO_GET_RQST PKG_NETWORK+160
stringtext(STR_DB_INFO_GET_RQST, "DB_INFO_GET")
#define STR_DB_INFO_SET_RQST PKG_NETWORK+161
stringtext(STR_DB_INFO_SET_RQST, "DB_INFO_SET")
#define STR_DB_MODIFIED_TIME_RQST PKG_NETWORK+162
stringtext(STR_DB_MODIFIED_TIME_RQST,"DB_MODIFIED_TIME")
#define STR_SEARCHSTART_RQST PKG_NETWORK+163
stringtext(STR_SEARCHSTART_RQST, "SEARCH")
#define STR_SEARCHSTOP_RQST PKG_NETWORK+164
stringtext(STR_SEARCHSTOP_RQST, "SEARCHSTOP")
#define STR_SERVER_TIME_RQST PKG_NETWORK+165
stringtext(STR_SERVER_TIME_RQST, "SERVER_TIME")
#define STR_DELETE_DB_RQST PKG_NETWORK+166
stringtext(STR_DELETE_DB_RQST, "DELETE_DB")
#define STR_FILE_SUMMARY_RQST PKG_NETWORK+167
stringtext(STR_FILE_SUMMARY_RQST, "FILE_SUMMARY")
#define STR_GET_DBOPTIONS_RQST PKG_NETWORK+168
stringtext(STR_GET_DBOPTIONS_RQST, "GET_DBOPTIONS")
#define ERR_ISPY_PROBE_COMPLETED PKG_NETWORK+169
errortext(ERR_ISPY_PROBE_COMPLETED, "Probe of %s port on %s has completed")
#define STR_DB_REPLINFO_SET_RQST PKG_NETWORK+170
stringtext(STR_DB_REPLINFO_SET_RQST, "DB_REPLINFO_SET")
#define STR_DB_REPLINFO_GET_RQST PKG_NETWORK+171
stringtext(STR_DB_REPLINFO_GET_RQST, "DB_REPLINFO_GET")
#define STR_GET_MODIFIED_NOTES_RQST PKG_NETWORK+172
stringtext(STR_GET_MODIFIED_NOTES_RQST, "GET_MODIFIED_NOTES")
#define STR_STAMP_NOTES_RQST PKG_NETWORK+173
stringtext(STR_STAMP_NOTES_RQST, "STAMP_NOTES")
#define STR_RENAME_DB_RQST PKG_NETWORK+174
stringtext(STR_RENAME_DB_RQST, "RENAME_DB")
#define STR_REPLICATE_RQST PKG_NETWORK+175
stringtext(STR_REPLICATE_RQST, "REPLICATE")
#define STR_GET_OBJECT_SIZE_RQST PKG_NETWORK+176
stringtext(STR_GET_OBJECT_SIZE_RQST, "GET_OBJECT_SIZE")
#define STR_FREE_OBJECT_RQST PKG_NETWORK+177
stringtext(STR_FREE_OBJECT_RQST, "FREE_OBJECT")
#define STR_ALLOC_OBJECT_RQST PKG_NETWORK+178
stringtext(STR_ALLOC_OBJECT_RQST, "ALLOC_OBJECT")
#define STR_REALLOC_OBJECT_RQST PKG_NETWORK+179
stringtext(STR_REALLOC_OBJECT_RQST, "REALLOC_OBJECT")
#define STR_READ_OBJECT_RQST PKG_NETWORK+180
stringtext(STR_READ_OBJECT_RQST, "READ_OBJECT")
#define STR_WRITE_OBJECT_RQST PKG_NETWORK+181
stringtext(STR_WRITE_OBJECT_RQST, "WRITE_OBJECT")
#define STR_OPEN_COLLECTION_RQST PKG_NETWORK+182
stringtext(STR_OPEN_COLLECTION_RQST, "OPEN_COLLECTION")
#define STR_CLOSE_COLLECTION_RQST PKG_NETWORK+183
stringtext(STR_CLOSE_COLLECTION_RQST,"CLOSE_COLLECTION")
#define STR_CLOSE_COLLECTION_RQST_ALT PKG_NETWORK+184
stringtext(STR_CLOSE_COLLECTION_RQST_ALT,"CLOSE_COLLECTION")
#define STR_UPDATE_COLLECTION_RQST PKG_NETWORK+185
stringtext(STR_UPDATE_COLLECTION_RQST,"UPDATE_COLLECTION")
#define STR_UPDATE_FILTERS_RQST PKG_NETWORK+186
stringtext(STR_UPDATE_FILTERS_RQST, "UPDATE_FILTERS")
#define STR_READ_ENTRIES_RQST PKG_NETWORK+187
stringtext(STR_READ_ENTRIES_RQST, "READ_ENTRIES")
#define STR_LOCATE_NOTE_RQST PKG_NETWORK+188
stringtext(STR_LOCATE_NOTE_RQST, "LOCATE_NOTE")
#define STR_FIND_NOTEID_RQST PKG_NETWORK+189
stringtext(STR_FIND_NOTEID_RQST, "FIND_NOTEID")
#define STR_UPDATE_NOTE_RQST_ALT PKG_NETWORK+190
stringtext(STR_UPDATE_NOTE_RQST_ALT, "UPDATE_NOTE")
#define STR_LOOKUP_HELP_NOTE_RQST PKG_NETWORK+191
stringtext(STR_LOOKUP_HELP_NOTE_RQST,"LOOKUP_HELP_NOTE")
#define STR_FIND_BY_KEY_RQST PKG_NETWORK+192
stringtext(STR_FIND_BY_KEY_RQST, "FIND_BY_KEY")
#define STR_NAME_LOOKUP_RQST PKG_NETWORK+193
stringtext(STR_NAME_LOOKUP_RQST, "NAME_LOOKUP")
#define STR_AUTHENTICATE_RQST PKG_NETWORK+194
stringtext(STR_AUTHENTICATE_RQST, "EXPLICIT_AUTHENTICATE")
#define STR_DB_SPACE_USAGE_RQST PKG_NETWORK+195
stringtext(STR_DB_SPACE_USAGE_RQST, "SPACE_USAGE")
#define STR_TEXT_SEARCH_RQST PKG_NETWORK+196
stringtext(STR_TEXT_SEARCH_RQST, "TEXT SEARCH")
#define ERR_QUIT PKG_NETWORK+197
errortext(ERR_QUIT, "Program shutdown in progress")
#define STR_ALLOC_UPOBJECT_RQST PKG_NETWORK+198
stringtext(STR_ALLOC_UPOBJECT_RQST, "ALLOC_UPDATE_OBJECT")
#define STR_FREE_UPOBJECT_RQST PKG_NETWORK+199
stringtext(STR_FREE_UPOBJECT_RQST, "FREE_UPDATE_OBJECT")
#define STR_NIFOPENNOTE_RQST PKG_NETWORK+200
stringtext(STR_NIFOPENNOTE_RQST, "NIF_OPEN_NOTE")
#define STR_NIFSTAMPNOTES_RQST PKG_NETWORK+201
stringtext(STR_NIFSTAMPNOTES_RQST, "NIF_STAMP_NOTES")
#define STR_GET_SERVER_NAMES_RQST PKG_NETWORK+202
stringtext(STR_GET_SERVER_NAMES_RQST,"GET_SERVER_NAMES")
#define STR_GET_SERVER_STATS_RQST PKG_NETWORK+203
stringtext(STR_GET_SERVER_STATS_RQST,"GET_SERVER_STATS")
#define STR_RELAY_EVENT_RQST PKG_NETWORK+204
errortext(STR_RELAY_EVENT_RQST, "RELAY_EVENT")
#define STR_FT_SEARCH_RQST PKG_NETWORK+205
stringtext(STR_FT_SEARCH_RQST, "FULL TEXT SEARCH")
#define STR_FT_CLOSE_SEARCH_RQST PKG_NETWORK+206
stringtext(STR_FT_CLOSE_SEARCH_RQST,"CLOSE FULL TEXT SEARCH")
#define STR_REMOTE_CONSOLE_RQST PKG_NETWORK+207
errortext(STR_REMOTE_CONSOLE_RQST, "REMOTE_CONSOLE")
#define STR_DB_SQUEEZE_RQST PKG_NETWORK+208
stringtext(STR_DB_SQUEEZE_RQST, "SQUEEZE DATABASE")
#define STR_FT_INDEX_RQST PKG_NETWORK+209
stringtext(STR_FT_INDEX_RQST, "BUILD FULL TEXT INDEX")
#define STR_FT_GET_LAST_INDEXTIME_RQST PKG_NETWORK+210
stringtext(STR_FT_GET_LAST_INDEXTIME_RQST, "GET LAST INDEX TIME")
#define STR_FT_DELETE_INDEX_RQST PKG_NETWORK+211
stringtext(STR_FT_DELETE_INDEX_RQST,"DELETE FULL TEXT INDEX")
#define STR_GET_NAMED_OBJECT_ID_RQST PKG_NETWORK+212
stringtext(STR_GET_NAMED_OBJECT_ID_RQST,"GET_NAMED_OBJECT_ID")
#define STR_DB_READ_HIST_RQST PKG_NETWORK+213
stringtext(STR_DB_READ_HIST_RQST,"READ REPLICATION HISTORY")
#define STR_DB_WRITE_HIST_RQST PKG_NETWORK+214
stringtext(STR_DB_WRITE_HIST_RQST,"WRITE REPLICATION HISTORY")
#define STR_GET_NOTE_INFO_BY_UNID_RQST PKG_NETWORK+215
stringtext(STR_GET_NOTE_INFO_BY_UNID_RQST,"GET_NOTE_INFO_BY_UNID")
#define STR_NAME_LOOKUPID_RQST PKG_NETWORK+216
stringtext(STR_NAME_LOOKUPID_RQST, "NAME_LOOKUPID")
#define STR_POLL_DEL_SEQNUM_RQST PKG_NETWORK+217
stringtext(STR_POLL_DEL_SEQNUM_RQST,"POLL_DEL_SEQNUM")
#define STR_GET_MULT_NOTE_INFO_RQST PKG_NETWORK+218
stringtext(STR_GET_MULT_NOTE_INFO_RQST,"GET_MULT_NOTE_INFO")
#define STR_GET_COLLECTION_DATA_RQST PKG_NETWORK+219
stringtext(STR_GET_COLLECTION_DATA_RQST,"GET_COLLECTION_DATA")

LotusScript Comment Templates for lsdoc.org (aka LotusScript.doc, aka Javadoc for LotusScript)

I am a big fan of Mikkel Heisterberg’s lsdoc.org for automatic help-page generation for LotusScript code. If you are not familiar with lsdoc.org, it’s similar to javadoc, but for LotusScript.

Ever since the advent of Code Templates, I’ve been using lsdoc-compatible syntax for my comments, and I wanted to share it with you here:

Comment Template – Sub

'/*************************************************************************************
' * ${element_type} ${element_name}
' * @param 
' * @author ${author}
' * @version ${date}
' *************************************************************************************/

Comment Template – Function

'/*************************************************************************************
' * ${element_type} ${element_name}:A function to
' * @param
' * @return
' * @author ${author}
' * @version ${date}
' *************************************************************************************/

Comment Template – class

'/*************************************************************************************
' * A Class to represent
' * @author ${author}
' * @version ${date}
' *************************************************************************************/

 
Update:
lsdoc.org is down, Mikkel unfortunately did not renew the domain name and it’s been taken over by some domain parkers. May they rot in hell, those guys! Mikkel told me that he will be probably loading the tool onto openntf, after Easter 2014, so please be patient.