ADT error & loop

I have a couple issues with this script. It seems to grab the emails w/o issues but still delivers the “function requires valid ADT argument” message. It seems to be more annoying than harmful. I searched this forum and found entries that referenced deleted objects that were no longer accessible (e.g. a loop that deletes docs in Db). It mentioned using adoc1 and adoc2 vs. just adoc1. We are only grabbing emails and sending… no document deletions at all. What needs to be done to remove the message? Also, we need to save the document before sending (doc is open when button is clicked) or else there will be no contents in the body. I used uidoc.save right after the initial DIM statements. After the loops are done, I need to close/exit the memo. I had a uidoc.close (true) after the loop but it never seems to make it that far. Maybe it needs to be doc instead of uidoc on the exit.

Sub Click(Source As Button)

Dim ws As New NotesUIWorkspace

'get back end document for current ui document

Dim doc As NotesDocument

Set doc = ws.CurrentDocument.Document

’ set from address

doc.ReplaceItemValue "principal", "test@test.com"

’ set reply address - if required

doc.ReplaceItemValue "replyto", "test@test.com"

’ open email address database

Dim adb As New NotesDatabase("server", "emailtest.nsf")

If adb.IsOpen = False Then Exit Sub

’ open address view

Dim view As NotesView

Set view = adb.GetView("emails")

If view Is Nothing Then Exit Sub

’ get first document

Dim adoc As NotesDocument

Set adoc = view.GetFirstDocument



Dim who, x

’ loop and send

Do Until adoc Is Nothing

	

	who = ""

	For x = 1 To 100

		who = who & adoc.GetItemValue("email")(0) & ";"

		Print "adding address: " who

		

		Set adoc = view.GetNextDocument(adoc)

		If adoc Is Nothing Then Exit For

	Next

	who = Fulltrim(Split(who, ";"))

	

	Print "sending message"

	doc.ReplaceItemValue "blindcopyto", who

	doc.Send False

	

	Set adoc = view.GetNextDocument(adoc)

Loop

End Sub

Subject: RE: ADT error & loop

Michael, since you have a Do loop which executes until adoc is nothing, and a For loop which executes 100 times or until adoc is nothing, is it possible that adoc gets set to Nothing somewhere in the For loop (less than 100 docs in the view), and when you try to do the GetNextDoc as part of the Do loop, adoc has no value at that point?

Subject: RE: ADT error & loop

Thanks and good point… we are testing in a view that has 10 documents (vs. 1000s). Could that be the issue? What would happen if you had 1020 docs? The final batch will always be an odd #.

Subject: RE: ADT error & loop

How about

Do Until adoc Is Nothing

	who = ""

	For x = 1 To 100

		who = who & adoc.GetItemValue("email")(0) & ";"

		Print "adding address: " who

		

		Set adoc = view.GetNextDocument(adoc)

		If adoc Is Nothing Then Exit For

	Next

	who = Fulltrim(Split(who, ";"))

	

	Print "sending message"

	doc.ReplaceItemValue "blindcopyto", who

	doc.Send False

'Change your getnextdoc to below code

	If Not (adoc Is Nothing) Then

		Set adoc = view.GetNextDocument(adoc)

	End If

Loop

Subject: RE: ADT error & loop

Thanks… am testing now. Will post results in a couple seconds. I did try and lower it to “For x = 1 To 10” but still received the ADT message. Am trying yours now…

Subject: RE: ADT error & loop

Are you saying that you don’t need to save the uidoc at all? Are you just using that to have a place to put the addressing info so you can send it or is there info in that doc, i.e., in a Body field that needs to be sent as part of the email?

Subject: RE: ADT error & loop

Thanks for “staying with me” on this one… I like the way the question was asked. A user will create a memo (HTML mail) then hit the button. To answer your question… yes, the contents of the document (inc. SendTo as “test@test.com”) must be sent. Once sent (and loop is done), I need to make sure the document is saved (or even in sent folder is fine) and closed. The “call uidoc.save” allowed me to see the contents but the sendto was not showing up… was wondering about the placement in the script.

Subject: RE: ADT error & loop

Ok, the way I see it is that with the For loop in there, let’s say there are 150 docs with addresses in the “emails” view. With the way this is written now, you would collect the first 100 addresses, put them into the blindcopyto field and send the email. Then, on the next iteration of the For…Next loop, you would get the remaining 50 into blindcopyto and send the email the second time.

Then, when it is finished, you want to save the uidoc. When you save it, the blindcopyto field will contain only the 50 email addresses. Does it matter that you will lose the first 100 or does it not matter what is in the blindcopyto field when the uidoc is saved?

Why not just put all the addresses into the blindcopyto and send the email just once to all, then save the uidoc?

Subject: RE: ADT error & loop

This would make 100% sense (re: all 150 in the field at once)… but there are several 1000! We will actually bump the “Fpr x = 1 to 100” to a larger # like 300. 300 still only equals ~16K. We might even up the # to 400-500. I did test the loop (shutdown the router) and it worked fine on the real data. I let it process a few iterations then deleted from mail.boxes. It is 100% OK that the final addresses are the only ones in the blindcopyto field. We just want a record of what was sent. re: the save… will it need to be saved twice (once before loop and one at the end)? I was having to do the uidoc.save before the loop otherwise the body text/images were missing.

Subject: RE: ADT error & loop

Michael, take a look at the code below. I did some rewriting of your original code.

When dealing with mail addressing fields, it is best to use an array to populate them, so what I did was set up a bcc variant array, then started looping through the docs in the email address view using a counter, bccctr%, to limit the number of addresses in the array to 100 at a time. This lets us loop through the entire view and send the email each time we hit the 100 mark and reset the counter variable.

After it finishes the loop, it then checks to see if any addresses have been collected but not used. This would apply if there were say 145 docs in the email view.

Take a look and let me know if this might work any better.

Dim ws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument	

Dim doc As NotesDocument

Dim view As NotesView		' open address view

Dim adoc As NotesDocument



Dim adb As New NotesDatabase("server", "emailtest.nsf")		' open email address database

If adb.IsOpen Then		

	

	Set uidoc = ws.CurrentDocument

	Set doc = uidoc.Document						'get back end document for current ui document

	

	doc.ReplaceItemValue "principal", "test@test.com"			' set from address	

	doc.ReplaceItemValue "replyto", "test@test.com"				' set reply address - if required	

	

	Set view = adb.GetView("emails")

	If Not (view Is Nothing) Then

		

		'Dim who, x

		Dim bcc() As Variant

		Redim bcc(0)

		bccctr% = -1

		

		Set adoc = view.GetFirstDocument		' get first document

		

		Do Until adoc Is Nothing			' loop and send

			

			bccctr% = bccctr% + 1

			Redim Preserve bcc(bccctr%)

			bcc(bccctr%) = adoc.email(0)

			Print "adding address: " & bcc(bccctr%)

			

			If bccctr% = 99 Then

				Print "sending message"

				doc.blindcopyto = bcc			

				Call doc.Send( False)

				bccctr% = -1

			End If

			

			Set adoc = view.GetNextDocument(adoc)

			

		Loop

		

		If bccctr% >= 0 Then

			Print "sending message"

			doc.blindcopyto = bcc			

			Call doc.Send( False)

		End If

		

		Call uidoc.Save

		Call uidoc.Close

	Else

		Msgbox "unable to access emails view in emailtest.nsf"

	End If

Else

	Msgbox "Unable to open emailtest.nsf"

End If

Subject: RE: ADT error & loop

Great… will test now. All was working OK excpet for prompt at the end. I attempt to use “call uidoc.close” but the save/send&file/draft/discard prompt still appears. I did attempt to include doc.saveoptions= “0” 1 line before the uidoc.close. Are the quotes needed? I’ll try yours now… thanks again. I’ll be back in a few minutes.

Subject: RE: ADT error & loop

Yes, the quotes are needed. SaveOptions is a text field.

Subject: RE: ADT error & loop

Tried the script… seemed to process fine. I did notice that the contents of the body were missing. I had to insert a call uidoc.save to get the contents to show up. I also added a dim sendnow as integer and a YES/NO prompt to ask the user if he/she wants to proceed. I did encounter the save dialog at the end. I was hoping to see the final msgbox, click OK then be taken back to the view. I did add a msgbox at the end. You know what would be nice? If the msgbox contained the exact # of docs sent… instead of msgbox “Your emails have been sent” → msgbox “ emails were sent”.

Subject: RE: ADT error & loop

Ok, so in this section here

bccctr% = bccctr% + 1

			Redim Preserve bcc(bccctr%)

			bcc(bccctr%) = adoc.email(0)

			Print "adding address: " & bcc(bccctr%)

			AddCount& = AddCount& + 1

add the AddCount& line. I did it as a Long just in case it ever went over 32,767!!

At the end of it all, have

MsgBox Cstr(AddCount&) & " emails were sent."

Subject: RE: ADT error & loop

Excellent… I’m posting the code here. I am getting an object variable not set error. I’m assuming it os the new entry (tried adding addcount as long - must be wrong). Also, I included the uidoc.save in the beginning because the body contents were missing w/o a save early on. What is missing here?

Dim ws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument 

Dim doc As NotesDocument

Dim view As NotesView ' open address view

Dim adoc As NotesDocument

Dim sendnow As Integer



sendnow = ws.Prompt (PROMPT_YESNO, _

"Send Now?", "Do you want to send to all customers now?")

If sendnow = 0 Then

	Exit Sub

End If



Call uidoc.Save



Dim adb As New NotesDatabase("server", "test.nsf") ' open email address database

If adb.IsOpen Then 

	

	Set uidoc = ws.CurrentDocument

	Set doc = uidoc.Document 'get back end document for current ui document

	

	doc.ReplaceItemValue "principal", "test@test.com" ' set from address 

	doc.ReplaceItemValue "replyto", "test@test.com" ' set reply address - if required 

	doc.ReplaceItemValue "sendto", "test@test.com"

	

	Set view = adb.GetView("emails")

	If Not (view Is Nothing) Then

'Dim who, x

		Dim bcc() As Variant

		Redim bcc(0)

		bccctr% = -1

		Dim AddCount As Long

		

		Set adoc = view.GetFirstDocument ' get first document

		

		Do Until adoc Is Nothing ' loop and send

			

			bccctr% = bccctr% + 1

			Redim Preserve bcc(bccctr%)

			bcc(bccctr%) = adoc.email(0)

			Print "adding address: " & bcc(bccctr%)

			AddCount& = AddCount& + 1

			

			If bccctr% = 299 Then

				Print "sending message"

				doc.blindcopyto = bcc 

				Call doc.Send( False)

				bccctr% = -1

			End If

			

			Set adoc = view.GetNextDocument(adoc)

			

		Loop

		

		If bccctr% >= 0 Then

			Print "sending message"

			doc.blindcopyto = bcc 

			Call doc.Send( False)

		End If

		

		Call uidoc.Save

		Call uidoc.Close

	Else

		Msgbox "unable to access emails view in target database"

	End If

Else

	Msgbox "Unable to open target database"

End If 



Msgbox Cstr(AddCount&) & " emails were sent."

Subject: RE: ADT error & loop

Perfect… that got rid of the ADT message! …and I did not adjust the “For x = 1 to 100”. My only remaining issue… how to exit out of the document (was saved earlier -w- “call uidoc.save” without receiving the dialog to send&file/saveasdraft/discard… I just want it to close out. Also… I notice that my my sendto is not automatically populated with our test address .

Dim ws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument

Set uidoc = ws.CurrentDocument

'get back end document and save for current ui document

Dim doc As NotesDocument

Set doc = ws.CurrentDocument.Document

’ set from address

doc.ReplaceItemValue "principal", "test@test.com"

’ set reply address - if required

doc.ReplaceItemValue "replyto", "test@test.com"



' set reply address - if required

doc.ReplaceItemValue "sendto", "test@test.com"



Call uidoc.Save

…then the rest of the script (open Db, loop, etc…)

Is the save in the right place? Maybe it should be in front of the ReplaceItem lines. I’m also wondering about the call uidoc.close (should it be something else or is true/false missing afterwards). Thanks for your continued assistance.