Link to home
Start Free TrialLog in
Avatar of gurusimran
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
Avatar of Sjef Bosman
Sjef Bosman
Flag of France image

There's a contradiction in what you want: a scheduled agent runs in the background, and therefore has no active view. Which makes setting "all documents in view" pointless.

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.
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
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...
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
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.
Avatar of gurusimran
gurusimran

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...
ASKER CERTIFIED SOLUTION
Avatar of mbonaci
mbonaci
Flag of Croatia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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? ;)
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.
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.
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
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.GetFirstDocument)
    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.GetFirstDocument)
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
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.GetFirstDocument)
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?
Frankly, I never tried. Maybe, some day...

Let's get this question closed. Gurusimran, are there any issues left?
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.