gurusimran
asked on
Scheduling Send Newsletter Action
I'm trying to schedule a "Send newsletter summary" simple action in an agent. I can run the agent fine if I set it to trigger "on event" with the target set to "all documents in view" The problem is that if I change the trigger to "On schedule" so I could have it run daily, the "all documents in view" option is no longer available.
I'm looking for help either getting this simple action working on a schedule, sending out a newsletter summary of the view I've created, OR instructions for an alternative solution (lotusscript, etc?).
Thank you
I'm looking for help either getting this simple action working on a schedule, sending out a newsletter summary of the view I've created, OR instructions for an alternative solution (lotusscript, etc?).
Thank you
It is very simple to do it using Lotus Script.
In your scheduled agent add this code (in Initialize event):
'You first have to do what sjef suggested to get a view:
Dim s As New NotesSession
Dim db As Notesatabase
Dim v As NotesView
Dim nl As NotesNewsletter
Dim c As NotesDocumentCollection
Dim doc As NotesDocument
Set db = s.CurrentDatabase
Set v = db.GetView( <Your view's name in double quotes> )
'Then you need this peace of code to collect documentCollection and create Newsletter summary:
Set c = db.Search( v.SelectionFormula, Nothing, 0 )
If( c.Count > 0 ) Then
Set nl = s.CreateNewsletter( c )
Set doc = nl.FormatMsgWithDoclinks( db )
doc.Form = "Memo"
doc.Subject = "The Report"
Call doc.Send( False, "The name of mail recipient" )
End If
I haven't tested this so post a question if something goes wrong.
Good luck,
Marko
In your scheduled agent add this code (in Initialize event):
'You first have to do what sjef suggested to get a view:
Dim s As New NotesSession
Dim db As Notesatabase
Dim v As NotesView
Dim nl As NotesNewsletter
Dim c As NotesDocumentCollection
Dim doc As NotesDocument
Set db = s.CurrentDatabase
Set v = db.GetView( <Your view's name in double quotes> )
'Then you need this peace of code to collect documentCollection and create Newsletter summary:
Set c = db.Search( v.SelectionFormula, Nothing, 0 )
If( c.Count > 0 ) Then
Set nl = s.CreateNewsletter( c )
Set doc = nl.FormatMsgWithDoclinks( db )
doc.Form = "Memo"
doc.Subject = "The Report"
Call doc.Send( False, "The name of mail recipient" )
End If
I haven't tested this so post a question if something goes wrong.
Good luck,
Marko
Hi Marko,
Try to avoid db.Search, it searches a database sequentially. And why do you need to search a view if all documents are concerned? I looked for an easier way to get a NotesDocumentCollection, but it doesn't exist (except for FTSearch, but you need toi set up full-text searching). Strange that a NotesView doesn't have an AllDocuments property...
Sjef
PS Just a hint: it's a "piece" of code...
Try to avoid db.Search, it searches a database sequentially. And why do you need to search a view if all documents are concerned? I looked for an easier way to get a NotesDocumentCollection, but it doesn't exist (except for FTSearch, but you need toi set up full-text searching). Strange that a NotesView doesn't have an AllDocuments property...
Sjef
PS Just a hint: it's a "piece" of code...
That's true Sjef,
but this is all happening in a background agent so noone will wait for it watching the screen.
You can build the collection by creating an empty one and then loop through the view and use col's method AddDocument.
When you first look at this solution the problem is how to create an empty collection, but you can easely create one using Responses property of a profile doc.
Marko
but this is all happening in a background agent so noone will wait for it watching the screen.
You can build the collection by creating an empty one and then loop through the view and use col's method AddDocument.
When you first look at this solution the problem is how to create an empty collection, but you can easely create one using Responses property of a profile doc.
Marko
O, and tanx for piece :)
I was indeed thinking that: where the xxx do I get an empty collection from? You're right:
Set doc= New NotesDocument(db)
Set dc= doc.Responses
I was merely considering the processing it requires to do a db.Search on a 40 Gb database, on a server that's already doing a lot. If there's one newsletter to be sent: big deal. And then there are 100 newsletters... Optimization always has to be in the back of your head, that's the only thing I wanted to say.
Set doc= New NotesDocument(db)
Set dc= doc.Responses
I was merely considering the processing it requires to do a db.Search on a 40 Gb database, on a server that's already doing a lot. If there's one newsletter to be sent: big deal. And then there are 100 newsletters... Optimization always has to be in the back of your head, that's the only thing I wanted to say.
ASKER
Thank you all for the quick responses. I'll try what you suggested tomorrow and let you know if I have questions.
Here's the tested and improved (but not optimized) solution:
Sub Initialize
Dim s As New NotesSession
Dim db As NotesDatabase
Dim v As NotesView
Dim nl As NotesNewsletter
Dim c As NotesDocumentCollection
Dim doc As NotesDocument
Set db = s.CurrentDatabase
Set v = db.GetView( "view name" )
Set c = db.Search( v.SelectionFormula, Nothing, 0 )
If( c.Count > 0 ) Then
Set nl = s.CreateNewsletter( c )
nl.DoScore = False 'if you don't want relevance score
nl.DoSubject = True 'to be able to specify subject of each doc
nl.SubjectItemName = "field name" 'name of the item in the doc which contains subject
Set doc = nl.FormatMsgWithDoclinks( db )
doc.Form = "Memo"
doc.Subject = "The Report"
Call doc.Send( False, "Recipient's name" )
End If
End Sub
The optimized solution is comming...
Sub Initialize
Dim s As New NotesSession
Dim db As NotesDatabase
Dim v As NotesView
Dim nl As NotesNewsletter
Dim c As NotesDocumentCollection
Dim doc As NotesDocument
Set db = s.CurrentDatabase
Set v = db.GetView( "view name" )
Set c = db.Search( v.SelectionFormula, Nothing, 0 )
If( c.Count > 0 ) Then
Set nl = s.CreateNewsletter( c )
nl.DoScore = False 'if you don't want relevance score
nl.DoSubject = True 'to be able to specify subject of each doc
nl.SubjectItemName = "field name" 'name of the item in the doc which contains subject
Set doc = nl.FormatMsgWithDoclinks( db )
doc.Form = "Memo"
doc.Subject = "The Report"
Call doc.Send( False, "Recipient's name" )
End If
End Sub
The optimized solution is comming...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hmm... You get an error on asking the Responses from a new document?? A Save might have done the trick ( a GetProfileDocument implicitly saves a new profile document).
For the rest: brilliant! I hope you know that EE is not a rent-a-coder site? ;)
For the rest: brilliant! I hope you know that EE is not a rent-a-coder site? ;)
Sjef:
I think that save will do the trick.
Gurusimran:
The important thing to say here is that the signer of the agent should have the ability to delete docs in the ACL, but if it's not possible then simply comment the line:
Call dummyDoc.Remove( True ) and you're good to go.
Sjef:
Yes, yes, not rent-a-coder, I know, but got carried away :)
Won't happen again :)
BTW Sjef, do you think that the good idea would be that EE pay a percentage of points in $.
Wouldn't that generate more $ traffic for them also?
Sorry for my "poetic" english,
Marko.
I think that save will do the trick.
Gurusimran:
The important thing to say here is that the signer of the agent should have the ability to delete docs in the ACL, but if it's not possible then simply comment the line:
Call dummyDoc.Remove( True ) and you're good to go.
Sjef:
Yes, yes, not rent-a-coder, I know, but got carried away :)
Won't happen again :)
BTW Sjef, do you think that the good idea would be that EE pay a percentage of points in $.
Wouldn't that generate more $ traffic for them also?
Sorry for my "poetic" english,
Marko.
Sjef,
no not error there, but in c.AddDocument, because of the line you are talking about which doesn't return collection because of fact that Responses property returns col only after doc is saved, otherwise returns Nothing.
no not error there, but in c.AddDocument, because of the line you are talking about which doesn't return collection because of fact that Responses property returns col only after doc is saved, otherwise returns Nothing.
LOL
I thought I had a good suggestion when I started, I assumed it was worth at least a few shares in the company. No way. I think the money transfers will be too expensive :)
You deserve the points!
Sjef
I thought I had a good suggestion when I started, I assumed it was worth at least a few shares in the company. No way. I think the money transfers will be too expensive :)
You deserve the points!
Sjef
To get a document without responses, without the need to Remove:
Dim view As NotesView
Dim doc As NotesDocument
Set view= db.GetView("Dinges")
Set doc= GetDocWithoutChildren(View .GetFirstD ocument)
If doc Is Nothing Then ' there were no documents in the view
.
End If
.
.
Function GetDocWithoutChildren(doc As NotesDocument) As NotesDocument
Set GetDocWithoutChildren= Nothing
If (doc.Responses Is Nothing) Then Exit Function
Set GetDocWithoutChildren= doc
If doc.Responses.Count=0 Then Exit Function
Set GetDocWithoutChildren= GetDocWithoutChildren(doc. Responses. GetFirstDo cument)
End Function
Dim view As NotesView
Dim doc As NotesDocument
Set view= db.GetView("Dinges")
Set doc= GetDocWithoutChildren(View
If doc Is Nothing Then ' there were no documents in the view
.
End If
.
.
Function GetDocWithoutChildren(doc As NotesDocument) As NotesDocument
Set GetDocWithoutChildren= Nothing
If (doc.Responses Is Nothing) Then Exit Function
Set GetDocWithoutChildren= doc
If doc.Responses.Count=0 Then Exit Function
Set GetDocWithoutChildren= GetDocWithoutChildren(doc.
End Function
It's a very good idea, but why the first two lines in the function?
I think it will never happen that the doc.Responses of the doc you fetched from a view will be Nothing,
or am I just not seeing something?
Usually when I test the collection I write something like this:
If c Is Nothing Then Exit Sub
If c.Count = 0 Then Exit Sub
Is your reason also "religious" one :)
Regards,
Marko
I think it will never happen that the doc.Responses of the doc you fetched from a view will be Nothing,
or am I just not seeing something?
Usually when I test the collection I write something like this:
If c Is Nothing Then Exit Sub
If c.Count = 0 Then Exit Sub
Is your reason also "religious" one :)
Regards,
Marko
Huh? I always try to write functions for the general case, so nothing goes wrong when I copy the function to some other application. This function gets ANY document as a parameter. Depending on the structure of the database (I wouldn't know if response documents are used at all), you need to test all situations. Which makes me realize that I missed a test (thank you!): whether doc Is Nothing.
Function GetDocWithoutChildren(doc As NotesDocument) As NotesDocument
Set GetDocWithoutChildren= Nothing
If doc Is Nothing Then Exit Function
If (doc.Responses Is Nothing) Then Exit Function
Set GetDocWithoutChildren= doc
If doc.Responses.Count=0 Then Exit Function
Set GetDocWithoutChildren= GetDocWithoutChildren(doc. Responses. GetFirstDo cument)
End Function
The first line isn't necessary indeed, for Nothing is the default return value. I added the test on the second line, because the function should work even when there are no documents in the view. The third line is required for an in-memory NotesDocument that hasn't been saved yet.
Not so religious, all the more safe. ;)
Function GetDocWithoutChildren(doc As NotesDocument) As NotesDocument
Set GetDocWithoutChildren= Nothing
If doc Is Nothing Then Exit Function
If (doc.Responses Is Nothing) Then Exit Function
Set GetDocWithoutChildren= doc
If doc.Responses.Count=0 Then Exit Function
Set GetDocWithoutChildren= GetDocWithoutChildren(doc.
End Function
The first line isn't necessary indeed, for Nothing is the default return value. I added the test on the second line, because the function should work even when there are no documents in the view. The third line is required for an in-memory NotesDocument that hasn't been saved yet.
Not so religious, all the more safe. ;)
I think you will not get that unsaved doc using view.GetFirstDocument or doc.Responses,
due to the fact that the doc is not in view (and it's not a response to anyone) until it's saved.
All I meant by the previous question was that doc.Responses will never return Nothing:
If there are no responses then the collection will be initialized (Something:) but the col.Count will be 0.
Is this correct?
due to the fact that the doc is not in view (and it's not a response to anyone) until it's saved.
All I meant by the previous question was that doc.Responses will never return Nothing:
If there are no responses then the collection will be initialized (Something:) but the col.Count will be 0.
Is this correct?
Frankly, I never tried. Maybe, some day...
Let's get this question closed. Gurusimran, are there any issues left?
Let's get this question closed. Gurusimran, are there any issues left?
ASKER
I was hoping to get something that worked using the formula language in notes, I'm not very familiar with lotus or java script, however I do have some limited experience copying code, making a few changes and plugging it in.
It will likely take me a couple days to get this integrated into my application, I will definately come back to this and award points.
Thank you all for all of your help, rent-a-coder.com er I mean experts-exchange is awesome.
It will likely take me a couple days to get this integrated into my application, I will definately come back to this and award points.
Thank you all for all of your help, rent-a-coder.com er I mean experts-exchange is awesome.
If you want to get information from a view, then open it in the agent, like this in LotusScript:
Dim ns As New NotesSession
Dim db As Notesatabase
Dim view As NotesView
Set db= ns.CurrentDatabase
Set view= db.GetView("Dinges")
Running a scheduled agent based on Formula language is a whole lot more difficult.