cLFlaVA
asked on
NotesUIDocument Save Changes Even Though Saved...
I've listed my code below. I'm wondering why, after this script runs, Notes still prompts the user to Save Changes. It's driving me insane.
As you can see, I call uidoc.Save right before uidoc.Close, so I'm wondering if this is one of the millions of problems in Notes. Is there any way around it?
Thanks for your time and help.
-Cory
Function SubmitForITGovApproval ( szForm As String ) As Integer
On Error Goto HandleError
Dim szFieldName As String
Dim szLabel As String
Dim szQuestion As String
Dim szTitle As String
Dim uidoc As NotesUIDocument
Dim uiw As New NotesUIWorkspace
SubmitForITGovApproval = True
szQuestion = "Are you sure you want to submit this document for IT Gov. approval?"
szTitle = "Submit For Approval?"
If Messagebox( szQuestion, MB_YESNO, szTitle ) = MB_YES Then
Set uidoc = uiw.CurrentDocument
uidoc.EditMode = True
uidoc.Save
If szForm = CONTRACT_FORM Then
uidoc.Document.ContractSta tus = STATUS_3
Else
uidoc.Document.SOWStatus = STATUS_3
End If
uidoc.Save
uidoc.Close
End If
Finish:
Exit Function
HandleError:
SubmitForITGovApproval = False
Messagebox "Error submitting for IT Gov. approval: (" & Erl() & " - " & Error() & ")"
Resume Finish
End Function
As you can see, I call uidoc.Save right before uidoc.Close, so I'm wondering if this is one of the millions of problems in Notes. Is there any way around it?
Thanks for your time and help.
-Cory
Function SubmitForITGovApproval ( szForm As String ) As Integer
On Error Goto HandleError
Dim szFieldName As String
Dim szLabel As String
Dim szQuestion As String
Dim szTitle As String
Dim uidoc As NotesUIDocument
Dim uiw As New NotesUIWorkspace
SubmitForITGovApproval = True
szQuestion = "Are you sure you want to submit this document for IT Gov. approval?"
szTitle = "Submit For Approval?"
If Messagebox( szQuestion, MB_YESNO, szTitle ) = MB_YES Then
Set uidoc = uiw.CurrentDocument
uidoc.EditMode = True
uidoc.Save
If szForm = CONTRACT_FORM Then
uidoc.Document.ContractSta
Else
uidoc.Document.SOWStatus = STATUS_3
End If
uidoc.Save
uidoc.Close
End If
Finish:
Exit Function
HandleError:
SubmitForITGovApproval = False
Messagebox "Error submitting for IT Gov. approval: (" & Erl() & " - " & Error() & ")"
Resume Finish
End Function
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Also, if this document happens to initially be in edit mode, then won't this:
doc.Save True, False
uidoc.Close
result in the same prompt?
doc.Save True, False
uidoc.Close
result in the same prompt?
ASKER
Ok, I've got it working (better) now. However, if the document is in edit mode, it will still prompt the user after the script runs:
Function SubmitForITGovApproval ( szForm As String ) As Integer
On Error Goto HandleError
Dim s As New NotesSession
Dim szFieldName As String
Dim szLabel As String
Dim szQuestion As String
Dim szTitle As String
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Dim uiw As New NotesUIWorkspace
SubmitForITGovApproval = True
szQuestion = "Are you sure you want to submit this document for IT Gov. approval?"
szTitle = "Submit For Approval?"
If Messagebox( szQuestion, MB_YESNO, szTitle ) = MB_YES Then
Set uidoc = uiw.CurrentDocument
Set doc = uidoc.Document
If szForm = CONTRACT_FORM Then
doc.ContractStatus = STATUS_3
Else
doc.SOWStatus = STATUS_3
End If
WriteLine "submitted this document for IT Gov. Approval.", doc
doc.Save True, False
uidoc.Close
End If
Finish:
Exit Function
HandleError:
SubmitForITGovApproval = False
Messagebox "Error submitting for IT Gov. approval: (" & Erl() & " - " & Error() & ")"
Resume Finish
End Function
I know it's because of uidoc.Close, is there any way to bypass this?
So your function SubmitForITGovApproval is actually called from the QuerySave event? Then DON'T call Save() from inside the function, but left the QuerySave finish it's job, and just add the following line to the QuerySave:
continue= SubmitForITGovApproval
continue= SubmitForITGovApproval
ASKER
ahh, but there are 5 other very very similar functions that will be called. These are called from action buttons. The querysave event calls some other function - unrelated.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hmmm. Back to square one. Okay, what do you want? You didn't tell me the whole story, did you? I sure need to know more:
- from where do you want to call this particular function?
- can the document be in both edit-mode or read-mode when the function is called? or only edit-mode?
- why don't you pass the doc as argument for the function, and let the caller handle the saving??
- from where do you want to call this particular function?
- can the document be in both edit-mode or read-mode when the function is called? or only edit-mode?
- why don't you pass the doc as argument for the function, and let the caller handle the saving??
Hey Bro, Don't you have to be in a meeting??
It's holiday mood here, so no meeting only stealing :)
Partha
Partha
ASKER
Would I have to set this SaveOptions field every time I'm saving something, then? Or will it reset all the time?
ASKER
sjef-
- these functions will be called from a form when the user clicks on an action button at the top of the screen.
- the document can be in both edit and read mode.
- I don't know, that's just not the way I set it up.
- these functions will be called from a form when the user clicks on an action button at the top of the screen.
- the document can be in both edit and read mode.
- I don't know, that's just not the way I set it up.
Grrrrrrr!
Sjef :D
Sjef :D
hey
This is your initial code:
On Error Goto HandleError
Dim szFieldName As String
Dim szLabel As String
Dim szQuestion As String
Dim szTitle As String
Dim uidoc As NotesUIDocument
Dim uiw As New NotesUIWorkspace
SubmitForITGovApproval = True
szQuestion = "Are you sure you want to submit this document for IT Gov. approval?"
szTitle = "Submit For Approval?"
If Messagebox( szQuestion, MB_YESNO, szTitle ) = MB_YES Then
Set uidoc = uiw.CurrentDocument
uidoc.EditMode = True
uidoc.Save
If szForm = CONTRACT_FORM Then
uidoc.Document.ContractSta tus = STATUS_3
Else
uidoc.Document.SOWStatus = STATUS_3
End If
uidoc.Save
call uidoc.fieldsettext("saveop tions","0" )
uidoc.Close
End If
This will prevent the save prompt but as sjef pointed out ,every save will result in querysave event being called
Partha
This is your initial code:
On Error Goto HandleError
Dim szFieldName As String
Dim szLabel As String
Dim szQuestion As String
Dim szTitle As String
Dim uidoc As NotesUIDocument
Dim uiw As New NotesUIWorkspace
SubmitForITGovApproval = True
szQuestion = "Are you sure you want to submit this document for IT Gov. approval?"
szTitle = "Submit For Approval?"
If Messagebox( szQuestion, MB_YESNO, szTitle ) = MB_YES Then
Set uidoc = uiw.CurrentDocument
uidoc.EditMode = True
uidoc.Save
If szForm = CONTRACT_FORM Then
uidoc.Document.ContractSta
Else
uidoc.Document.SOWStatus = STATUS_3
End If
uidoc.Save
call uidoc.fieldsettext("saveop
uidoc.Close
End If
This will prevent the save prompt but as sjef pointed out ,every save will result in querysave event being called
Partha
I call this a kludge...
Have to go to a meeting now did i answer anythign here ?:-)
Partha
Partha
ASKER
With my ammended code (with the help of sjef above) and your suggestion of the SaveOptions field, though, I should get the desired result?
Basically, since the document is being saved from the backend during the whole process, and the user will not be able to change any fields during the function's processing, there's no need to re-ask "should it save". Does this make sense?
So, I will now try putting your saveoptions solution into my newer code. Do I have to create an actual field called saveoptions? Should it be computed? computed when composed?
Basically, since the document is being saved from the backend during the whole process, and the user will not be able to change any fields during the function's processing, there's no need to re-ask "should it save". Does this make sense?
So, I will now try putting your saveoptions solution into my newer code. Do I have to create an actual field called saveoptions? Should it be computed? computed when composed?
ASKER
and I call it: "i don't yet know any better"
Yeah it's better you have a field by name saveoptions in the form, and just editable would do
partha
partha
ASKER
ok thanks, i'll try it now.
But make sure you manipulate it accordingly (i.e when you edit the documnet later, probably before saving set the saveoptions to "1" and save it...
partha
partha
ASKER
well, if we're setting 0 just before close, then closing it, it shouldn't ever "remember" the 0 i'm setting it to...
LOL
Although he's my bro, I consider the SaveOptions-solution in this case a 'last resort' solution. If all else fails, then use it, reluctantly. It's the high way where you could easily take my way, if you would be so kind to forgive the expression. Could you please answer the questions I had before? I sincerely question the logic of your form's buttons and actions. Could you please shed some light??
Sjef
Although he's my bro, I consider the SaveOptions-solution in this case a 'last resort' solution. If all else fails, then use it, reluctantly. It's the high way where you could easily take my way, if you would be so kind to forgive the expression. Could you please answer the questions I had before? I sincerely question the logic of your form's buttons and actions. Could you please shed some light??
Sjef
ASKER
ok, which question - the third? I didn't really understand it.
>> - why don't you pass the doc as argument for the function, and let the caller handle the saving??
Could you explain a little more? Thanks.
>> - why don't you pass the doc as argument for the function, and let the caller handle the saving??
Could you explain a little more? Thanks.
Bro,
This is one of the "Frequently" used workarounds. But you are right, there are elegant ways of writing this whole stuff.. He could have written everythign in querysave and in the code which calls this functoin he cud have just given :
@command([filesave])
@command([fileclosewindow] )
Partha
This is one of the "Frequently" used workarounds. But you are right, there are elegant ways of writing this whole stuff.. He could have written everythign in querysave and in the code which calls this functoin he cud have just given :
@command([filesave])
@command([fileclosewindow]
Partha
Okay. On second thought, add another parameter that will take care of saving the document if required
I assume you have in your QuerySave function something like
.
ok= SubmitForITGovApproval
.
Now instead of saving INSIDE the function SubmitForITGovApproval, you skip the saving and you let QuerySave finish its job. Like this:
In QuerySave:
Dim uidoc As NotesUIDocument
Dim ws As NotesUIWorkspace
Set uidoc= ws.CurrentDocument
ok= SubmitForITGovApproval(uid oc.Documen t, False)
If Not ok Then continue= False ' will stop saving the document
And in your function SubmitForITGovApproval:
Function SubmitForITGovApproval(doc As NotesDocument, dosave As Integer)
.
SubmitForITGovApproval= False ' this line isn't required
If MessageBox ... Then
SubmitForITGovApproval= True
If dosave Then
Call doc.Save(True, False)
End If
End If
That's all. If you call the same function from somewhere else, you can force saving using
Call SubmitForITGovApproval(doc , True)
Am I making myself a little clear??
I assume you have in your QuerySave function something like
.
ok= SubmitForITGovApproval
.
Now instead of saving INSIDE the function SubmitForITGovApproval, you skip the saving and you let QuerySave finish its job. Like this:
In QuerySave:
Dim uidoc As NotesUIDocument
Dim ws As NotesUIWorkspace
Set uidoc= ws.CurrentDocument
ok= SubmitForITGovApproval(uid
If Not ok Then continue= False ' will stop saving the document
And in your function SubmitForITGovApproval:
Function SubmitForITGovApproval(doc
.
SubmitForITGovApproval= False ' this line isn't required
If MessageBox ... Then
SubmitForITGovApproval= True
If dosave Then
Call doc.Save(True, False)
End If
End If
That's all. If you call the same function from somewhere else, you can force saving using
Call SubmitForITGovApproval(doc
Am I making myself a little clear??
ASKER
But there are also times when a user can save the form without submitting it for approval. Plus, there are five separate approval stages.
cLFlava,
Everything is a "If condition" in querysave
Partha
Everything is a "If condition" in querysave
Partha
ASKER
My QuerySave:
Sub Querysave(Source As Notesuidocument, Continue As Variant)
On Error Goto HandleError
' assign a unique id if this is a new document
If Source.IsNewDoc And Source.Document.ContractNu mber( 0 ) = "" Then
AssignUniqueID Source, CONTRACT_FORM
Else
' log any changed fields
CompareValues CONTRACT_FORM
End If
Finish:
Exit Sub
HandleError:
Continue = False
Resume Finish
End Sub
Sub Querysave(Source As Notesuidocument, Continue As Variant)
On Error Goto HandleError
' assign a unique id if this is a new document
If Source.IsNewDoc And Source.Document.ContractNu
AssignUniqueID Source, CONTRACT_FORM
Else
' log any changed fields
CompareValues CONTRACT_FORM
End If
Finish:
Exit Sub
HandleError:
Continue = False
Resume Finish
End Sub
ASKER
i've got two meetings now - i'll definitely be back to continue this.
thanks so much for your help so far.
thanks so much for your help so far.
Handle it the way Lotus handles it in mail. The actions buttons -- save as draft, send and file, simple send -- all have the same very basic code:
1) Set an indicator field to a value unique to the particular action button
2) save and close window
This effectively just causes the QuerySave/PostSave/QueryCl ose to do allthe processing, and those functions call a routine in a script library, and THOSE routines have access to some common code.
At a simplified level, you might have:
Action SUBMIT:
FIELD ProcessingOption := "SUBMIT";
@Command([FileSave]);
@Command([FileClose);
Action SAVE DRAFT:
FIELD ProcessingOption := "DRAFT";
@Command([FileSave]);
@Command([FileClose);
QuerySave:
Select Case Source.Document.Processing Option(0)
Case "DRAFT"
Call UpdateAuditHistoryRoutine
Source.Document.Processing Option = "OKTOSAVE"
Case "SUBMIT"
If CheckValidationsRoutine() Then
Call UpdateAuditHistoryRoutine
Source.Document.Processing Option = "OKTOSAVE"
Else
Continue = False 'prevent save
Source.Document.Processing Option = ""
End If
Case Else
Msgbox "Unknown save process",,Source.Document. Processing Option(0)
Continue = False
End Select
PostSave:
If Source.Document.Processing Option(0) = "OKTOSAVE" Then
Source.Document.Processing Option = "SAVED"
Else
Source.Document.Processing Option = ""
End If
QueryClose:
If Source.Document.Processing Option(0) <> "SAVED" Then
Source.Document.Processing Option = ""
Msgbox "Unknown close process",,Source.Document. Processing Option(0)
End If
1) Set an indicator field to a value unique to the particular action button
2) save and close window
This effectively just causes the QuerySave/PostSave/QueryCl
At a simplified level, you might have:
Action SUBMIT:
FIELD ProcessingOption := "SUBMIT";
@Command([FileSave]);
@Command([FileClose);
Action SAVE DRAFT:
FIELD ProcessingOption := "DRAFT";
@Command([FileSave]);
@Command([FileClose);
QuerySave:
Select Case Source.Document.Processing
Case "DRAFT"
Call UpdateAuditHistoryRoutine
Source.Document.Processing
Case "SUBMIT"
If CheckValidationsRoutine() Then
Call UpdateAuditHistoryRoutine
Source.Document.Processing
Else
Continue = False 'prevent save
Source.Document.Processing
End If
Case Else
Msgbox "Unknown save process",,Source.Document.
Continue = False
End Select
PostSave:
If Source.Document.Processing
Source.Document.Processing
Else
Source.Document.Processing
End If
QueryClose:
If Source.Document.Processing
Source.Document.Processing
Msgbox "Unknown close process",,Source.Document.
End If
Or don't use notesuidocument to save/set anything. There's no need, because you are closing it anyway :
Function SubmitForITGovApproval ( szForm As String ) As Integer
On Error Goto HandleError
Dim szFieldName As String
Dim szLabel As String
Dim szQuestion As String
Dim szTitle As String
Dim uidoc As NotesUIDocument
Dim uiw As New NotesUIWorkspace
SubmitForITGovApproval = True
szQuestion = "Are you sure you want to submit this document for IT Gov. approval?"
szTitle = "Submit For Approval?"
If Messagebox( szQuestion, MB_YESNO, szTitle ) = MB_YES Then
Set uidoc = uiw.CurrentDocument
if uidoc.editmode then
' save state
Call uidoc.save()
end if
If szForm = CONTRACT_FORM Then
uidoc.Document.ContractSta tus = STATUS_3
Else
uidoc.Document.SOWStatus = STATUS_3
End If
uidoc.document.save( true, false )
uidoc.document.saveoptions = "0" ' this line may or may not be necessary
uidoc.Close
End If
Finish:
Exit Function
HandleError:
SubmitForITGovApproval = False
Messagebox "Error submitting for IT Gov. approval: (" & Erl() & " - " & Error() & ")"
Resume Finish
End Function
Function SubmitForITGovApproval ( szForm As String ) As Integer
On Error Goto HandleError
Dim szFieldName As String
Dim szLabel As String
Dim szQuestion As String
Dim szTitle As String
Dim uidoc As NotesUIDocument
Dim uiw As New NotesUIWorkspace
SubmitForITGovApproval = True
szQuestion = "Are you sure you want to submit this document for IT Gov. approval?"
szTitle = "Submit For Approval?"
If Messagebox( szQuestion, MB_YESNO, szTitle ) = MB_YES Then
Set uidoc = uiw.CurrentDocument
if uidoc.editmode then
' save state
Call uidoc.save()
end if
If szForm = CONTRACT_FORM Then
uidoc.Document.ContractSta
Else
uidoc.Document.SOWStatus = STATUS_3
End If
uidoc.document.save( true, false )
uidoc.document.saveoptions
uidoc.Close
End If
Finish:
Exit Function
HandleError:
SubmitForITGovApproval = False
Messagebox "Error submitting for IT Gov. approval: (" & Erl() & " - " & Error() & ")"
Resume Finish
End Function
Hi Tom, please re-read from the start... ;)
I think a code review is more appropriate. Sorry clFlaVa, not to criticize you, but there seme to be some serious misconceptions in the code, about how and where documents can be saved, about UIDocuments and Documents, etc.
I think a code review is more appropriate. Sorry clFlaVa, not to criticize you, but there seme to be some serious misconceptions in the code, about how and where documents can be saved, about UIDocuments and Documents, etc.
ASKER
Yes, sjef, I understand there are misconceptions. This is the only way for me to learn. Thanks, I'll let you all know what my solution ends up being.
You'll get by with a little help... Do be back! You're learning the right way.
ASKER
Alright, here's an update.
I took many of your pieces of advice. My main concern was the advice from sjef:
>> Sorry clFlaVa, not to criticize you, but there seme to be some serious misconceptions in the code, about how and where documents can be saved, about UIDocuments and Documents, etc.
I've changed the functionality to the below, and it seems to work perfectly. Please let me know if you see any weak points.
--- --- --- --- ---
QUERYSAVE:
Sub Querysave(Source As Notesuidocument, Continue As Variant)
On Error Goto HandleError
If Source.IsNewDoc And Source.Document.ContractNu mber( 0 ) = "" Then
' give the contract a unique identifier
' Note: There are no calls to doc.Save NOR uidoc.Save in here
AssignUniqueID Source, CONTRACT_FORM
Else
' determine if any changes were made and record the changes
' Note: There are no calls to doc.Save NOR uidoc.Save in here
CompareValues CONTRACT_FORM
End If
Finish:
Exit Sub
HandleError:
Continue = False
Messagebox "An error occurred. Contract was not saved.", , "Error Saving..."
Resume Finish
End Sub
--- --- --- --- ---
Each Action Button Looks Very Similar To This (the action buttons can only be seen in edit mode) :
Sub Click(Source As Button)
If Messagebox( "Are you sure you want to submit this contract for PM approval?", MB_YESNO, "Submit?") = MB_YES Then
' No call to doc.Save NOR uidoc.Save in ValidateContract function
If ValidateContract Then
Dim uiw As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Set uidoc = uiw.CurrentDocument
Set doc = uidoc.Document
doc.ContractStatus = STATUS_2
' No call to doc.Save NOR uidoc.Save in this function
WriteLine "submitted this contract for PM approval."
uidoc.Save
uidoc.Close
End If
End If
End Sub
I took many of your pieces of advice. My main concern was the advice from sjef:
>> Sorry clFlaVa, not to criticize you, but there seme to be some serious misconceptions in the code, about how and where documents can be saved, about UIDocuments and Documents, etc.
I've changed the functionality to the below, and it seems to work perfectly. Please let me know if you see any weak points.
--- --- --- --- ---
QUERYSAVE:
Sub Querysave(Source As Notesuidocument, Continue As Variant)
On Error Goto HandleError
If Source.IsNewDoc And Source.Document.ContractNu
' give the contract a unique identifier
' Note: There are no calls to doc.Save NOR uidoc.Save in here
AssignUniqueID Source, CONTRACT_FORM
Else
' determine if any changes were made and record the changes
' Note: There are no calls to doc.Save NOR uidoc.Save in here
CompareValues CONTRACT_FORM
End If
Finish:
Exit Sub
HandleError:
Continue = False
Messagebox "An error occurred. Contract was not saved.", , "Error Saving..."
Resume Finish
End Sub
--- --- --- --- ---
Each Action Button Looks Very Similar To This (the action buttons can only be seen in edit mode) :
Sub Click(Source As Button)
If Messagebox( "Are you sure you want to submit this contract for PM approval?", MB_YESNO, "Submit?") = MB_YES Then
' No call to doc.Save NOR uidoc.Save in ValidateContract function
If ValidateContract Then
Dim uiw As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Set uidoc = uiw.CurrentDocument
Set doc = uidoc.Document
doc.ContractStatus = STATUS_2
' No call to doc.Save NOR uidoc.Save in this function
WriteLine "submitted this contract for PM approval."
uidoc.Save
uidoc.Close
End If
End If
End Sub
Better :) Only one question:
' No call to doc.Save NOR uidoc.Save in this function
WriteLine "submitted this contract for PM approval."
--> uidoc.Save ' in contradiction with the comment above!!
uidoc.Close
And? Does this work for you? If it does, we're all happy.
' No call to doc.Save NOR uidoc.Save in this function
WriteLine "submitted this contract for PM approval."
--> uidoc.Save ' in contradiction with the comment above!!
uidoc.Close
And? Does this work for you? If it does, we're all happy.
ASKER
I meant, no call to those save functions within the function WriteLine...
I thought the main problem I was having was that I was calling save in multiple places, whereas in my new code, i'm only calling it once, at the very end.
It works, just wanted to make sure it made better sense from the saving in uidoc/doc perspective...
I thought the main problem I was having was that I was calling save in multiple places, whereas in my new code, i'm only calling it once, at the very end.
It works, just wanted to make sure it made better sense from the saving in uidoc/doc perspective...
Looks great! Very transparent code.
ASKER
Cool thanks.
I think I'm going to do 80-20 for this between sjef and p_.
Any recommendations otherwise?
I think I'm going to do 80-20 for this between sjef and p_.
Any recommendations otherwise?
ASKER
This script is part of a script library, the audit trail is part of a separate script library. The audit trail initiates in the form's post open event, and gets compared on the querysave event.
So, do you have any suggestions as to how to handle this? Thanks.