Convert common names to Canonical names

If there any utility or code sample that would allow you to do a mass conversion of reader/author fields that were stored originally as common name into Canonical versions?

Subject: Convert common names to Canonical names

Kevin,

The code is easy to write, but you have to be confident that you’re looking up in the right N&A Book or Directory, if that’s how you do it.

regards,

raphael

Subject: RE: Convert common names to Canonical names

Raphael

We only have one address book currently.

What commands would I look for in Help? Or do you know of any sample code to get me started?

Thanks.

Subject: RE: Convert common names to Canonical names

Use this

@Name([CANONICALIZE]; @Name)

@Name([CANONICALIZE]; @UserName)

@Name([CANONICALIZE]; Field)

Subject: Here you go…

I just whipped this up for you in a couple of minutes…haven’t actually tested it but it should put you on the right track. You’ll need to change the Const values to match the field names you want to update in your documents.

Put this code into an agent which is set to run on all selected documents.

Alex


Sub Initialize

Dim Session As New NotesSession

Dim CurrDb As NotesDatabase

Dim NamesDb As NotesDatabase

Dim PersonDoc As NotesDocument

Dim UserNotesName As NotesName

Dim UsersView As NotesView

Dim DocCollection As NotesDocumentCollection

Dim Doc As NotesDocument

Dim ReadersField As NotesItem

Dim AuthorsField As NotesItem

Dim NamesArray As Variant

Dim ServerName As NotesName

Dim DocNumber As Long



' Error Handler

On Error Goto Error_Handler



' Set your constant values here

Const AddressBookPath = "names.nsf"

Const ReadersFieldName = "Readers"

Const AuthorsFieldName = "Authors"



Set CurrDb = Session.CurrentDatabase

Set DocCollection = CurrDb.UnprocessedDocuments



If DocCollection.Count = 0 Then

	' No documents were selected

	Exit Sub

End If



' Open the Address Book

Set ServerName = New NotesName(CurrDb.Server)

Set NamesDb = New NotesDatabase(ServerName.Abbreviated, AddressBookPath)



If NamesDb Is Nothing Then

	Messagebox "The address book could not be found.  Please ensure it exists and you have access to it.", 0+16, "Address Book Not Found"

	Exit Sub

End If



If Not NamesDb.IsOpen Then

	Messagebox "The address book could not be opened.  Please ensure you have access to it.", 0+16, "Address Book Not Opened"

	Exit Sub

End If



Set UsersView = NamesDb.GetView("($Users)")

If UsersView Is Nothing Then

	Messagebox "The $Users view in the address book could not be found.", 0+16, "Address Book View Not Found"

	Exit Sub

End If



' Scan all the selected documents

Set Doc = DocCollection.GetFirstDocument

While Not Doc Is Nothing

	DocNumber = DocNumber + 1

	Print "Processing document " & Trim(Cstr(DocNumber)) & " of " & Trim(Cstr(DocCollection.Count))

	

	' Handle the readers field

	If Doc.HasItem(ReadersFieldName) Then

		If Trim(Doc.GetItemValue(ReadersFieldName)(0)) <> "" Then

			Set NamesArray = Doc.GetItemValue(ReadersFieldName)

			Forall v_Name In NamesArray

				Set PersonDoc = UsersView.GetDocumentByKey(v_Name, True)

				If Not PersonDoc Is Nothing Then

					Set UserNotesName = New NotesName(PersonDoc.FullName(0))

				Else

					' Person document wasn't found...put the original value back into the field

					Set UserNotesName = New NotesName(v_Name)

				End If

				

				If ReadersField Is Nothing Then

					Set ReadersField = Doc.ReplaceItemValue(ReadersFieldName, UserNotesName.Canonical)

				Else

					Call ReadersField.AppendToTextList(UserNotesName.Canonical)

				End If

			End Forall

			

			' Set the field flags

			If Not ReadersField Is Nothing Then

				ReadersField.IsSummary = True

				ReadersField.IsReaders = True

			End If

		End If

	End If

	

	' Handle the authors field

	If Doc.HasItem(AuthorsFieldName) Then

		If Trim(Doc.GetItemValue(AuthorsFieldName)(0)) <> "" Then

			Set NamesArray = Doc.GetItemValue(AuthorsFieldName)

			Forall v_Name In NamesArray

				Set PersonDoc = UsersView.GetDocumentByKey(v_Name, True)

				If Not PersonDoc Is Nothing Then

					Set UserNotesName = New NotesName(PersonDoc.FullName(0))

				Else

					' Person document wasn't found...put the original value back into the field

					Set UserNotesName = New NotesName(v_Name)

				End If

				

				If AuthorsField Is Nothing Then

					Set AuthorsField = Doc.ReplaceItemValue(AuthorsFieldName, UserNotesName.Canonical)

				Else

					Call AuthorsField.AppendToTextList(UserNotesName.Canonical)

				End If

			End Forall

			

			' Set the field flags

			If Not AuthorsField Is Nothing Then

				AuthorsField.IsSummary = True

				AuthorsField.IsAuthors = True

			End If

		End If

	End If

	

	' Save the document

	Call Doc.Save(True, True)

	

	' Get the next document

	Set Doc = DocCollection.GetNextDocument(Doc)

Wend



Print "Conversion is now complete"

Exit Sub

Error_Handler:

Dim NewLine As String

NewLine = Chr(10) & Chr(13)

If Messagebox("The following error occurred: " & NewLine & "Error number: " & Cstr(Err) & NewLine & "Line number: " & Cstr(Erl) & NewLine & "Description: " & Error$ & NewLine & NewLine & "Do you want to continue processing?", 0+16, "An error has occurred") = 7 Then

	' The No button was clicked.  Stop processing

	Exit Sub

End If

Resume Next

End Sub

Subject: RE: Here you go…

Wow! I can’t believe you did all that. Thanks!

Subject: Always happy to help out!

Subject: Important code update

Kevin,

I just realized there was an important part of the code is missing. After saving each document the ReadersField and AuthorsField need to be cleared out otherwise on each consecutive document read they will just keep getting bigger & bigger.

Here’s the update…

Alex


.

.

.

.

Save the document

Call Doc.Save(True, True)

’ Reset the fields

If Not ReadersField Is Nothing Then

Delete ReadersField

End If

If Not AuthorsField Is Nothing Then

Delete AuthorsField

End If

’ Get the next document

Set Doc = DocCollection.GetNextDocument(Doc)

Wend

.

.

.

.