Hello,
I have a ‘Project’ form with 11 fields. I would like to capture in the ‘History’ any field that is changed. I created a ‘Copied’ form with the same 11 fields. I use ‘CopyAllItems’ in the PostOpen event of the ‘Project’ document to create a ‘Copied’ doc. In the QuerySave, I call the “CompareDocs” sub that compares the ‘Project’ doc with the ‘Copied’ doc. If any fields are different, it fills a ‘msg’ variable with the name of that field.
Problem:
- How do I get a handle to the ‘Copied’ doc; I can’t pass it to the QuerySave and I don’t want to have to save it.
Maybe there is a much easier way to do this. Any help is appreciated.
Thanks.
Subject: No, its a great idea. Just make sure that you declare a Global Variable…
copyDoc and it will be available in the PostOpen, QuerySave and QueryClose events (and you do not have to save it).
Subject: Check if fields change
Here’s how I do it:1) globally dim some variables representing each of the 11 fields;
-
on postopen, set the vars with the value of each field, respectively;
-
in querysave, assuming that any input validation is complete (which you can’t do out of hand, because field Input Validation occurs after querysave; I usually validate in a separate global function or in the querysave itself), compare the existing field values with those stored in the vars from above;
-
if different, write to a history field;
-
remember to reset the global vars if you want to catch serial changes in one editing session.
Subject: RE: Check if fields change
Bill(s):Thanks for the help; I’ve got it half-working! The variables are fine; I declared them globally. When I’m debugging and in QuerySave, the variables show up (populated) in ‘Globals.’ I then call a “CompareDocs” function (I changed it from a sub to a function) which has these lines in it:
If Cstr(doc.ProjName(0)) <> PName Then ChangeMsg = “Project Name”
If Cstr(doc.ProjType(0)) <> PType Then ChangeMsg = ChangeMsg + “Project Type”
…etc through all 11 fields building ‘ChangeMsg’ String which I also declared Globally.
(PName, PType are the Global variables)
and then:
If ChangeMsg = “” Then
CompareDocs = False
Else
CompareDocs = True
I then use the following in QuerySave:
If CompareDocs( doc ) Then
’ Add to History…
doc.HistoryChange = ChangeMsg & Chr(10) & doc.HistoryChange(0)
Two Problems and a Question:
-
When testing, I’m only changing the first field (ProjName) but it adds EVERY field to ChangeMsg!
-
When I get back to QuerySave, the ChangeMsg variable is not even listed!
Question:
Assuming I get ‘ChangeMsg’ populated correctly, if there was more than 1 field changed, how would I parse them out? For example, if 3 fields get changed, ‘ChangeMsg’ looks like:
Project NameProject TypeProject Size as one string!
I tried using Lists and ListTags and then I tried arrays to no avail. (This is confusing me because I’ve always just thrown up the combined string Msg in a messagebox!)
Thanks again.
Subject: RE: Check if fields change
Try to use the fields property of form class. It will be more flexible as you don’t have to hardcode fieldnames. Then compare uidoc values to backend values in Querysave e.g.
Sub Postmodechange(Source As Notesuidocument)
If Not Source Is Nothing Then
If source.EDITMODE Then
Set doc = source.document
doc.ISAV_SprmecFlag = "1"
doc.ISAV_SprelecFlag = "1"
'build an array of actual values
If source.Isnewdoc Then Exit Sub 'don't need an empty array
Set S = New NotesSession
Set db = S.CurrentDatabase
Set doc = Source.Document
Set form = db.GetForm(doc.Form(0))
'# of fields
fieldnum = Ubound(form.fields)
'redim array
Redim FieldValues(fieldnum,1)
counter = 0
'fill array with each fieldname and its contents
Forall field In form.fields
FieldValues(counter,0) = field
FieldValues(counter,1) = source.fieldgettext(field)
counter = counter +1
End Forall
End If
End If
End Sub
Querysave excerpt:
If Source.Isnewdoc Then
Call History(Source)
Call SendInfo(db, doc, source)
Exit Sub
Else
For fieldnum = 0 To Ubound(FieldValues)
If FieldValues(fieldnum,1) <> source.fieldgettext(FieldValues(fieldnum,0)) Then
Call History(source)
WasSaved = 1
Exit For 'bail out at first modification found
End If
Next
End If
Subject: RE: Check if fields change
Sorry, company holidays kept me away.
-
If you use a separate function, I would pass in the uidoc (Source) to comparedocs. I would then compare the global vars with using uidoc.FieldGetText([fieldname]). I would also use [ Not … = … ] instead of [ … <> … ] in the comparisons. Something is obviously wrong with your condition if the “then” gets executed each time.
-
Is ChangeMsg global? I may need to be if you play with it in the function and then use it in the querysave. You don’t need it though … (below)
Question answer: Do all those comparisons in the querysave and don’t use a function. (I recommended it before for any separate field validations you might want to do, not for this.) For each non-equality in the field comparisons, add ", ". Then strip out the last two characters before the doc.historychange commit.