You Can View User Feedback To This Tip
These two agents overcome a weakness within Notes R4 and R5: once you have created an agent and exited the designer you cannot change its PRIVATE/ SHARED flag. Manipulating two fields in the agent's design note the following two pieces of code can prevent you from re-writing the same agent with a different setting.Both codes are written as agents themselves (I designed them as "Manually From Actions Menu" and "Run Once"); they come with detailed in-code documentation. Please be aware that they use undocumented features, so precautions like backing up the original agents should be taken.
Agent 1: going from PRIVATE to SHARED:
======================================
Sub Initialize
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++
' + Agent "Change Agent to SHARED"
' + sub Initialize
' + lm/edcom 25-APR-2001
' + ===================================================
' + This agent changes another agent within the same database
' + from PRIVATE to SHARED;
' + Since there is no other way (at least none that I know of) it loops
' + through all possible Note IDs from 0x0001 to 0xFFFF; if the agent
' + isn't found within this range and misspelling can be excluded as a
' + reason the range has to be extended (resulting in longer
' + processing time !).
' + Once the agent to be changed is found the design note fields
' + "$AssistFlags" and "$Flags" are manipulated:
' + the first field controls the "Shared Agent" checkbox, the other is
' + a combination of various design note properties; both have to be
' + manipulated at the same time;
' + if "$AssistFlags" contains a "P" the checkbox is unmarked;
' + if "$Flags" contains a "V" the design note is marked as being
' + PRIVATE;
' +
' + USE THIS AGENT AT YOUR OWN RISK ! Be sure to make a
' + backup copy of the agent before manipulating it !!
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dim sn As New NotesSession
Dim thisdb As NotesDatabase
Dim coll As NotesDocumentCollection
Dim doc As NotesDocument
Dim agnt As NotesAgent
Dim strTitle As String
Dim strFlag As String
Dim strL As String
Dim strR As String
Dim strNID As String
Dim intSuccess As Integer
Dim intPos As Integer
Dim lngCnt As Long
intSuccess = False ' preset the SUCCESS flag
Set thisdb = sn.CurrentDatabase
strTitle = Ucase(Inputbox("Enter the agent's title: ", "CHANGE AGENT FLAGS"))
' looping Note IDs 0001 to FFFF
For lngCnt = 1 To 65535
strNID = Hex (lngCnt)
Set doc = thisdb.GetDocumentByID (strNID)
' is there a document with this Note ID ?
If Not doc Is Nothing Then
' if doc has an item by this name it must be an agent's design note
If doc.HasItem ("$AssistFlags") Then
' does the design note belong to our agent ?
If Ucase(doc.GetItemValue("$TITLE") (0)) = strTitle Then
' a "P" in the $AssistFlags string unchecks the "SHARED" checkbox in the agent designer
strFlag = doc.GetItemValue("$AssistFlags") (0)
intPos = Instr(strFlag, "P")
strL = Left(strFlag, intPos - 1)
strR = Mid(strFlag, intPos + 1)
Call doc.ReplaceItemValue("$AssistFlags", strL & strR)
' a "V" in the $Flags string marks the agent as being PRIVATE
strFlag = doc.GetItemValue("$Flags") (0)
intPos = Instr(strFlag, "V")
strL = Left(strFlag, intPos - 1)
strR = Mid(strFlag, intPos + 1)
Call doc.ReplaceItemValue("$Flags", strL & strR)
Call doc.Save (True, True)
' set the SUCCESS flag for a final message
intSuccess = True
Exit For ' no further looping necessary
End If ' UCASE($TITLE)...
End If ' HasItem($AssistFlags)
End If ' not doc is nothing
Next
If intSuccess Then
Msgbox "The agent " & strTitle & " is now marked as 'Shared'. " &_
"The change will be visible after closing and re-opening the database", _
64, "AGENT FLAGS CHANGED"
Else
Msgbox "An agent named " & strTitle & " could not be found", 64, "AGENT FLAGS NOT CHANGED"
End If
End Sub
=======================================
Agent 2: going from SHARED to PRIVATE:
=======================================
Sub Initialize
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++
' + Agent "Change Agent to PRIVATE"
' + sub Initialize
' + lm/edcom 25-APR-2001
' + ===================================================
' + This agent changes another agent within the same database
' + from SHARED to PRIVATE;
' + Since there is no other way (at least none that I know of) it loops
' + through all possible Note IDs from 0x0001 to 0xFFFF; if the agent
' + isn't found within this range and misspelling can be excluded as a
' + reason the range has to be extended (resulting in longer
' + processing time !).
' + Once the agent to be changed is found the design note fields
' + "$AssistFlags" and "$Flags" are manipulated:
' + the first field controls the "Shared Agent" checkbox, the other is
' + a combination of various design note properties; both have to be
' + manipulated at the same time;
' + if "$AssistFlags" contains a "P" the checkbox is unmarked;
' + if "$Flags" contains a "V" the design note is marked as being
' + PRIVATE;
' + the person performing this manipulation wil be the new owner of
' + the now private agent
' +
' + USE THIS AGENT AT YOUR OWN RISK ! Be sure to make a
' + backup copy of the agent before manipulating it !!
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dim sn As New NotesSession
Dim thisdb As NotesDatabase
Dim coll As NotesDocumentCollection
Dim doc As NotesDocument
Dim agnt As NotesAgent
Dim strTitle As String
Dim strFlag As String
Dim strL As String
Dim strR As String
Dim strNID As String
Dim intSuccess As Integer
Dim intPos As Integer
Dim lngCnt As Long
intSuccess = False ' preset the SUCCESS flag
Set thisdb = sn.CurrentDatabase
strTitle = Ucase(Inputbox("Enter the agent's title: ", "CHANGE AGENT FLAGS"))
' looping Note IDs 0001 to FFFF
For lngCnt = 1 To 65535
strNID = Hex (lngCnt)
Set doc = thisdb.GetDocumentByID (strNID)
' is there a document with this Note ID ?
If Not doc Is Nothing Then
' if doc has an item "$AssistFlags" it must be an agent's design note
If doc.HasItem ("$AssistFlags") Then
' does the design note belong to our agent ?
If Ucase(doc.GetItemValue("$TITLE") (0)) = strTitle Then
' a "P" in the $AssistFlags string unchecks the "SHARED" checkbox in the agent designer
strFlag = doc.GetItemValue("$AssistFlags") (0) & "P"
Call doc.ReplaceItemValue("$AssistFlags", strFlag)
' a "V" in the $Flags string marks the agent as being PRIVATE;
' the person running this agent will become its owner
strFlag = doc.GetItemValue("$Flags") (0)
intPos = Instr(strFlag, "f")
strL = Left(strFlag, intPos)
strR = Mid(strFlag, intPos + 1)
Call doc.ReplaceItemValue("$Flags", strL & "V" & strR)
Call doc.Save (True, True)
' set the SUCCESS flag for a final message
intSuccess = True
Exit For ' no further looping necessary
End If ' UCASE($TITLE)...
End If ' HasItem($AssistFlags)
End If ' not doc is nothing
Next
If intSuccess Then
Msgbox "The agent " & strTitle & " is now marked as 'PRIVATE'. " &_
"The change will be visible after closing and re-opening the database", _
64, "AGENT FLAGS CHANGED"
Else
Msgbox "An agent named " & strTitle & " could not be found", 64, "AGENT FLAGS NOT CHANGED"
End If
End Sub
- The agent implements the fastest way to get the NoteID of a design element that is referenced by name and type (such as Agent - "Periodic Archive", Form - "Customer," etc). Instead of parsing the NoteID's from 0001 to FFFF, this function uses an on-disk index of NOTE_CLASS types and is very efficient. The code has been tested using Lotus Designer Release 5.0.4 under a win32 platform.
Option Public Declare Function NIFFindDesignNote Lib "nnotes.dll" (Byval hDb As Long, Byval noteName As Lmbcs String, Byval classType As Integer, hNote As Long) As Integer Declare Function NSFDbOpen Lib "nnotes.dll" (Byval sDbName As Lmbcs String , hDb As Long) As Integer Declare Function NSFDbClose Lib "nnotes.dll" (Byval hDb As Long) As Integer Declare Function OSPathNetConstruct Lib "nnotes.dll" (Byval portName As Integer, Byval serverName As Lmbcs String, Byval fileName As Lmbcs String, Byval pathName As Lmbcs String) As Integer Const MAXPATH = 256 Const NOTE_CLASS_FORM = 0004 ' form note Const NOTE_CLASS_VIEW = 0008 ' view note Const NOTE_CLASS_FILTER = 0512 ' filter note Const NOTE_CLASS_FIELD = 1024 ' field note Function getNoteID(Byval servername As String,Byval filename As String,Byval notename As String, Byval notetype As Integer) As Long Dim hdb As Long Dim hnote As Long Dim pathname As String*MAXPATH Dim result As Integer 'OSPathNetConstruct creates a full network path - pathname - specification for a Domino database file Call OSPathNetConstruct(0, servername, filename, pathname) 'NSFDbOpen returns a handle - hdb - to a database - pathname - result = NSFDbOpen(pathname, hdb) If result <> 0 Then Messagebox("Cannot open the database!") getNoteID = -1 Goto endf End If 'NIFFindDesignNote function returns the note ID of a form, view, shared folder, agent, or field note, given the name and NOTE_CLASS_xxx result = NIFFindDesignNote(hdb, notename, notetype, hnote) If result <> 0 Then Messagebox("Cannot find the note!") getNoteID = -1 Goto dbclose End If getNoteID = hnote dbclose: 'NSFDbClose closes a previously opened database result = NSFDbClose(hdb) If result <> 0 Then Messagebox("Cannot close the database!") End If endf: End Function --------------------------------------------------------- This is a small example of how to use the function above: --------------------------------------------------------- Sub Initialize Dim s As New NotesSession Dim db As NotesDatabase Dim noteID As Long Dim strNID As String Dim servername, dbname, notename As String servername="SearchDomino" ' "" for local dbname="Tips.nsf" notetype = NOTE_CLASS_FILTER ' agent notename = "Periodic Archive" Set db = s.GetDatabase(servername, dbname) noteID = getNoteID(servername, dbname, notename, notetype) If noteID = -1 Then Goto ends End If strNID = Hex(noteID) Set doc = db.GetDocumentByID (strNID) If Not doc Is Nothing Then 'Process NoteID document End If ends: End Sub Catalin Popescu
This was first published in May 2001