I gotta write an article on this… but here’s the gist of what I do:
Create a Form called “emailtemplate”
Add the following fields:
MailMergeFields
key
includeDoclink
$AutoForward
$KeepPrivate
Encrypt
DueDateTime
ExpireDate
Importance
searchcriteria
From
SendTo
CopyTo
BlindCopyTo
FaxToList
ReplyTo
subject
Body
You’ll want to set the field values to their logical counterpart in a given email message. IE., $AutoForward should be set to “1”, etc. (I’ll explain some other field specifics later in this post…)
Now, you create an agent (scheduled) called sched/Notifications|Notifications.
There’s several subs and functions that I put in my agent to get the job done, but here’s the gist of it:
You’re going to cycle through all email templates and do a search for any documents that match the criteria you’ll define in the emailtemplate’s “searchcriteria” field.
For example, the emailtemplate who’s key is “notification_newdoc” will have the following in it’s searchcriteria field:
Now, you’ll return a collection of such documents and run your notification agent against said documents. The thing that I do is do a basic mail merge against placeholder valyues in my given email.
For example, if I have a field in the document called “projectnumber”, I’ll put the following in the emailtemplate subject field:
Project Number # - Project Creation
I also build in the ability to (and here’s where the includeDoclink field comes into play) add a doclink where is placed (obviously in the Body field).
This allows me to control what’s being sent for my automated emailings by 1) forcing a From address to my application’s requirements, 2) having the ability to include attachments, doclinks or anything else you can cram into an email, as well as the mail-routing functional fields like $AutoForward which tells the message to not trigger OoO responses etc. It’s pretty damned functional IMHO.
If you’re interested in the code, let me know! I’ll check back here…
Dim s As New NotesSession
Dim db As NotesDatabase
Dim collection As NotesDocumentCollection
Dim tcollection As NotesDocumentCollection
Dim mserver As String, mdb As String
Dim doc As NotesDocument
Dim tdoc As notesdocument
Dim vw As NotesView, key As String
Dim dbtitle As String
Dim dateTime As NotesDateTime
Dim tdateTime As NotesDateTime
Set dateTime = New NotesDateTime( "Yesterday" )
Set tdateTime = New NotesDateTime( "01/01/2000" )
mserver = s.CurrentDatabase.Server
mdb = s.CurrentDatabase.FilePath
Set s = New NotesSession
Set db = s.CurrentDatabase
dbtitle = db.Title
Set vw = db.GetView("bykey")
Set tcollection = db.Search(|@LowerCase(Form) = "emailtemplate" & @LowerCase(Status) = "active"|, tdatetime, 0)
For t = 1 To tcollection.Count
Set tdoc = tcollection.GetNthDocument( t )
If (tdoc.searchcriteria(0) <> "") Then
Set collection = db.Search(tdoc.searchcriteria(0), datetime, 0)
If collection.Count > 0 Then
Msgbox dbtitle + | Notification Agent: There are | + Cstr(collection.Count) + | documents that reach the criteria defined in the "| + tdoc.description(0) + |" template.|
For i = 1 To collection.Count
Set doc = collection.GetNthDocument( i )
key = Cstr(tdoc.GetItemValue("key")(0))
Call sendEmail(doc, tdoc, key, s)
Next
Else
Msgbox dbtitle + | Notification Agent: There are no documents that reach the criteria defined in the "| + tdoc.description(0) + |" template.|
End If
Else
Msgbox dbtitle + | Notification Agent: There is no criteria defined in the "| + tdoc.description(0) + |" template.|
End If
Next
Sub sendEmail(doc As NotesDocument, tdoc As NotesDocument, key As String, s As NotesSession)
Dim db As NotesDatabase
Dim mserver As String, mdb As String
Dim vw As NotesView
Dim getMailbox As notesdatabase
Dim memo As NotesDocument
Dim tempRT As NotesRichTextItem
Dim mmf As NotesItem
Dim nSendTo As Variant, nCopyTo As Variant
Dim nBlindCopyTo As Variant, nFaxToList As Variant
Dim tempdoc As NotesDocument
mserver = s.CurrentDatabase.Server
mdb = s.CurrentDatabase.FilePath
Set db = s.CurrentDatabase
Set getMailbox = s.getdatabase ( mserver, "mail2.box")
If Not getMailbox.IsOpen Then
Set getMailbox = s.getdatabase ( mserver, "mail.box")
If Not getMailbox.IsOpen Then
Set getMailbox = s.getdatabase ( mserver, "mail1.box")
If Not getMailbox.IsOpen Then Exit Sub
End If
End If
If getMailbox.isopen Then
Set memo = getMailbox.CreateDocument
Set tempdoc = db.CreateDocument
Call tdoc.CopyAllItems( memo, True )
Call tdoc.CopyAllItems( tempdoc, True)
'Remove All Email Template-specific fields
Call memo.removeitem("Body")
Call memo.RemoveItem("vInclude")
Call memo.RemoveItem("MailMergeFields")
Call memo.RemoveItem("includeDoclink")
Call memo.RemoveItem("description")
Call memo.RemoveItem("status")
Call memo.RemoveItem("key")
Call memo.RemoveItem("searchcriteria")
'Remove All possibly troublesome fields
If Not(memo.ReplyTo(0) <> "") Then
Call memo.RemoveItem("ReplyTo")
End If
If Not(memo.DueDateTime(0) <> "") Then
Call memo.RemoveItem("DueDateTime")
End If
If Not(memo.Importance(0) <> "2" Or memo.Importance(0) <> "") Then
Call memo.RemoveItem("Importance")
End If
If Not(memo.GetItemValue("Encrypt")(0) <> "") Then
Call memo.RemoveItem("Encrypt")
memo.EncryptOnSend = False
Else
memo.EncryptOnSend = True
End If
Set mmf = tempdoc.GetFirstItem("MailMergeFields")
'Set string and variants in memory for Mail Merge
nSubject = memo.Subject(0)
nSendTo = memo.SendTo
nCopyTo = memo.CopyTo
nBlindCopyTo = memo.BlindCopyTo
nFaxToList = memo.FaxToList
'Iterate through all Mail Merge placeholders and replace with content from the document
Forall v In mmf.Values
Set tempRT = mailMergeRT(tempdoc, doc, Cstr("<" + v + ">"), Cstr(doc.GetItemValue(v)(0)))
nSubject = Cstr(ReplaceSubstring (nSubject, Cstr("<" + v + ">"), doc.GetItemValue(v)(0)))
nSendTo = mailMergeArray(nSendTo, Cstr("<" + v + ">"), Cstr(doc.GetItemValue(v)(0)))
nCopyTo = mailMergeArray(nCopyTo, Cstr("<" + v + ">"), Cstr(doc.GetItemValue(v)(0)))
nBlindCopyTo = mailMergeArray(nBlindCopyTo, Cstr("<" + v + ">"), Cstr(doc.GetItemValue(v)(0)))
nFaxToList = mailMergeArray(nFaxToList, Cstr("<" + v + ">"), Cstr(doc.GetItemValue(v)(0)))
End Forall
Msgbox nSubject
Call memo.ReplaceItemValue("Subject",nSubject)
Set rtitem = memo.CreateRichTextItem( "Body" )
Call rtitem.AppendRTItem( tempRT )
Call memo.ReplaceItemValue("Form","Memo")
Call memo.ReplaceItemValue("From",tdoc.From(0))
Call memo.ReplaceItemValue("Principal",tdoc.From(0))
memo.SendTo = nSendTo
memo.CopyTo = nCopyTo
memo.BlindCopyTo = nBlindCopyTo
memo.FaxToList = nFaxToList
'Build Recipient List for new Memo -- mail won't route without it!
memo.Recipients = Arrayappend(memo.Recipients, memo.SendTo)
memo.Recipients = Arrayappend(memo.Recipients, memo.CopyTo)
memo.Recipients = Arrayappend(memo.Recipients, memo.BlindCopyTo)
memo.Recipients = Arrayappend(memo.Recipients, memo.FaxToList)
memo.PostedDate = Now()
memo.DeliveredDate = Now()
memo.ComposedDate = Now()
Call memo.Save ( True, False )
'Create a new notesitem named the same value of the emailtemplate (minus "_active")
Call doc.ReplaceItemValue(key, "1")
Call doc.Save(False, False)
End If
Function mailMergeRT(tdoc As NotesDocument, doc As NotesDocument, searchString As String, replaceString As String) As NotesRichTextItem
Dim body As NotesRichTextItem
Dim rtnav As NotesRichTextNavigator
Dim rtrange As NotesRichTextRange
Set body = tdoc.GetFirstItem("Body")
Set rtnav = body.CreateNavigator
Call rtnav.FindFirstElement(RTELEM_TYPE_TEXTPARAGRAPH)
n% = 0
Set rtrange = body.CreateRange
While rtrange.FindAndReplace (searchString, replaceString, RT_REPL_ALL) > 0
n% = n% + 1
Call body.Update
Wend
If n% > 0 Then
Call body.Compact
End If
If tdoc.GetItemValue("includeDoclink")(0) = "1" Then
If rtnav.FindFirstString("<doclink>") Then
Call rtrange.SetBegin(rtnav)
Call body.BeginInsert(rtrange)
Call body.AppendText(" ")
Call body.AppendDocLink(doc, doc.title(0))
Call body.EndInsert
Set rtrange = body.CreateRange
Call rtnav.FindFirstElement(4)
Call rtrange.SetBegin(rtnav)
Call rtrange.FindAndReplace("<doclink>", " ", 1)
Call body.Compact
End If
End If
Set mailMergeRT = body
Function ReplaceSubstring (Byval expr1, Byval expr2, Byval expr3) As Variant
Dim pos As Long, length1 As Long, length2 As Integer
Dim result As Variant
pos = Instr (expr1, expr2)
length2 = Len (expr2)
If (pos > 0) Then
While (pos)
length1 = Len (expr1)
result = result + Left (expr1, pos-1) + expr3
expr1 = Right (expr1, length1-pos-length2+1)
pos = Instr (expr1, expr2)
Wend
result = result + Right (expr1, length1-pos-length2+1)
Else
result = expr1
End If
ReplaceSubstring = result
And that should give you a working agent. Just create the email templates, a view called “(bykey)|bykey” that’s categorized and sorted by “key”, and configure your notifications. Make the UI of the emailtemplate forms pretty and you’ve now got a fully-functional mail merge engine that will allow your database admins to maintain their own logic-based notifications without bugging you to “make COMMENTS bold” or something silly like that.
This isn’t “simple” in that it’s a one-liner or some hackery formula, but the implementation of this will make the configuration, maintenance, and the chores associated with what you’re trying to do THAT much more “simple”.
As for something that you can just copy/paste… that’s about a good as I can get it for the moment - too swamped to do much else in truth.
But what I’ve given ya was a pole, a stocked pond, and the blueprints on how to bait your line – hopefully that’s enough to keep you eating well after you make “COMMENTS” bold…
are you serious? who are you to ask for someone here to “give” you anything? Chris took the time to give you a working solution. what you want to do cannot be done in formula language so take what you got [for free] and be happy.
Yes, I am aware of that. How do I handle now? When you create a memo using @mailsend function the memo form is automatically in edit mode. Why it didn’t work?