Search

Top Ten List

Of all my ramblings, people seem to find the following the most interesting:
  1. Pimp My Fields
  2. Using the WebBrowser control to view attachments inline
  3. Purty charts in Domino
  4. My approach to DbLookup and DbColumn in Javascript
  5. Mind Map of Database Design
  6. Design Catalog - version control for Domino
  7. Workaround for LotusScript event binding
  8. Clickable URL's in Notes view columns
  9. Every time you use window.open, God kills a kitten
  10. Create, edit, and delete without agents via AJAX

« ASCII and Atbash Ciphers | Main| Fun with Pass-Thru HTML »

"Quick and dirty" field maps with LotusScript lists

Category domino

Many have said this before, but it seems to remain true, so I'll echo the sentiment: the most under-utilized data type in LotusScript is the List. According to Domino Designer Help, "A list is a one-dimensional collection of elements of the same data type." Put another way, it's an array indexed with strings rather than integers. This makes it incredibly easy to work with. For one thing, you don't have to Redim a list each time you need to add a value (or allocate enough space ahead of time); simply assign a value to a "list tag":

 

Dim lstrStateCapitals List As String
lstrStateCapitals("Colorado") = "Denver"

 

When you need to retrieve the value later, it's equally easy:

 

strCurrentStateCapital = lstrStateCapitals("Colorado") 'Returns "Denver"

 

Finally, if you no longer need to store the value:

 

Erase lstrStateCapitals("Colorado") 'Omitting the tag erases the entire list

 

In the examples above, both the list tag and the value are strings, but list values can be any data type, as long as they are the same throughout. You could, for example, define a list of NotesDatabase handles, allowing you to refer to them later by their title; you could store a list of NotesDocumentCollection handles, allowing you to group different collections of documents by various labels. Lists can even contain user-defined classes - for example, a list of Employee objects (please note: this is referring to how each employee would be treated by the code, not necessarily by their employer) as a property of a Department class, allowing each list element to be referred to by name, employee ID, or any other uniquely identifying string. Uniqueness being the key, as any existing Employee can be replaced by specifying a new Employee with the same list tag... thank goodness it's not that simple in real life.

 

Now, this all sounds pretty idyllic, particularly if you're new to the data type, but there are a couple things you may want to be aware of before you start replacing all your array-based code with lists:

  1. By default, list tags are case sensitive. To override this, you must specify Option Compare NoCase in the module containing the list declaration. Otherwise, value assignment and retrieval will treat otherwise identical tags of varying case as entirely distinct elements.
  2. Although lists can contain (and be members of) user-defined classes, they may not be used as members of user defined data types.
  3. Domino Designer Help offers no warnings regarding performance issues with lists, but I choose to avoid them if I anticipate needing to store an extremely large number of elements and / or manipulate them rapidly. This is because of how completely dynamic this data type is: you don't ever have to tell it how many values you need to store, or that you're about to add or remove an element... you just do it. Which means that memory has to be allocated on the spot before the new element can be stored - which I suspect requires a very brief delay, undetectable unless dealing with extremely large lists - and must recover memory when an element is erased. It's possible that this actually happens, but there's a very subtle discrepancy in the Help at this point: it is specifically stated that, when erasing arrays (whether fixed or dynamic) or entire lists, storage is recovered; in the case of erasing a single list element, however, it states only that the element no longer exists in the list. It's possible that the meaning is identical, but for some reason I just don't trust that. So if any of you have stored an exorbitant number of elements in a list without ill effects, please let me know.

All limitations aside, it occurred to me this afternoon that one scenario in which this data type might quickly and easily provide a solution is in field mapping. Stop me when this sounds familiar: you've got two data stores (maybe both Domino databases, maybe not), and the users need the data copied or moved from one store to another. Although procedurally the applications are identical, the field names used are not: Author in one  is the equivalent of Originator in the other, Title = Subject, and, for some unfathomable reason, DueDate = Untitled_1_9_4.  A quick and easy way to store this equivalence would be as follows:

 

Dim lstrTargetFieldNames List As String
lstrTargetFieldNames("Author") = "Originator"
lstrTargetFieldNames("Title") = "Subject"
lstrTargetFieldNames("DueDate") = "Untitled_1_9_4"

 

Ideally, of course, these mappings should be stored as data, not code, perhaps somewhere in either the source or target location. For example, you could loop through a view that displays only field mapping definition documents:

 

Set ndocFieldMap = nvwFieldMap.GetFirstDocument
Do While Not (ndocFieldMap Is Nothing)
 strSourceFieldName = ndocFieldMap.GetItemValue("SourceFieldName")(0)
 strTargetFieldName = ndocFieldMap.GetItemValue("TargetFieldName")(0)
 lstrTargetFieldNames(strSourceFieldName) = strTargetFieldName
 Set ndocFieldMap = nvwFieldMap.GetNextDocument(ndocFieldMap)
Loop

 

One very handy feature available to the List data type is the Listtag function. This is only available within a Forall loop, and simply returns the tag of the list item currently being processed by the loop. Hence, once a list has been defined that maps source data field names to target field names, only three lines of code are needed to process each equivalent pair of documents:

 

Forall strListValue In lstrTargetFieldNames
 Call ndocTarget.ReplaceItemValue(strListValue, ndocSource.GetItemValue(Listtag(strListValue)))
End Forall

 

Naturally, you'd also have to save each target document, but the point is that this approach is easy, efficient, and - assuming the list is indeed initially populated via database lookups (or config / INI files) and not hardcoded - extremely dynamic, and can therefore be reused ad infinitum with little or no need for code modification each time.

Contact Me

Hire Me

Elsewhere

What the Quote?

"They're all after me lucky charms."

Declan Sciolla-Lynch

"Dance, my puppets!!! DANCE!!!"

Nathan Freeman

"In the year 7000, August 1st will be on a Wednesday."

Brent Bowers

"Uh, maybe it's because you don't bend that way?"

Steven Rodgers

"Then again, you're the only person I know who can sing like bagpipes."

Tim Tripcony

Apparel

Lotus Rocks

I write the code that makes the young girls cry

Current Terror Alert Level

Assorted Linkage

ClustrMap