Chris
Miller is one of the best
Domino administrators alive. He regularly writes for the SocialBiz
user group and answers difficult
questions about Domino administration, like last week's From
the SocialBiz Mailbox: Excluding Calendars from Mail-in Databases
You all probably know those unnecessary
"errors" the Scheduler writes each time, when it encounters a
mail database, where it cannot find the database's owner in the Domino
directory anymore.
SchedMgr: Error processing calendar
profile document (NoteID: NT....) in database...:
Can't find $BusyName field on profile
SchedMgr: Error processing calendar
profile document (NoteID: NT...) in database ...:
Cannot find user in Domino Directory
Perhaps, the user has left the company,
doesn't use this mail database anymore or the database simply is a mail-in
database.
The Scheduler task is important to validate
and update freetime information about current users, but in the above cases,
the mail database doesn't include important calendar information anymore.
Thus it would be great to just tell the Schedule: "Please, ignore
this database".
And Chris knows a solution: There is
a small program "NoCal" to do this magic little trick.
But it has some limitations:
- It's really, really old: Release: R5, Platform: Windows 95/98/NT, Date Posted: 04.05.2001
- it has to be run from the command line and
- it just can switch off the "Has Calendar" database option.
I
felt this itching again: Can't I do better than this?
- Something small and transportable like an agent, you can easily put in your mail(-in) database template or any database, you want,
- it should be easy to switch on and off this option and
- it can be run comfortably in the Notes client.
And I did it with
through investigations, lot of tries (and failures) and some C API calls:
The basic agent looks like this:
Sub
Initialize
'/**
'
* gets current database's options, prints "Has Calendar" option,
'
* toggles it and prints new status
'
*
'
* @author Thomas Bahn/assono <tbahn@assono.de>
'
* @version 2014-07-17
'
*/
Dim
session As
NotesSession
Dim
returnCode As
Integer
Dim
hDB As
Long
Dim
retDbOptions As
Long
On
Error
GoTo
miniErrorHandler
Set
session = New
NotesSession
'
open the current database
returnCode = NSFDbOpen(session.CurrentDatabase.FilePath,
hDB)
Call
ShowCAPIErrorIfAnyAndEnd(returnCode, "NSFDbOpen",
hDB)
'
get current options
returnCode = NSFDbGetOptions(hDB,
retDbOptions)
Call
ShowCAPIErrorIfAnyAndEnd(returnCode, "NSFDbGetOptions",
hDB)
'
print current status
If
retDbOptions And
DBOPTION_HAS_CALENDAR Then
Print
"Database has calendar"
Else
Print
"Database doesn't have
calendar"
End
If
'
toggle option
returnCode = NSFDbSetOptions(hDB,
_
retDbOptions
Xor
DBOPTION_HAS_CALENDAR, _
DBOPTION_HAS_CALENDAR)
Call
ShowCAPIErrorIfAnyAndEnd(returnCode, "NSFDbSetOptions",
hDB)
'
get current options
returnCode = NSFDbGetOptions(hDB,
retDbOptions)
Call
ShowCAPIErrorIfAnyAndEnd(returnCode, "NSFDbGetOptions",
hDB)
'
print new status
If
retDbOptions And
DBOPTION_HAS_CALENDAR Then
Print
"Database now has calendar"
Else
Print
"Database now doesn't
have calendar"
End
If
'
close the database
returnCode = NSFDbClose(hDB)
Exit
Sub
miniErrorHandler:
MessageBox
"Error #"
& Err
& " occurred in
line " & Erl
& Chr$(10)
&_
"Error
message: " & Chr$(10)
& Error$,
48,
"Error"
If
hDB <> 0
Then
' if there is a valid handle,
try to close database
returnCode = NSFDbClose(hDB)
End
If
End
Sub
It needs some (Declarations):
' STATUS LNPUBLIC NSFDbOpen(char
far *PathName, DBHANDLE far *rethDB);
Declare
Function
NSFDbOpen Lib
"nnotes.dll"
(ByVal
pathName As
LMBCS String,
rethDB As
Long)
As
Integer
' WORD LNPUBLIC OSLoadString(HMODULE
hModule, STATUS StringCode, char far *retBuffer, WORD BufferLength);
Declare
Function
OSLoadString Lib
"nnotes"
Alias
"OSLoadString"
(ByVal
hModule As
Long,
ByVal
stringCode As
Integer,
ByVal
retBuffer As
LMBCS
String,
ByVal
bufferLength As
Integer)
As
Integer
' STATUS LNPUBLIC NSFDbGetOptions(DBHANDLE
hDB, DWORD far *retDbOptions);
Declare
Function
NSFDbGetOptions Lib
"nnotes.dll"
(ByVal
hDB As
Long,
retDbOptions As
Long)
As
Integer
' STATUS LNPUBLIC NSFDbSetOptions(DBHANDLE
hDB, DWORD DbOptions, DWORD Mask);
Declare
Function
NSFDbSetOptions Lib
"nnotes.dll"
(ByVal
hDB As
Long,
ByVal
dbOptions As
Long,
ByVal
mask As
Long)
As
Integer
' STATUS LNPUBLIC NSFDbClose(DBHANDLE
hDB);
Declare
Function
NSFDbClose Lib
"nnotes.dll"
(ByVal
hDB As
Long)
As
Integer
' DBOPTION_HAS_CALENDAR
- TRUE if database stores calendar events.
Const
DBOPTION_HAS_CALENDAR& = &H00002000
Const
NOERROR = 0
Const
NULLHANDLE = 0&
And two support functions for the C
API error handling:
Sub
ShowCAPIErrorIfAnyAndEnd(errorCode As
Integer,
functionName As
String,
hDB As
Long)
'/**
'
* shows user the C API error and aborts execution.
'
*
'
* @param errorCode return code of the
function's execution
'
* @param functionName name of the C
API function called
'
* @param hDB handle to the open database
'
*
'
* @author Thomas Bahn/assono <tbahn@assono.de>
'
* @version 2014-07-17
'
*/
If
errorCode = NOERROR Then
Exit
Sub
' exit if no error occured
MessageBox
_
"An
error occurred in C API function '"
& functionName & "'"
& Chr$(10)
&_
"Error
code: " & Trim$(Str$(errorCode))
& Chr$(10)
& _
"Error
message:" & Chr$(10)
& GetCAPIErrorMsg(errorCode), _
48,
"Error calling C API"
If
hDB <> 0
Then
' if there is a valid handle,
try to close database
Call
NSFDbClose(hDB)
End
If
End
End
Sub
Function
GetCAPIErrorMsg(errorCode As
Integer)
As
String
'/**
'
* gets error message for the C API error.
'
*
'
* @param errorCode return code of the
function's execution
'
* @return error message for the C API
error
'
*
'
* @author Thomas Bahn/assono <tbahn@assono.de>
'
* @version 2014-07-17
'
*/
Dim
length As
Integer
Dim
buffer As
String
'
initialize a buffer of adequate length to accept the error string
buffer = String$(256,
0)
'
get the API error message from the internal Notes/Domino string tables
length = OSLoadString(NULLHANDLE,
errorCode, buffer, Len(buffer))
If
length > 0
Then
' remove
any trailing characters from the string
GetCAPIErrorMsg = Left$(buffer,
InStr(1,
buffer, Chr$(0))
- 1)
Else
' couldn?t
locate the error message in the string tables
GetCAPIErrorMsg = "Unknown
error"
End
If
End
Function
Just create an agent, which is started
manually and has a target of "None".
A small database with the ready-to-copy-agent:
ToggleHasCalendarOption.zip
(52
KB)
The database also contains an extended
version of the agent to change this option in another database,
which the user the choose first. Then the current status of the 'Has Calendar'
option is displayed and the user is asked, if he wants to change it.
Important: As far as I know does
this database option not replicate! Thus you probably have to switch
it off on all servers.