Link to home
Start Free TrialLog in
Avatar of cLFlaVA
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.ContractStatus = 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
ASKER CERTIFIED SOLUTION
Avatar of Sjef Bosman
Sjef Bosman
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cLFlaVA
cLFlaVA

ASKER

Thanks a ton for your suggestions.  One thing though, is that I've got an Audit Trail running on the form's querysave event, so that's why I was calling it from there.

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.
Avatar of cLFlaVA

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?
Avatar of cLFlaVA

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
Avatar of cLFlaVA

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
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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??
Hey Bro, Don't you have to be in a meeting??
It's holiday mood here, so no meeting only stealing :)

Partha
Avatar of cLFlaVA

ASKER

Would I have to set this SaveOptions field every time I'm saving something, then?  Or will it reset all the time?
Avatar of cLFlaVA

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.
Grrrrrrr!

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.ContractStatus = STATUS_3
         Else
              uidoc.Document.SOWStatus = STATUS_3
         End If
         
         uidoc.Save
call uidoc.fieldsettext("saveoptions","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
I call this a kludge...
Have to go to a meeting now  did i answer anythign here ?:-)

Partha
Avatar of cLFlaVA

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?
Avatar of cLFlaVA

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
Avatar of cLFlaVA

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
Avatar of cLFlaVA

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
Avatar of cLFlaVA

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.
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
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(uidoc.Document, 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??
Avatar of cLFlaVA

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
Avatar of cLFlaVA

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.ContractNumber( 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
Avatar of cLFlaVA

ASKER

i've got two meetings now - i'll definitely be back to continue this.

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/QueryClose 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.ProcessingOption(0)
    Case "DRAFT"
        Call UpdateAuditHistoryRoutine
        Source.Document.ProcessingOption = "OKTOSAVE"
    Case "SUBMIT"
        If CheckValidationsRoutine() Then
            Call UpdateAuditHistoryRoutine
            Source.Document.ProcessingOption = "OKTOSAVE"
        Else
            Continue = False 'prevent save
            Source.Document.ProcessingOption = ""
        End If
    Case Else
        Msgbox "Unknown save process",,Source.Document.ProcessingOption(0)
        Continue = False
End Select


PostSave:
If Source.Document.ProcessingOption(0) = "OKTOSAVE" Then
    Source.Document.ProcessingOption = "SAVED"
Else
    Source.Document.ProcessingOption = ""
End If

QueryClose:
If Source.Document.ProcessingOption(0) <> "SAVED" Then
    Source.Document.ProcessingOption = ""
    Msgbox "Unknown close process",,Source.Document.ProcessingOption(0)
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.ContractStatus = 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
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.
Avatar of cLFlaVA

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.
Avatar of cLFlaVA

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.ContractNumber( 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
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.
Avatar of cLFlaVA

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...
Looks great! Very transparent code.
Avatar of cLFlaVA

ASKER

Cool thanks.

I think I'm going to do 80-20 for this between sjef and p_.

Any recommendations otherwise?