Aug 01

Lotus Notes Improvements

Hynek Kobelka has 37 improvement request for Lotus Notes, reminded me of some options that I would like for the LotusScript debugger as mentioned before.  This even made it to Ed Brill‘s discussion "If I could add ONE feature to Lotus Notes 7.x, it would be…".  

Back to the list of 37, some of the improvements have been discussed by Mary Beth Raven and others so I will not touch on those.  
9. Calendar-Alarms get the focus while working in a different application – The alarm window just needs help.  Take a look at the other’s alarm implementation.
10. Add a "File-Attach" – Button into the Memo-Form – makes sense, why disable the option when you know where it should go.
12. Display in the mail file the current usage of the quota – Yes this would be nice.
13. Give us a "-Cancelled-" Status for Calendar-Entries –  The strike through should only be there until I remove it from my calendar.  It would be nice to see the meeting is being canceled if I have not looked at my Inbox.
15. Make Type-Ahead a "combobox" –  Yes, showing a list is much better.
17. Contacts in the Mail-DB – YES!!!
24. Resorting of a view should be "cleared" once the user closes and reopens a database –  I would disagree,  I like it when it remembers what I want.
27. Create a function which is only available from a Conflict-Document "COMPARE WITH PARENT" – That would be sweet.
33. Computed View-Column-Titles – Please

Another improvement would be to Implement type ahead for class I create, not just the Domino classes.  The next thing on my list would be to redesign the properties box, so here are some thoughts:
  • Nothing else that I know uses this concept
  • Why does it always change size
  • If I position it towards the bottom then I could lose some information when I select another tab
  • I do like the floating concept
  • Why does Notes not realize that the properties box is position outside of the screen when I am forced to lower my resolutoin, why
  • I find my self browsing through the tabs to find something because I can never remember what the icons mean
Jun 14

Session.DocumentContext something isn't right

If you ran the following code in the Web Query Save agent that was assigned to a form with a subject field. The original value of subject was "Truck" and the new value entered on the web was "Car". The Web Query Save agent code was:
Dim Session As New NotesSession
Dim docBefore As NotesDocument
Dim documentContext As NotesDocument
Dim docAfter As NotesDocument

Set docBefore = Session.CurrentDatabase.getDocumentByUNID( "f02506889e2d5cfc8625712f001b02f9" )
Msgbox "Before: " +
docBefore.subject(0) Set documentContext = Session.DocumentContext
Msgbox "Context: " + documentContext.subject(0)
Set docAfter = Session.CurrentDatabase.getDocumentByUNID( "f02506889e2d5cfc8625712f001b02f9" )
Msgbox "After:" +
docAfter.subject(0)
I was expecting to see:
Before: Truck
Context: Car
After: Truck

What I saw was:
Before: Truck
Context: Car
After: Truck

Domino seems to read the document from the database until the DocumentContext is used at which the document is read from memory where the changes are allready made. This will make my job capturing what has change for Open Audit a litte hard, thus take a little more time.
Jun 08

Template Build Class 1.1.0

Updated the Template Build Class to include a build number that will be different the build version. The build version is text which could have 1.1.0, 1.0.0 beta 1, etc. The build number is an actual number and would be 40, 100, etc. Here are the methods available:
Public Sub new( )Public Function GetVersionField() As NotesDocument
Public Function getTemplateBuildName( ) As String
Public Function setTemplateBuildName( BuildName As String )
Public Function getTemplateBuild( ) As String
Public Function setTemplateBuild( Build As String )
Public Function getTemplateBuildNumber( ) As Double
Public Function setTemplateBuildNumber( BuildNumber As Double )
Public Function getTemplateBuildDate( ) As NotesDateTime
Public Function setTemplateBuildDate( BuildDate As NotesDateTime )
Public Function hasTemplateBuild( ) As Boolean
Public Sub Save( )
Public Sub delete( )

Template Build Class

Option Public
Option Declare
 
'/**
' * Notes/Domino uses a shared field called $TemplateBuild to store the current
' * build number, build name and build date this class will allow access to the shared field
' * both to read and update.
' *
' * History
' *14 Apr 2005	Christopher J Doig	Initial version
' *30 May 2006	Chad Schelfhout ( http://www.chadsmiley.com )
' *		Converted function to class
' *		Setters and getters for Build information
' * 		Allow the creation of the shared field if it does not exist
' *8 June 2006	Chad Schelfhout ( http://www.chadsmiley.com )
' *		Added TemplateBuildNumber which is a number not text.  This will allow the comparison to see if a new version is available.
' */
Class TemplateBuild
	SharedFieldTitleName As String
	SharedFieldName As String
	TemplateBuildNameField As String
	TemplateBuildNumberField As String
	TemplateBuildField As String
	TemplateBuildDateField As String
 
	docTemplateBuild As NotesDocument
	session As NotesSession
	saveDocTemplateBuild As Boolean
	Public Sub New ()
		SharedFieldTitleName = "$Title"
		SharedFieldName = "$TemplateBuild"
		TemplateBuildNameField = "$TemplateBuildName"
		TemplateBuildNumberField = "$TemplateBuildNumber"
		TemplateBuildField = "$TemplateBuild"
		TemplateBuildDateField = "$TemplateBuildDate"
 
		Set session = New NotesSession
		saveDocTemplateBuild = False
		Call GetVersionField()
	End Sub
'/*
' * 	Attempt to load the Build information if it is not there then import the DXL to create
' * the shared field then try and load the Build information again.
' */
	Public Function GetVersionField () As NotesDocument
		Call attemptLoad()
		If docTemplateBuild Is Nothing Then
			Call createBuildTemplateField()
			Call attemptLoad()
		End If
		Set GetVersionField = docTemplateBuild
	End Function
 
'/*
' * Search for the shared field called $TemplateBuild
' */
	Private Sub attemptLoad() 
 
		Dim doc As NotesDocument
		Dim nc As NotesNoteCollection
		Dim item As NotesItem
		Dim strID As String
 
		Set nc = session.CurrentDatabase.CreateNoteCollection ( False )
		nc.SelectSharedFields = True
		Call nc.BuildCollection
		strID = nc.GetFirstNoteId
 
		Set docTemplateBuild = Nothing
		Do Until strID = ""
			Set doc = session.CurrentDatabase.GetDocumentByID ( strID )
			Set item = doc.GetFirstItem ( SharedFieldTitleName )
			If item.Text = SharedFieldName Then
				Set docTemplateBuild = doc
				Exit Do
			End If
			strID = nc.GetNextNoteId ( strID )
		Loop
	End Sub
'/*
' * Import a shared field called $TemplateBuild
' */
	Private Sub createBuildTemplateField()
 
		Dim importer As NotesDXLImporter
		Set importer = session.CreateDXLImporter
 
		importer.DesignImportOption = DXLIMPORTOPTION_CREATE
		Call importer.Import( |<!--?xml version='1.0' encoding='utf-8'?-->
 
					Application Name
 
					0.0.0
 
					0
 
					20050815T000000,00-07
 
		| , Session.CurrentDatabase )
		saveDocTemplateBuild = True
	End Sub
'/*
' * Get, Set Template Build Name
' */
	Public Function getTemplateBuildName As String
		getTemplateBuildName = ""
		If hasTemplateBuild Then
			If docTemplateBuild.HasItem( TemplateBuildNameField ) Then
				getTemplateBuildName = docTemplateBuild.getFirstItem( TemplateBuildNameField ).text
			End If
		End If
	End Function
	Public Sub setTemplateBuildName ( BuildName As String )
		If hasTemplateBuild Then
			Call docTemplateBuild.ReplaceItemValue( TemplateBuildNameField ,  BuildName )
			saveDocTemplateBuild = True
		End If
	End Sub
 
'/*
' * Get, Set Template Build
' */
	Public Function getTemplateBuild As String
		getTemplateBuild = ""
		If hasTemplateBuild Then
			If docTemplateBuild.HasItem( TemplateBuildField ) Then
				getTemplateBuild = docTemplateBuild.getFirstItem( TemplateBuildField ).text
			End If
		End If
	End Function
	Public Sub setTemplateBuild ( Build As String )
		If hasTemplateBuild Then
			Call docTemplateBuild.ReplaceItemValue( TemplateBuildField ,  Build )
			saveDocTemplateBuild = True
		End If
	End Sub
 
'/*
' * Get, Set Template Build Number
' */
	Public Function getTemplateBuildNumber As Double
		getTemplateBuildNumber = 0
		If hasTemplateBuild Then
			If docTemplateBuild.HasItem( TemplateBuildNumberField ) Then
				If ( Isnumeric( docTemplateBuild.getFirstItem( TemplateBuildNumberField ).text  ) ) Then
					getTemplateBuildNumber = Cdbl( docTemplateBuild.getFirstItem( TemplateBuildNumberField ).text )
				End If
			End If
		End If
	End Function
	Public Sub setTemplateBuildNumber ( BuildNumber As Double )
		If hasTemplateBuild Then
			Call docTemplateBuild.ReplaceItemValue( TemplateBuildNumberField ,  BuildNumber )
			saveDocTemplateBuild = True
		End If
	End Sub
 
'/*
' * Get, Set Template Build Date
' */
	Public Function getTemplateBuildDate As NotesDateTime
		Set getTemplateBuildDate = New NotesDateTime( "0/0/0" )
		If hasTemplateBuild Then
			If ( docTemplateBuild.HasItem( TemplateBuildDateField ) ) Then
				Set getTemplateBuildDate = docTemplateBuild.getFirstItem( TemplateBuildDateField ).dateTimeValue
			End If
		End If
	End Function
	Public Sub setTemplateBuildDate ( BuildDate As NotesDateTime )
		If hasTemplateBuild Then
			Call docTemplateBuild.ReplaceItemValue( TemplateBuildDateField ,  BuildDate )
			saveDocTemplateBuild = True
		End If
	End Sub
 
	Public Function hasTemplateBuild As Boolean
		hasTemplateBuild = Not ( docTemplateBuild Is Nothing)
	End Function
 
	Public Sub Save()
		If saveDocTemplateBuild Then
			Call docTemplateBuild.Save( True , False )
			saveDocTemplateBuild = False
		End If
	End Sub
	Public Sub delete
		Call save
	End Sub
End Class
May 31

Template Build Class

Updated code to remove extra XML information

Chris suggested that a web service be made available for projects to check for updates at openNTF. Vince implemented this rather quickly so I started to testing it on my projects. Everything worked great, but what I noticed was that I now have to maintain this information in both the ‘Check for Updates’ agent and the $TemplateBuild shared field so that it shows in the database properties.

Remember Chris Doig’s tool to set the build information using a notes database (Great Tool). There is duplicate information in these two tools causing me to maintain the build information in both places. Hopefully I have provided a class that can help reduce the duplicity. The Template Build class will allow the setting and getting of the Template Build, Template Build Name and Template Build Date of the $TemplateBuild shared field. This can be used by the web service to get the information, Chris’s tool can use it to set the information, and anyone else can use it to set or get the information. Then everyone will be happy, at least I will be!!

Here are the methods available:
Public Sub new( )<br>
Public Function GetVersionField() As NotesDocument<br>
Public Function getTemplateBuildName( ) As String<br>
Public Function setTemplateBuildName( BuildName As String )<br>
Public Function getTemplateBuild( ) As String<br>
Public Function setTemplateBuild( Build As String )<br>
Public Function getTemplateBuildDate( ) As NotesDateTime<br>
Public Function hasTemplateBuild( ) As Boolean<br>
Public Sub delete( )<br>


Template Build Class

Option Public
Option Declare
 
'/**
' * Notes/Domino uses a shared field called $TemplateBuild to store the current 
' * build number, build name and build date this class will allow access to the shared field
' * both to read and update.  
' *
' * History
' *14 Apr 2005	Christopher J Doig	Initial version
' *30 May 2006	Chad Schelfhout ( http://www.chadsmiley.com )
' *		Converted function to class
' *		Setters and getters for Build information
' * 		Allow the creation of the shared field if it does not exist
' */
Class TemplateBuild
	SharedFieldTitleName As String
	SharedFieldName As String
	TemplateBuildNameField As String
	TemplateBuildField As String
	TemplateBuildDateField As String
 
	docTemplateBuild As NotesDocument
	session As NotesSession
	saveDocTemplateBuild As Boolean
	Public Sub New ()
		SharedFieldTitleName = "$Title"
		SharedFieldName = "$TemplateBuild" 
		TemplateBuildNameField = "$TemplateBuildName"
		TemplateBuildField = "$TemplateBuild"
		TemplateBuildDateField = "$TemplateBuildDate"
 
		Set session = New NotesSession
		saveDocTemplateBuild = False
		Call GetVersionField()
	End Sub
'/*
' * 	Attempt to load the Build information if it is not there then import the DXL to create
' * the shared field then try and load the Build information again.
' */
	Public Function GetVersionField () As NotesDocument
		Call attemptLoad()
		If docTemplateBuild Is Nothing Then
			Call createBuildTemplateField()
			Call attemptLoad()
		End If
		Set GetVersionField = docTemplateBuild
	End Function
 
'/*
' * Search for the shared field called $TemplateBuild
' */
	Private Sub attemptLoad() 
 
		Dim doc As NotesDocument
		Dim nc As NotesNoteCollection
		Dim item As NotesItem
		Dim strID As String
 
		Set nc = session.CurrentDatabase.CreateNoteCollection ( False )
		nc.SelectSharedFields = True
		Call nc.BuildCollection
		strID = nc.GetFirstNoteId
 
		Set docTemplateBuild = Nothing
		Do Until strID = ""
			Set doc = session.CurrentDatabase.GetDocumentByID ( strID )		
			Set item = doc.GetFirstItem ( SharedFieldTitleName )
			If item.Text = SharedFieldName Then
				Set docTemplateBuild = doc
				Exit Do
			End If
			strID = nc.GetNextNoteId ( strID )
		Loop
	End Sub
'/*
' * Import a shared field called $TemplateBuild
' */
	Private Sub createBuildTemplateField()
 
		Dim importer As NotesDXLImporter
		Set importer = session.CreateDXLImporter
 
		importer.DesignImportOption = DXLIMPORTOPTION_CREATE
		Call importer.Import( |<?xml version='1.0' encoding='utf-8'?><!DOCTYPE sharedfield>
		<sharedfield name='$TemplateBuild' xmlns='http://www.lotus.com/dxl' language='en'>
	<field type='text' kind='editable' name='$TemplateBuild'/>
	<item name='$TemplateBuildName' sign='true'>
		<textlist>
			<text>Application Name</text>
		</textlist>
	</item>
	<item name='$TemplateBuild' sign='true'>
		<textlist>
			<text>0.0.0</text>
		</textlist>
	</item>
	<item name='$TemplateBuildDate' sign='true'>
		<datetimelist>
			<datetime dst='true'>19010101T000000,00-07</datetime>
		</datetimelist>
	</item>
</sharedfield>| , Session.CurrentDatabase )
		saveDocTemplateBuild = True
	End Sub
'/*
' * Get, Set Template Build Name
' */	
	Public Function getTemplateBuildName As String
		getTemplateBuildName = ""
		If hasTemplateBuild Then
			If docTemplateBuild.HasItem( TemplateBuildNameField ) Then
				getTemplateBuildName = docTemplateBuild.getFirstItem( TemplateBuildNameField ).text
			End If
		End If
	End Function
	Public Sub setTemplateBuildName ( BuildName As String )
		If hasTemplateBuild Then
			Call docTemplateBuild.ReplaceItemValue( TemplateBuildNameField ,  BuildName )
			saveDocTemplateBuild = True
		End If
	End Sub
 
'/*
' * Get, Set Template Build
' */	
	Public Function getTemplateBuild	As String
		getTemplateBuild = ""
		If hasTemplateBuild Then
			If docTemplateBuild.HasItem( TemplateBuildField ) Then
				getTemplateBuild = docTemplateBuild.getFirstItem( TemplateBuildField ).text
			End If
		End If
	End Function
	Public Sub setTemplateBuild ( Build As String )
		If hasTemplateBuild Then
			Call docTemplateBuild.ReplaceItemValue( TemplateBuildField ,  Build )
			saveDocTemplateBuild = True
		End If
	End Sub
 
'/*
' * Get, Set Template Build Date
' */	
	Public Function getTemplateBuildDate As NotesDateTime
		Set getTemplateBuildDate = New NotesDateTime( "0/0/0" )
		If hasTemplateBuild Then
			If ( docTemplateBuild.HasItem( TemplateBuildDateField ) ) Then
				Set getTemplateBuildDate = docTemplateBuild.getFirstItem( TemplateBuildDateField ).dateTimeValue
			End If
		End If
	End Function
	Public Sub setTemplateBuildDate ( BuildDate As NotesDateTime )
		If hasTemplateBuild Then
			Call docTemplateBuild.ReplaceItemValue( TemplateBuildDateField ,  BuildDate )
			saveDocTemplateBuild = True
		End If
	End Sub
 
	Public Function hasTemplateBuild As Boolean
		hasTemplateBuild = Not ( docTemplateBuild Is Nothing)
	End Function
 
	Public Sub delete 
		If saveDocTemplateBuild Then
			Call docTemplateBuild.Save( True , False )
			saveDocTemplateBuild = False
		End If
	End Sub
End Class
May 25

Open Audit 1.0.0 Beta 1

Collage of configuration options I have created my second openNTF project which will allow developers to create audit documents when field changes.  All configuration will be controlled through a configuration document for a given form.  Open Audit is currently in beta, I am looking for some feed back to see if this will be useful for developers before I continue to develop the rest of the tool.  Currently on the Notes UI has been implemented, which is the toughest part (just my opinion).

Here is where Open Audit is at as of 1.0.0 Beta 1
New Features
  • Configurable audit key
  • Field filter and field exclusion filter, with wildcards
  • Field descriptions to assign more meaningful names
  • Retention based on days or number of versions
  • External audit database or current database
Not Implemented
  • Backend audit class
  • Java audit class
  • Retention agent
May 23

Line Break Class

Simple class to get the necessary characters to create a line break. The line break is needed for prompts, input, and others. There is not much to explain once you see the available methods:
Public   Sub  new  (   )  As  String 
Public   Function  getLineBreakSession (  Session As  NotesSession   )  As  String
Public   Function  getLineBreak (   )  As  String 
Public   Function  getWindows (   )  As  String
Public   Function  getMacintosh (   )  As  String
Public   Function  getUnix (   )  As String
Public   Function  getLinux (   )  As  String
The first code block is the traditional LotusScript coding where you will need to create an instance of LineBreak in order to use it. The second follows the concept of simulating an abstract concept. This allows LineBreak.getLineBreak() to be called from anywhere at any time as long as the class is included.

Line Break

 Option Declare
 
'/**
' *	Determines what line break to use base on the platform.
' *	
' *	@author	Chad Schelfhout ( http:///www.chadsmiley.com)
' * @since		1.0.0
' */
Class LineBreak
	Private pSession As notesSession
'/**
' *	Constructor
' */
	Public Sub new ( )
		Set pSession = New NotesSession
	End Sub
'/**
' *	Get the type of line break based off the current session
' */
	Public Function getLineBreakSession( Session As NotesSession )As String
		Set pSession = Session
		getLineBreakSession = getLineBreak()
	End Function
'/**
' * determines the current line break based off the current platform
' */
	Public Function getLineBreak() As String
		If pSession Is Nothing Then
			Set pSession = New NotesSession()
		End If
		Select Case pSession.Platform()
		Case "Windows/32":
			getLineBreak = getWindows()
		Case "Macintosh":
			getLineBreak = getMacintosh()
		Case "Unix":
			getLineBreak = getUnix()
		Case "Linux":
			getLineBreak = getLinux()
		End Select
	End Function
'/**
' *	Returns the Windows line break
' */
	Public Function getWindows() As String
		getWindows = Chr$(13) & Chr$(10)
	End Function
'/**
' *	Returns the Mac line break
' */
	Public Function getMacintosh() As String
		getMacintosh = Chr$(13)
	End Function
'/**
' *	Returns the Unix line break
' */
	Public Function getUnix() As String
		getUnix = Chr$(10)
	End Function
'/**
' *	Returns the Linx line break
' */
	Public Function getLinux() As String
		getLinux = Chr$(10)
	End Function
End Class


Line Break simulate abstract class

Option Declare
 
'/**
' * Global variable to simulate an abstract class that is why it is named
' * the same as the class.
' */
Dim LineBreak As LineBreak
 
'/**
' *	Determines what line break to use base on the platform.
' *	
' * @author	Chad Schelfhout ( http:///www.chadsmiley.com)
' * @since		1.0.0
' */
Class LineBreak
	Private pSession As notesSession
'/**
' *	Constructor
' */
	Public Sub new ( )
		Set pSession = New NotesSession
	End Sub
'/**
' *	Get the type of line break based off the current session
' */
	Public Function getLineBreakSession( Session As NotesSession )As String
		Set pSession = Session
		getLineBreakSession = getLineBreak()
	End Function
'/**
' * determines the current line break based off the current platform
' */
	Public Function getLineBreak() As String
		If pSession Is Nothing Then
			Set pSession = New NotesSession()
		End If
		Select Case pSession.Platform()
		Case "Windows/32":
			getLineBreak = getWindows()
		Case "Macintosh":
			getLineBreak = getMacintosh()
		Case "Unix":
			getLineBreak = getUnix()
		Case "Linux":
			getLineBreak = getLinux()
		End Select
	End Function
'/**
' *	Returns the Windows line break
' */
	Public Function getWindows() As String
		getWindows = Chr$(13) & Chr$(10)
	End Function
'/**
' *	Returns the Mac line break
' */
	Public Function getMacintosh() As String
		getMacintosh = Chr$(13)
	End Function
'/**
' *	Returns the Unix line break
' */
	Public Function getUnix() As String
		getUnix = Chr$(10)
	End Function
'/**
' *	Returns the Linx line break
' */
	Public Function getLinux() As String
		getLinux = Chr$(10)
	End Function
End Class
'/**
' * Instanciate the global variable that will act like an abstract class
' */
Sub Initialize
	Set LineBreak = New LineBreak()
End Sub