Solved/workaround: in-memory-NotesDocument problem: Updates to one NotesDocument instance updates the other one too

For workaround, see below.

Our Scenario:

A List of Docments are getting updated in a for-Loop, e.g. by ComuteWithForm(). Other Documents must be updated if some fields are being changed, e.g. “readers” must be spreaded to the response documents. Our goal is (due to performance) to update the responses only if nesessary, that means we need to compare fields before and after an Update to a NotesDocument (unsaved at this point).

The problem is that a second instance of a NotesDocument (retrieved by getDocumentbyUNID->should contain the previous state of the unsaved document) not only has the same field values as the unsaved first instance, further adding fields to the first Document adds those fields to the second instance as well.-

Example:

//get the 1st selected document in View

set doc = db.UnprocessedDocuments.GetFirstDocument

//Add Field “TESTFIELD” with value “1” to the NotesDocument (not saved yet)

doc.TESTFIELD = “1”

//get the saved copy for compare

set savedDoc = db.getDocumentbyUNID(doc.UniversalID)

Print savedDoc.TESTFIELD(0)

→ this prints “1”, should be “”, since the saved Doc doeasn’t have this item!

→ no matter if the savedDoc is bound before or after TESTFIELD is added to the in-memory/unsaved document “doc”

doc.Testfield2 = “2”

print savedDoc.TestField2(0)

→ this prints “2”, should be “”!

How else can I compare fields of the unsaved backend document with the altered, unsaved instance of the document (except storing the field values in variables before altering the first instance)?



Workaround:

A trick is to use a special view, from which the saved / unaltered copy can be retrieved by View.GetDocumentbyKey(key, True). The key can be e.g. the UNID or NoteID of the document.

This works in QuerySave and WebquerySave as well, at the cost of an extra view in the database.

Subject: in-memory-NotesDocument problem: Updates to one NotesDocument instance updates the other one too

Denis,

This was discussed in a thread the other day. Even if you you grab a reference to the doc via getDocumentByUNID, you are going to grab the recent reference to the doc in memory (which would be the changed doc.) Nowhere in the documentation does it say that the doc object retrieved by the getDocumentByUNID method will return an object with the previous values.

You will need to create a copy of the document object during your queryopen event like so:

Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant)

Dim db as NotesDatabase

Dim doc as NotesDocument

set doc = Source.Document

set db = doc.ParentDatabase

set originalDoc = New NotesDocument(db)

Call doc.CopyAllItems(originalDoc)

End Sub

You would then use the global variable originalDoc to check against your changed doc during a querysave event. originalDoc is not dimmed in this module because it has to have global scope to move between events for the check.

check this thread for further details:

http://www-10.lotus.com/ldd/nd6forum.nsf/ShowMyTopicsAllFlatweb/2acaa95b2fc3db488525738500448792?OpenDocument

hth.

brandt

Subject: only partial “solution” (i better call it “workaround”)

To get a handle before a document is being altered does not work for webquerysave, since the session.documentContext already contains the altered version.

How can I get around this here?

However, for the other scenario I could use CopyallItems(), but isn’t this a perfomance-impact when i have to do this for 10-50 Documents each time? And CopyAllItems will copy the Attachments in-memory as well, doesn’t it? OK, i could use CopyItem() for those Items i really need…

Subject: in-memory-NotesDocument problem: Updates to one NotesDocument instance updates the other one too

Sub Click(Source As Button)

Dim uiws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument

Dim doc As NotesDocument

Dim db As NotesDatabase

Dim vw As NotesView

Dim docOriginal As NotesDocument



Set uidoc = uiws.CurrentDocument

Set doc = uidoc.Document

Set db = doc.ParentDatabase

Set vw = db.GetView("Help") 'Whatever your lookup view is named

Set docOriginal = vw.GetDocumentByKey(doc.Topic(0), True) 'Assume that Topic is the field on which the view "Help" is keyed



doc.ReplaceItemValue "DeleteThisField", "1"

Msgbox docOriginal.DeleteThisField(0) 'Blank, not 1

End Sub

Subject: RE: in-memory-NotesDocument problem: Updates to one NotesDocument instance updates the other one too

Thank you, a view helps me out here and it works with webQuerySave as well this way!