Wednesday, 9 December 2015

Quick Tip: Update Child Documents When Parent Data Changes

Last week I was faced with the question whether there was a way, using LotusScript, to update the child documents at the time when field values in the parent document were modified by the user. From a colleague I got the following solution which he had found on the SearchDomino TechTarget site. I tested this solution and it worked perfectly when using response documents. This solution saved me a lot of time this week. The solution consists of 5 steps which are listed below.


Step1. Create hidden field InheritedFields
Create a hidden field called "InheritedFields" on the parent form that is multivalue text. The value should be a list of all field names that need to be updated on the child documents when updates are made to parent (e.g. "Field1" : "Field2" : "Field3").

Step 2. Declarations
In the Declarations of the parent form, include the following:
'handle to parent document
Dim doc As NotesDocument

Step 3. QueryModeChange
In the QueryModeChange of the parent form:
Dim listOfInheritedFields As Variant
Dim doc As NotesDocument
If Not(source.IsNewDoc) And Not(source.EditMode) Then
Set doc = Source.Document
listOfInheritedFields = doc.InheritedFields
Redim inheritFieldsArray(0 To Ubound(listOfInheritedFields), 0 To 1)
For i=0 To Ubound(listOfInheritedFields)
inheritFieldsArray(i, 0) = listOfInheritedFields(i)
inheritFieldsArray(i, 1) = Source.FieldGetText(listOfInheritedFields(i))
Next
End If

Step 4. Create UpdateChildDocuments sub routine
Sub UpdateChildDocuments
Dim actDC As NotesDocumentCollection
Dim actDoc As NotesDocument
Stop
Set actDC = doc.Responses
If actDC.Count > 0 Then
Dim fieldUpdateArray() As String
Dim fieldUpdateCount As Integer
fieldUpdateCount = 0
'initialize array to ""
Redim fieldUpdateArray(0 To 0)
fieldUpdateArray(0) = ""
For i=0 To Ubound(inheritFieldsArray)
fieldName = inheritFieldsArray(i,0)
origFieldVal = inheritFieldsArray(i,1)
currFieldVal = doc.GetItemValue(fieldName)(0)
If (origFieldVal <> currFieldVal) Then
Redim Preserve fieldUpdateArray(0 To fieldUpdateCount)
fieldUpdateArray(fieldUpdateCount) = fieldName
fieldUpdateCount = fieldUpdateCount + 1
End If
Next
If fieldUpdateArray(0) <> "" Then
Set actDoc = actDC.GetFirstDocument
While Not (actDoc Is Nothing)
For i=0 To Ubound(fieldUpdateArray)
currVal = doc.GetItemValue(fieldUpdateArray(i))(0)
Call actDoc.ReplaceItemValue(fieldUpdateArray(i), currVal)
Next
Call actDoc.Save(True, True)
Set actDoc = actDC.GetNextDocument(actDoc)
Wend
End If
End If
End Sub

Step 5. QuerySave
In the QuerySave of parent document:
Set doc = Source.Document
If Not (Source.IsNewDoc) Then
UpdateChildDocuments
End If

Link: Updating Response documents when parent data changes

2 comments:

  1. A couple of comments:

    I'd check for count is zero and then exit the sub as early as possible, save on navigating long blocks of code.
    The NotesDocumentCollection has a couple of nifty methods, called StampAll and StampAllMulti.
    They update all of the documents in one quick burst, which is a LOT quicker.
    like call actDC.StampAll(itemName, value). Even better is StampAllMulti, if you need to do special fields like Reader fields, or multiple fields in one go. Just create a new document, populate with the stuff you want to distribute, and call actDC.StampAllMulti(document). There a couple of caveats, see documentation.

    ReplyDelete
    Replies
    1. Thanks very much for your Reply Lars. I will look into StampAll and StampAllMulti.

      Delete