Display Date Range As Bar In Notes Views

You can find a lot of stuff on the internet like Chris Blatnick’s ” Using Color Columns To Make A Gantt Chart” to display column values either as color or as picture ( you might take a look at “A Splash of Color” as well ).
Today I would like to share my solution on how to build a view to display a date range like it is used in group calendar applications.

Display Calendar Entries

I tried to keep the view design as simple as possible to avoid performance impacts. As you can see in the sample database there are no formulas in the columns. All necessary information is stored in a “collector” document.

Form Design

The form contains one field for each day in a month ( Day_1 … Day_31 ). All fields are of type text with multiple values enabled. To colorize Day_1 ( and all subsequent colums ) simply put 0 : 255 : 255 into Day_1 which results in an aquamarine color.
Surfing the web for more information about view column colors I found this article on breakingpar.com.
Instead of using 6 decimal numbers for foreground and background color, you can use hexadecimal values as well. This would make it easier to handle the data when passing it via LotusScript to the collector document.

We can now build a list of colorcodes.

' Declaration

Dim ColorCode List As String

Sub Initialize
	ColorCode("Alice_Blue") = "F0F8FF"
	ColorCode("Antique_White") = "FAEBD7"
	ColorCode("Aqua") = "00FFFF"
	ColorCode("Aquamarine") = "7FFFD4"
	ColorCode("Azure") = "F0FFFF"
	ColorCode("Beige") = "F5F5DC"
	ColorCode("Bisque") = "FFE4C4"
	ColorCode("Black") = "000000"
	ColorCode("Blanched_Almond") = "FFEBCD"
	ColorCode("Blue") = "0000FF"
	ColorCode("Blue_Violet") = "8A2BE2"

...
End Sub

You can call the following function and pass a colorcode from the list as a parameter. You can use any hexadecimal value that is not in the list as well.

Function SetMarker ( doc As NotesDocument, user As String,_
DateFrom As NotesDateTime, DateTo As NotesDateTime, color As String ) As Integer

	On Error Goto ERR_HANDLE
	SetMarker = 0
	Dim item As NotesItem
	Dim i As Integer
	Dim MarkerBegin As Integer
	Dim MarkerEnd As Integer
	Dim MarkerColor (1) As String

	If Iselement(ColorCode( color)) Then
		MarkerColor(0) = ColorCode( color)
		MarkerColor(1) = ColorCode( color)
	Else
		MarkerColor(0) = color
		MarkerColor(1) = color
	End If

	MarkerBegin = Day ( DateFrom.DateOnly )
	MarkerEnd = Int ( Day ( DateTo.DateOnly )) + 1

	Set Item = doc.ReplaceItemValue ( DAY_FLD_PREFIX + Cstr( MarkerBegin ), MarkerColor)
	If MarkerEnd - MarkerBegin > 1 Then
		For i = (MarkerBegin +1) To (MarkerEnd -1)
			Set Item = doc.ReplaceItemValue ( DAY_FLD_PREFIX + Cstr ( i ), "" )
		Next
	End If
	If Not ( MarkerEnd > 31 ) Then
		Set Item = doc.ReplaceItemValue ( DAY_FLD_PREFIX + Cstr ( MarkerEnd ), "FFFFFFF" )
	End If
	Call doc.Save ( False, False )

EXITPOINT:
	Exit Function
ERR_HANDLE:
	SetMarker=1
End Function

The function writes the necessary values to the document. It translates the DateFrom and DateTo parameters and writes the according colorcodes. As you can see in the next screenshot, only two fields are needed to build a bar for a date range.

Values

Notes colorizes the column displaying the colorcode from the document and subsequent columns as long as you do not set the column to another color. Any hexadecimal value longer than 6 will reset the column color to default.

DOWNLOAD Sample Database


Instance member…does not exist’ when enabling Out Of Office

Today I had a lot of calls in our helpdesk regarding Out Of Office. Users complained that the had enabled the agent before Christmas and it worked fine but when they tried to disable the agent it does not disable. Instead the Out Of Office profile shows the following message:

Even it is in German, I think I do not have to translate the blue text as you might know that this is the message that is displayed when a user has editor access to his mail file and tries to enable / disable the Out Of Office agent.
With editor access an administration request is created that will enable / disable the agent on behalf of the user.

Well, nothing special so far. Except the fact that this message is displayed to the user all day long and I could not find any administration request on the server.

I tried to reproduce the error on my workstation but failed. I opened the users desktop remotely and there it was. An error message occurred in the statusbar stating that there is a

Notes error: 182 Instance member CONFIGUREMAILAGENTTEXT does not exist.

I searched the Knowledge Base for CONFIGUREMAILAGENTTEXT and found this technote

In Lotus Notes®, you attempt to enable the Out Of Office (OOO) agent in your mail file. The agent does not enable and you notice the following error message in the status bar of the Notes client:

“Notes error: 182 Instance member CONFIGUREMAILAGENTTEXT does not exist.”

This issue only occurs for users with Editor access to their mail file and only occurs in Notes, regardless of the mail template design being used. The issue does not occur when using Lotus Domino® Web Access (DWA) mail.

So, what has happened?

On December, 29th, 2007 I did a mass change on the users mail files to ensure that all ACL only have editor access with all options set except ‘Can Create personal agents’.

We use Domino server version 7.0.3 and Notes Client version 7.0.2 with a slightly modified dwa7.ntf mail template. The changes do not touch the Out Of Office profile !

Reading the technote mentioned before, I found the following hint:

NOTE: The DWA7 client that ships with the Notes/Domino 7.0.2 release is incompatible with all previous versions of Notes.

All previous versions of Notes? Does this mean version 7.0.1, too ?
To make a long story short; yes it means that version 7.0.1 is not compatible with dwa7.ntf shipped with client version 7.0.2.

And yes, we have some clients still using this version. Exactly the same users who are not able to disable the Out of Office agent are on this ‘old’ client version.

To solve the puzzle, I will have to update the clients ASAP J

Another option ( according to the technote ) is to grant designer access. I used the following code to do the changes out of the Domino Directory.

Create a new agent in the DD ( Select from menue, All selected documents ) and copy the following code into the agent.

Option Public
Option Declare

'Use "OpenLogFunctions"
Sub Initialize
	'On Error Goto Errorhandler
	Dim ws As New NotesUIWorkspace
	Dim session As New NotesSession
	Dim db As NotesDatabase
	Dim dc As NotesDocumentCollection
	Dim doc As NotesDocument
	Dim total As Long
	Dim docnum As Long

	Set db = session.CurrentDatabase

	Set dc = db.UnprocessedDocuments
	total = dc.Count
	docnum = 0

	Set doc = dc.GetFirstDocument
	While Not doc Is Nothing
		docnum = docnum + 1
		Call UpdateStatusBar(docnum, total)
		Call ProcessPersonDoc(doc)
		Set doc = dc.GetNextDocument(doc)
	Wend

	Call ws.ViewRefresh
	'Exit Sub

Errorhandler:
	'Call LogError
	'Exit Sub

End Sub

Sub UpdateStatusBar(x As Long, total As Long)
	'This will display the percentage complete in the status bar as the agent runs

	Print "Working..." & Cstr(Round((x / total), 2)*100) & "% done"

End Sub

Sub ProcessPersonDoc(doc As NotesDocument)
	'On Error Goto stackError
	Dim s As New NotesSession
	Dim profile As NotesDocument
	Dim owner As String
	Dim ACL As NotesACL
	Dim ACLEntry As NotesACLEntry
	Dim nn As NotesName

	Dim Maildb As New NotesDatabase( doc.MailServer(0), doc.MailFile(0) )
	If Maildb.IsOpen Then
		Print( "Succesfully opened " & Maildb.Title )
		Set profile = Maildb.GetProfileDocument("CalendarProfile")
		Set nn = s.CreateName ( profile.Owner(0) )

		Set ACL = MailDB.ACL
		Set ACLEntry = ACL.GetEntry ( profile.Owner(0) )
		If Not ( ACLEntry Is Nothing ) Then
			ACLEntry.Remove
			ACL.Save
		End If

		'Set OWNER access to DESIGNER
		Set ACLENtry = New NotesACLEntry ( ACL, profile.Owner(0), 5 )
		ACLENtry.CanDeleteDocuments = True
		ACLENtry.CanCreateLSOrJavaAgent = True
		ACLENtry.IsPerson = True
		ACL.Save

	End If

EXITPOINT:
	'Exit Sub
stackError:
	'Call LogError()
	'Resume EXITPOINT
End Sub

Now you can select one or more persons and run the agent against their mail file. The agent will read the calendar profile to determine the mail file owner and then changes the ACL.


Compare Two Arrays

For one of my projects I needed a function to compare two arrays. The following function returns true if both array have the same elements (regardless of their position in arrays).

Function ArraysAreEqual (vA As Variant, vB As Variant) As Variant

	Dim IsEqual As Variant
	ArraysAreEqual = True

	Forall a In vA
		IsEqual = False
		Forall b In vB
			If a = b Then
				IsEqual = True
				Exit Forall
			End If
		End Forall
		If Not IsEqual Then
			ArraysAreEqual = False
			Exit Function
		End If
	End Forall

	Forall b In vB
		IsEqual = False
		Forall a In vA
			If b = a Then
				IsEqual = True
				Exit Forall
			End If
		End Forall
		If Not IsEqual Then
			ArraysAreEqual = False
			Exit Function
		End If
	End Forall

End Function

To execute your code only when both array are different simply use

	If Not (ArraysAreEqual ( mBefore, mAfter )) Then
	   ' your code goes here
           ' ...

	End If

Mail Archivierung – Ein Praxisproblem

Eigentümer einer Maildatei können Zugriffe auf Mails und Kalender über “Werkzeuge – Vorgaben – Zugriff und Delegierung” selbstständig steuern.
Bei der geplanten Archivierung von Mails ergeben sich daraus aber Probleme beim Zugriff auf archivierte Dokumente.

Ein Archivsystem sichert neben den eigentlichen Inhalten der Mail auch die zu diesem Zeitpunkt existierende ACL.

ACL

Lt. der abgebildeten ACL darf also neben dem Eigentümer der Maildate auch der Administrator lesend auf die Mails zugreifen und somit auch auf archivierte Mails.
Wird der Zugriff für den Leser Administrator wieder entfernt, so kann er weder auf die Datenbank noch auf Mails zugreifen, die nach diesem Zeitpunkt archiviert wurden. Sehr wohl kann er aber noch über die Archivrecherche auf Mails zugreifen, die vor dem Zeitpunkt der Löschung seines Zugriffs aus der ACL in das Archiv gespeichert wurden.

Die Probleme, die sich daraus ergeben können, sollen hier nicht weiter erläutert werden.

Ein in der Praxis wohl häufiger auftretendes Problem erfordert aber unbedingte AUfmerksamkeit; eine Lösung muss VOR Beginn der Mailarchivierung implementiert werden.

Dabei geht es um folgendes Szenario:

Ein Vorgesetzter delegiert den Zugriff auf seine Mails an eine Assistentin, die namentlich in die ACL eingetragen wird. Ã?ber einen gewissen Zeitraum werden nun Mails mit diesen Zugriffsberechtigungen archiviert.
Die bisherige Assistentin wird dann einem neuen Vorgesetzten zur Seite gestellt, oder vertritt eine Kollegin.

In Variante 1 hat dann die neue Assistentin keinen Zugriff auf die bisher archivierten Mails, weil sie bisher ja keinen Zugriff auf die Datenbank ihres Vorgesetzen hatte.
In Variante 2 kann nicht auf die archivierten Mails der zusätzlichen Datenbank zugegriffen werden, weil es an den nötigen Berechtigungen zum Zeitpunk der Archivierung fehlt.

Lösen lässt sich dieses Dilemma, wenn man in die ACL der Datenbank eine Gruppe einfügt, die auf die Datenbank Lesezugriff hat.

Hier stösst man aber zugleich auf ein weiteres Problem. Alle Einträge, die in der ACL nicht als MANAGER oder ENTWICKLER eingetragen sind, können vom Eigentümer der Datenbank über die Vorgaben geändert werden. Das betrifft sowohl die Art des Zugriffs als auch das Löschen des Eintrags.

Zugriff und Delegierung

Da wir aber der Gruppe keine Berechtigung als Manager geben wollen, müssen wir anderweitig sicherstellen, daÃ? der MailBox Eigentümer die Rechte der Gruppe nicht ändern kann.
Das kann am Einfachsten dadurch erreicht werden, daÃ? die Gruppe für den Eigentümer gar nicht sichtbar ist.

versteckte Gruppe

Mit einem kleinen Eingriff in die Gestaltung der Maildatei kommt man zum Ziel. Bei Einführung einer Mailarchivierung wird man in der Regel sowieso die Maildatei modifizieren müssen; bei der einen Lösung mehr, bei einer anderen weniger.
Die Modifikation zum Verstecken der Gruppe(n) sind so minimal, daÃ? sie im Prinzip nicht ins Gewicht fallen. Trotzdem sollten die Codeänderungen dokumentiert werden. 🙂

In der Script Bibliothek “ACLManagement” wird der Code ab Zeile 578 ( +/- 2 Zeilen ) folgendermaÃ?en geändert

alt:

Case ACLLEVEL_READER
    x = Ubound(Me.ReadMail)
    Me.ReadMail(x) = Me.aclentry.Name
    Redim Preserve Me.ReadMail(x+1)
    Call IsPublicReader()
    Call IsPublicWriter()

neu:

Case ACLLEVEL_READER
    x = Ubound(Me.ReadMail)
    '############## 26.10.2007,Ulrich Krause ################
    If ( Not Instr(Me.aclentry.Name, "#Arc" ) > 0 ) Then
     Me.ReadMail(x) = Me.aclentry.Name
     Redim Preserve Me.ReadMail(x+1)
     Call IsPublicReader()
     Call IsPublicWriter()
   End If

Durch diese einfache Ã?nderung ist es nun möglich, in die ACL der Maildatenbanken Gruppen einzufügen, die mit dem Prefix “#Arc” beginnen. Der Eintrag in das Domino Directory und die Pflege der Gruppenmitglieder erfolgt dann bei Bedarf manuell.
Der Name der Gruppe wird aus dem Prefix und z.B. den Namen des Mail Box Eigentümers gebildet. Damit lässt sich dann der Zugriff datenbankspeziefisch steuern. Eine weitere Gruppe “#ArcDefaultReaders” mit ACLLEVEL_READER kann dann in gleicher Weise zur datenbankübergreifenden Recherche verwendet werden.

Dies ist die aus meiner Sicht einfachste Lösung um sicherzustellen, daÃ? unterschiedliche Personen auf archivierte Mails zugreifen können.


PING in LotusScript

Die Klasse PING enhält die Funktion Ping(), der die zu überpr?fende Adresse als Zeichenkette in der Form “127.0.0.1” übergeben wird. Ist der Ping erfolgreich wird true zurückgegeben,ansonsten false.

Die Konstante TIMEOUT gibt an, wie viele Millisekunden ( DEFAULT = 500 ms ) die Funktion versuchen soll, den Zielrechner zu erreichen. Zum Testen der Funktion erstellen sie einen Button und kopieren sie den folgenden Code in den Click Event der Schaltfläche

Read More


Lotus Script Klasse “Systeminformationen”

Lotus Script Klasse mit folgenden Funktionen:

    kleine/ grosse Schriftarten installiert
    Ist eine Soundkarte installiert
    Anzahl Farben
    Tastatur Typ
    Anzahl Funktionstasten
    Hostname
    IP Adresse des Host
    aktuelle Bildschirmaufloesung
    CPU Taktfrequenz
    Anzahl Processoren
    Prozessor Typ
    Prozessor Build Level
    Prozessor Revision
    Betriebssystem
    Windows Systemverzeichnis
    Notes Verzeichnis
    Welche COM Ports sind verfuegbar
    Dateisystem, Label und
    Seriennummer der Festplatte
    Neustart von Windows ( auch Windows 2000 !!
    LockWorkstation
    Internet – Verbindungsstatus

DOWNLOAD