Update all responses from another response - lotus script included

Hi, I’ve searched the forum and found several close responses (including one of mine!) but am still having a problem figuring this out.

I’m not a Lotus Script guru, and am unable to figure this out from the Help or from the Forum.

What I’m trying to do is update one field on all related response docs, from a response doc.

So if I change the field on one response doc, I would like to:

  1. Grab it’s parent

  2. Grab all that parents children (responses),

  3. Update those reponses to match the response doc field I just changed.

  4. Save newly changed collection response.

  5. Refresh view if possible

I’ll be doing this in the Post Save - unless there’s a better way.

Here’s what I’ve got so far (producing the ‘variant does not contain an object’ error)

Sub Postsave(Source As Notesuidocument)

Dim workspace As New NotesUIWorkspace

Dim uidoc As NotesUIDocument

Dim doc As NotesDocument

Dim ProgramChoice As String

Dim collection As NotesDocumentCollection

Dim currentResponse As NotesDocument

Dim parentid As String

Dim parent As NotesDocument



Set uidoc = workspace.CurrentDocument

Set doc = uidoc.Document

'Get parent UNID of the current response doc

parentid = doc.ParentDocumentUNID

'Get parent document

Set parent = db.GetDocumentByUNID(parentid)

'Get all responses to parent

Set collection = parent.Responses

Set currentResponse = collection.GetFirstDocument



While Not ( currentResponse Is Nothing )

	Call currentResponse.ReplaceItemValue("Emp_SingleContactProgam", uidoc.fieldgettext("Emp_SingleContactProgam"))

	Call currentResponse.Save(True,False)

	

	Set currentResponse = collection.GetNextDocument(currentResponse)

Wend

End Sub

I think it’s because I don’t know how to handle, or tell the difference between when to use uidoc and doc.

Based on suggestions in this forum I’ve also tried using stampall to no avail.

I think this is the closest I’ve come but it’s still not working.

If anyone has any suggestions or tips they would be much appreciated.

Thank you

Subject: SOLUTION: Update all responses from another response - lotus script included

In the QuerySave on the Response doc:

Sub Querysave(Source As Notesuidocument, Continue As Variant)

Call source.Close

End Sub

In the QueryClose on the response doc:

Sub Queryclose(Source As Notesuidocument, Continue As Variant)

Dim session As New NotesSession



Dim db As NotesDatabase

Set db = session.CurrentDatabase



Dim doc As NotesDocument

Set doc = source.document

'Get value of Emp_SingleContactProgram field in current response doc

ProgramChoice = doc.GetItemValue("Emp_SingleContactProgram")

'If Emp_SingleContactProgram is not empty then update Parent and other Responses

If Not ProgramChoice(0)="" Then

'Get parent UNID of the current response doc

	Dim parentid As String

	parentid = doc.ParentDocumentUNID

'Get parent document

	Dim parent As NotesDocument

	Set parent = db.GetDocumentByUNID(parentid)

'Get value of Emp_SingleContactProgram field from parent doc

	pProgramChoice = parent.GetItemValue("Emp_SingleContactProgram")

	

	Dim item As NotesItem

'Compare field value of response doc to parent doc and change if different

	If Ubound(ProgramChoice) <> Ubound(pProgramChoice) Then

		Set item = parent.ReplaceItemValue("Emp_SingleContactProgram",ProgramChoice)

		Call parent.Save(True,False)

	Else

		For i = 0 To Ubound(ProgramChoice)

			If pProgramChoice(i) <> ProgramChoice(i) Then

				Set item = parent.ReplaceItemValue("Emp_SingleContactProgram",ProgramChoice)

				Exit For

			End If

		Next

		Call parent.Save(True,False)

	End If

'Get response docs of parent

	Dim response As NotesDocument

	Dim dc As NotesDocumentCollection

	Dim ritem As NotesItem

	

	Set dc = parent.Responses

'See if field exists on response doc, and change if different

	If Not(dc Is Nothing) Then

		For n = 1 To dc.count

			Set response = dc.GetNthDocument(n)

'check to see if Emp_SingleContactprogram field exists on the other responses

			If response.HasItem("Emp_SingleContactProgram") Then

'compare Emp_SingleContactprogram field value to parent and change if different

				rProgramChoice = response.GetItemValue("Emp_SingleContactProgram")

				If Ubound(ProgramChoice) <> Ubound(rProgramChoice) Then

					Set ritem = response.ReplaceItemValue("Emp_SingleContactProgram",ProgramChoice)

				Else

					For i = 0 To Ubound(ProgramChoice)

						If rProgramChoice(i) <> ProgramChoice(i) Then

							Set ritem = response.ReplaceItemValue("Emp_SingleContactProgram",ProgramChoice)

							Exit For

						End If

					Next

				End If

				Call response.Save(True,False)

			End If

		Next

	End If

End If

End Sub

The biggest challenge was figuring out you have to make sure the ‘Don’t support specialized response hierarchy’ selection is UNCHECKED in the database properties. If you had it checked prior to entering this code, you will need to make a new copy of the database, then use the Adminstrator to Compact the db ‘Copy Style’, then delete the old one.

If you don’t do that dc.count will always equal 0. Even though responses will show up in every view, the parent.reponses collection will never be anything other than 0. Thus there would be nothing for the code to update.

ps. THANKS MIKE, the code you provided was exactly what I needed to make this work. Thank you!

Subject: Updated SOLUTION: Update all responses from another response - lotus script included

Sorry about all that other stuff, but here’s a much easier, concise solution. I realized since I can overwrite it everytime, there is no need for the comparison checks, just do it:

Sub Queryclose(Source As Notesuidocument, Continue As Variant)

'**************************************************************************************************************

’ This function sets the ‘Single Point of Contact’ field on the Parent and all of the siblings

’ if the users fills out the ‘Single Point of Contact’ field in the Cross Marketing Preference section.

’ If so, we grab the Parent and set the Emp_SingleContactProgram field, then grab all the

’ response docs to that parent and set the ‘Single Point of Contact’ field on each child as well.

’ This function will act every time the document is saved so no matter which child doc has the

’ ‘Single Point of Contact’ field filled in or changed, it will be reflected immediately on all others.

'**************************************************************************************************************

Dim session As New NotesSession



Dim db As NotesDatabase

Dim doc As NotesDocument

Set db = session.CurrentDatabase

Set doc = source.document

'Get value of Emp_SingleContactProgram field in current response doc

ProgramChoice = doc.Emp_SingleContactProgram

'Get parent UNID, parent doc, set value and save parent

Dim parentid As String

parentid = doc.ParentDocumentUNID



Dim parent As NotesDocument

Set parent = db.GetDocumentByUNID(parentid)



Dim item As NotesItem

Set item = parent.ReplaceItemValue("Emp_SingleContactProgram",ProgramChoice(0))

Call parent.Save(True,False)

’ Set Single Point of Contact on all other responses

’ Get response docs of parent

Dim response As NotesDocument

Dim dc As NotesDocumentCollection

Dim ritem As NotesItem



Set dc = parent.Responses



If Not(dc Is Nothing) Then

	For n = 1 To dc.count

		Set response = dc.GetNthDocument(n)

’ only modify Employer Admin Program response docs

		If response.Form(0) = "EmpAdmProg"  Then

			Set ritem = response.ReplaceItemValue("Emp_SingleContactProgram",ProgramChoice(0))

			Set ritem = response.ReplaceItemValue("dspEmp_SingleContactProgram",ProgramChoice(0))

			Call response.Save(True,False)				

		End If

		

	Next

	

End If

End Sub

Subject: RE: Updated SOLUTION: Update all responses from another response - lotus script included

When setting a field value in all documents in a collection to the same value, use dc.StampAll – it is many, many times faster. Many, many, many. Oh, so very much faster. Way fast. Wicked fast. Use it.

Subject: RE: Updated SOLUTION: Update all responses from another response - lotus script included

How right you are! Thanks for the tip Stan. I’ve started using it where applicable.

However, in this case, because there are multiple types of response docs, don’t I have to find out which one I’m modifying first to make sure it’s only the right ones? Or is there a way I can get a collection of Responses that are only of type “EmpAdmProg”??

Thanks

Subject: Here’s some code that might help. I didn’t write it, I found it, but it works!

When a user enters a value in a multi-value field on a response doc, this script will update the parent doc, then go out and grab a collection of the other response docs. It will first check to see if that field even exists on the response docs. If it doesn’t, it skips it. If the field does exist, it updates the field.

This script basically syncronizes a field value between a parent and its responses, even when that value is being changed in a response doc.

Please realize, this code was written for a multi-value field. It can easily be changed to accomodate a single value field. Also, it will only work on the first level of response docs. It won’t work on response-to-response docs.

In the QuerySave event of a response form, I put the following code to close the doc so it will kick off the QueryClose event:

Call source.Close

Then in the QueryClose event, I put the following code (I want to syncronize a field called BookNumber):

Dim session As New NotesSession

Dim db As NotesDatabase

Set db = session.CurrentDatabase

Dim doc As NotesDocument

Set doc = source.document

'Get value of BookNumber field in current doc

bookno = doc.GetItemValue(“BookNumber”)

'Get parent UNID of the current response doc

Dim parentid As String

parentid = doc.ParentDocumentUNID

'Get parent document

Dim parent As NotesDocument

Set parent = db.GetDocumentByUNID(parentid)

'Get value of BookNumber field from parent doc

pbookno = parent.GetItemValue(“BookNumber”)

Dim item As NotesItem

'Compare field value of response doc to parent doc and change if different

If Ubound(bookno) <> Ubound(pbookno) Then

Set item = parent.ReplaceItemValue(“BookNumber”,bookno)

Call parent.Save(True,False)

Else

For i = 0 To Ubound(bookno)

If pbookno(i) <> bookno(i) Then

Set item = parent.ReplaceItemValue(“BookNumber”,bookno)

Exit For

End If

Next

Call parent.Save(True,False)

End If

'Get response docs of parent

Dim response As NotesDocument

Dim dc As NotesDocumentCollection

Dim ritem As NotesItem

Set dc = parent.Responses

'See if field exists on response doc, and change if different

If Not(dc Is Nothing) Then

For n = 1 To dc.count

Set response = dc.GetNthDocument(n)

'check to see if BookNumber field exists

If response.HasItem(“BookNumber”) Then

'compare BookNumber field value to parent and change if different

rbookno = response.GetItemValue(“BookNumber”)

If Ubound(bookno) <> Ubound(rbookno) Then

Set ritem = response.ReplaceItemValue(“BookNumber”,bookno)

Else

For i = 0 To Ubound(bookno)

If rbookno(i) <> bookno(i) Then

Set ritem = response.ReplaceItemValue(“BookNumber”,bookno)

Exit For

End If

Next

End If

Call response.Save(True,False)

End If

Next

End If

End Sub

===========================================

On the parent form, create a hidden, computed field, named ParentDoc, w/formula: @Text(@DocumentUniqueID)

On the response form (inheritance enabled), create a hidden, computed-when-composed field w/formula: ParentDoc

You can then use ParentDoc as the first argument in your @GetDocField and @SetDocField formulas.

Subject: RE: Here’s some code that might help. I didn’t write it, I found it, but it works!

Thanks!

I’ve massaged it down to this:

Sub Queryclose(Source As Notesuidocument, Continue As Variant)

Dim session As New NotesSession



Dim db As NotesDatabase

Set db = session.CurrentDatabase



Dim doc As NotesDocument

Set doc = source.document

'Get value of Emp_SingleContactProgam field in current doc

ResponseProgramChoice = doc.GetItemValue("Emp_SingleContactProgam")

'Get parent UNID of the current response doc

Dim parentid As String

parentid = doc.ParentDocumentUNID

'Get parent document

Dim parent As NotesDocument

Set parent = db.GetDocumentByUNID(parentid)

'Get value of BookNumber field from parent doc

ParentProgramChoice = parent.GetItemValue("Emp_SingleContactProgam")



Dim item As NotesItem

'Set parent doc

Set item = parent.ReplaceItemValue("Emp_SingleContactProgam",ResponseProgramChoice)

Call parent.Save(True,False)

'Get response docs of parent

Dim response As NotesDocument

Dim dc As NotesDocumentCollection

Dim ritem As NotesItem

Set dc = parent.Responses

'Loop through and set field on Responses

If Not(dc Is Nothing) Then

	For n = 1 To dc.count

		Set response = dc.GetNthDocument(n)

		CurrentResponseProgramChoice = response.GetItemValue("Emp_SingleContactProgam")

		Set ritem = response.ReplaceItemValue("Emp_SingleContactProgam",ResponseProgramChoice)

		Call response.Save(True,False)			

		Exit For

	Next

End If

End Sub

And it’s setting, but refreshing the parent, and it’s not looping through the responses. It’s just not changing any of them.

I’ll keep trying.