Reminder Agent: Getting "Object Variable not set"

I'm developing a training resources database. There is a form and a hidden view called "Courses2". TThe fields, from the form, in the view used are:
Employee_Email
Trainer_Email
TL_Email
HR_Email
Act_Start_Date

All fields are text except for Act_Start_Date which is Date/Time. All are editable.                                                

I've written a scheduled agent that is supposed to run once a day on documents in a view. The agent checks all the documents in the view and checks that the date in Act_Start_Date is 30 days before todays date. If it finds a document it mails the employee and the TL (team leader).

When I run the agent manually I get "Object Variable not set".

My code is

Sub Initialize
      Dim s As New notessession
      Dim db As notesdatabase
      Set db=s.currentdatabase
      Dim due As notesview
      Dim maildoc, viewdoc As notesdocument
      Dim daten As Variant
      Dim duedate As String
      Dim TL As String
      Dim Employee As String
      Set due=db.getview("Courses2")
      Set viewdoc=due.getfirstdocument
      
      Do Until viewdoc Is Nothing
            
            daten=Today()
            duedate=viewdoc.Act_Start_Date(0)
            TL=viewdoc.TL_Email("")
            Employee=viewdoc.Employee_Email(0)
            
            If daten=(duedate-30) Then
                  Set maildoc=db.createdocument
                  maildoc.form="Memo"
                  Dim rtitem As New notesrichtextitem(maildoc, "Body")
                  maildoc.Subject="Training Reminder - 1 month to go"
                  Call maildoc.AppendItemValue("SendTo",TL)
                  Call maildoc.AppendItemValue("CC",Employee)
                  Call rtitem.AppendText( "Training in a month's time for"& Employee)
                  Call maildoc.send(False, maildoc.SendTo(0))
            End If
            
            Set viewdoc=due.getnextdocument(viewdoc)
      Loop
      
End Sub  
gcousinsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

HemanthaKumarCommented:
there is a better way for this approach...

In the agent you have Add Search button.. it is meant to search docs with specific criteria..

In your case choose the field and lesser than 30 days.

And in script use db.UnprocessedDocuments to fetch this search related docs.

So your script will look like this
' Set session and db objs
dim col as NotesDocumentCollection
dim doc as NotesDocument
set col = db.UnProcessedDocuments
set doc = col.GetFirstDocuments
while not doc is nothing

'mailing script here

set doc = col.GetNextDocument(doc)
wend

~Hemanth
0
gcousinsAuthor Commented:
Hi,

What do you mean by Add Search button?

Gary
0
gcousinsAuthor Commented:
I'm now getting an error when I try to save the agent, "Not a member: GETFIRSTDOCUMENTS"
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

gcousinsAuthor Commented:
Hi,

Forget the last comment, I've now got a script that looks like this but I've got an error "Wrong number of arguments for: GETFIRSTDOCUMENT".

Sub Initialize
      Dim s As New notessession
      Dim db As notesdatabase
      Set db=s.currentdatabase
      Dim col As NotesDocumentCollection
      Dim doc As NotesDocument
      Dim maildoc, viewdoc As notesdocument
      Dim daten As Variant
      Dim duedate As String
      Dim TL As String
      Dim Employee As String
      Set col = db.UnProcessedDocuments
      Set doc = col.GetFirstDocument(doc)
      While Not doc Is Nothing
            
            daten=Today()
            duedate=viewdoc.Act_Start_Date(0)
            TL=viewdoc.TL_Email(0)
            Employee=viewdoc.Employee_Email(0)
            
            If daten=(duedate-30) Then
                  Set maildoc=db.createdocument
                  maildoc.form="Memo"
                  Dim rtitem As New notesrichtextitem(maildoc, "Body")
                  maildoc.Subject="Training Reminder - 1 month to go"
                  Call maildoc.AppendItemValue("SendTo",TL)
                  Call maildoc.AppendItemValue("CC",Employee)
                  Call rtitem.AppendText( "Training in a month's time for"& Employee)
                  Call maildoc.send(False, maildoc.SendTo(0))
            End If
            
            Set doc = col.GetNextDocument(doc)
      Wend
      
End Sub

0
Sjef BosmanGroupware ConsultantCommented:
GetFirstDocument doesn't have parameters.
0
HemanthaKumarCommented:
that is a typo

Not >set doc = col.GetFirstDocuments

it should be
set doc = col.GetFirstDocument
0
gcousinsAuthor Commented:
Ok, my script now looks like this but when I run it manually I get "object variable not set". Is datedate declared properly as string?

Sub Initialize
      Dim s As New notessession
      Dim db As notesdatabase
      Set db=s.currentdatabase
      Dim col As NotesDocumentCollection
      Dim due As notesview
      Dim doc As NotesDocument
      Dim maildoc, viewdoc As notesdocument
      Dim daten As Variant
      Dim duedate As String
      Dim TL As String
      Dim Employee As String
      Set Due = db.GetView( "Courses2" )
      Set doc = due.GetFirstDocument
      While Not doc Is Nothing
            
            daten=Today()
            duedate=viewdoc.Act_Start_Date(0)
            TL=viewdoc.TL_Email(0)
            Employee=viewdoc.Employee_Email(0)
            
            If daten=(duedate-30) Then
                  Set maildoc=db.createdocument
                  maildoc.form="Memo"
                  Dim rtitem As New notesrichtextitem(maildoc, "Body")
                  maildoc.Subject="Training Reminder - 1 month to go"
                  Call maildoc.AppendItemValue("SendTo",TL)
                  Call maildoc.AppendItemValue("CC",Employee)
                  Call rtitem.AppendText( "Training in a month's time for"& Employee)
                  Call maildoc.send(False, maildoc.SendTo(0))
            End If
            
            Set doc = col.GetNextDocument(doc)
      Wend
      
End Sub

0
gcousinsAuthor Commented:
Sorry, I meant Datedue declared properly?
0
Bozzie4IT ArchitectCommented:
Duedate is not a date, so you can't use it to compare (you declared it as string?)

Also, always setting the daten var to 'today' is not very efficient.  And "viewdoc" does not exist.
And you make a classic mistake in declaring maildoc and viewdoc on 1 line : correct is
dim maildoc as notesdocument, viewdoc as notesdocument (not : maildoc, viewdoc as notesdocument)

Sub Initialize
     Dim s As New notessession
     Dim db As notesdatabase
     Set db=s.currentdatabase
     Dim col As NotesDocumentCollection
     Dim due As notesview
     Dim doc As NotesDocument
     'Dim maildoc, viewdoc As notesdocument
dim maildoc
     Dim daten As new notesdatetime(now)
     Dim duedate As notesdatetime
     Dim TL As String
     Dim Employee As String
     Set Due = db.GetView( "Courses2" )
     Set doc = due.GetFirstDocument

     While Not doc Is Nothing
                           'duedate=viewdoc.Act_Start_Date(0)
if doc.hasitem("Act_Start_Date") then
set duedate = doc.getfirstitem("Act_Start_Date").DateTimeValue
Call duedate.adjustday(-30)
else
Print "ERROR"
end if
          TL=doc.TL_Email(0)
          Employee=doc.Employee_Email(0)
          if daten.lslocaltime > duedate.lslocaltime then
          'If daten=(duedate-30) Then
               Set maildoc=db.createdocument
               maildoc.form="Memo"
               Dim rtitem As New notesrichtextitem(maildoc, "Body")
               maildoc.Subject="Training Reminder - 1 month to go"
               Call maildoc.AppendItemValue("SendTo",TL)
               Call maildoc.AppendItemValue("CC",Employee)
               Call rtitem.AppendText( "Training in a month's time for"& Employee)
               Call maildoc.send(False, maildoc.SendTo(0))
          End If
         
          Set doc = col.GetNextDocument(doc)
     Wend
     
End Sub
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gcousinsAuthor Commented:
Thanks Bossie4 for your help, as you've probably worked out I'm new to Lotusscript. What should I select in the Document Selection part of the agent? I'm also still getting the same error when the agent runs manually.
0
Sjef BosmanGroupware ConsultantCommented:
Why don't you use the debugger? See File/Tools/Debug LotusScript to switch it on. Now when you run your agent or script manually, the debugger will start. Click Continue (or type F5) and wait until the error message pops up. You'll see the line the error occurred on. Let us know which line that was.
0
Sjef BosmanGroupware ConsultantCommented:
By the way, Object variable not set always means that you try to use a variable declared as some object variable, but it has no (valid) content. You never checked if the view Courses2 does exist, so the line
    Set doc = due.GetFirstDocument
uses due as object which might still have a value Nothing. Then you get the error. So it is only with object variables, or Variants that have or are supposed to have an object.
0
gcousinsAuthor Commented:
I ran the debugger as you suggested and got the error at the following line:

Set doc = due.GetFirstDocument
0
Sjef BosmanGroupware ConsultantCommented:
Ah. As I expected. The view doesn't exist in the current database, or you don't have access to that view. Check the tab at the bottom that says: Variables. Due will probably be Nothing.
0
Sjef BosmanGroupware ConsultantCommented:
Ah! It's a hidden view. Easiest thing to do: give the view an alias name of Courses2. Otherwise you need to use the parentheses around the name. Suggestion: ALWAYS USE ALIASES, then you can rename the view later on anything you like, but don't ever rename the Alias.
0
Bozzie4IT ArchitectCommented:
Good one sjef :-)

G, you should always add 'option declare' (without the quotes) to the options section of all scripts you write.  That will at least not allow you to use variables that were not declared, and will prevent typos (trust me, I know)

In the Document Selection part of your agent, you don't have to put anything, because this agent will have to work on 'All documents in database' (because you use a view to get the documents to work on).

cheers,

Tom
0
gcousinsAuthor Commented:
You were right I had named it as [Courses2] but have now changed it to Courses2. The agent now runs but I still get the error message.
0
Sjef BosmanGroupware ConsultantCommented:
You get "the" error message... I don't have "the" answer ;)

Does the agent run manually? Then use the debugger over and over again, until you find the error. And please be a little more descriptive :)
0
gcousinsAuthor Commented:
OK guys, how do you want the points? Both sjef and bossie4 provided me with lots of information and Herman contributed at the start. How about 200,200,100?
0
Sjef BosmanGroupware ConsultantCommented:
You want us to fight over the "bones"? Hah!

Sjef ;)
0
gcousinsAuthor Commented:
Well if I give all the points to one person the others will feel agrieved. I'll go with the 200,200,100 split.

0
Sjef BosmanGroupware ConsultantCommented:
Nobody will complain if the rules about points are (more or less) obeyed. They're somewhere on EE, but I never seem able to find them. Your split suits me fine. Thanks!
0
gcousinsAuthor Commented:
The error in question is "Object variable not set", the line is Set doc = col.GetNextDocument(doc) and col has no value in the variable tab of the debugger.
0
Sjef BosmanGroupware ConsultantCommented:
You walk through a view, and not a collection. Use
    doc= due.getnextdocument(doc)
0
gcousinsAuthor Commented:
Thanks sjef, It works. I'll allocate the points. Thanks to all for their time.
0
Bozzie4IT ArchitectCommented:
Missed that 1 in the code I corrected .... Should have gotten rid of the 'dim col... ' stuff, so it would have shown up quite easily  ....

Tom
0
gcousinsAuthor Commented:
One small problem guys, I let the agent run over the weekend and it mails every day. It's supposed to be a reminder to let someone know that if they have training in one months time e,g. if they have training on 20th December it should mail them once to let them know on the 21st November (30 days before). I think what its doing now is 30 days or less.

0
Sjef BosmanGroupware ConsultantCommented:
Ask Tom why he changed this line:
          if daten.lslocaltime > duedate.lslocaltime then
0
gcousinsAuthor Commented:
Hi Tom,

Any idea on the above issue?
0
Sjef BosmanGroupware ConsultantCommented:
Maybe Tom is busy. Well, normally it's better to use less/greater than or equal, because a date is easily missed: the server goes down unexpectedly, maintenance during a Sunday, whatever. You could change your agent a little (in pseudo-code):

    If the reminder hasn't been sent already Then
        If within warning period Then
            send reminder
            doc.ReminderSent= Now
        End If
    End If
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Lotus IBM

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.