Prevent Validation Errors When F9 Is Pressed
There's always the trouble with validation formulas executing when you don't want them to execute. For example, if you have a radio button set to "Refresh Fields On Keyword Change", then validation formulas will execute when the value changes and your users will get prompted with their errors. This would be a case where you don't want the users to be prompted. One thing you can do is use the @IsDocBeingRecalculated function in your validation formulas to prevent the validation from happening:
@If(@IsDocBeingRecalculated; @Success; ... (rest of validation formula) ...)
For example, let's say we want to check the field "Untitled" for a blank value:
@If(@IsDocBeingRecalculated; @Success; Untitled = ""; @Failure("Please fill out this field"); @Success)
If you do this, then every time you refresh the document (the user presses F9, a keyword field changes, or you call uiDoc.Refresh in a script, as outlined in this document), then the validation will not cause any errors.
That's all well and good, but what if you want to find out if a form is valid before you write it to disk? Well, the @IsValid formula runs through validation and returns @True if the form passes validation, but all that does is refresh the document - which would pass validation with all the new functions.
If you're working with LotusScript, there's a way you can check the document before saving. First, use the same validation formulas outlined above. Next, your LotusScript action button can make an attempt at saving the document and see if the validation fails:
Dim ws As New notesUIWorkspace
Dim uiDoc As notesUIDocument
Set uiDoc = ws.currentDocument
On Error Resume Next
Call uiDoc.Save
On Error Goto 0
If Err <> 0 Then
Err = 0
Exit Sub
End If
' ... Continue with your code ...
Again, this just expands on the same ideas as the other tip and traps for an error, tries to save the document (the other tip tries to refresh), and exits if there was an error trying to save.
Note that if there isn't an error, the document is written to disk. That may or may not be important to your code. For example, you may want to check to see document would save, then set some fields, then actually do the save. In that case you would end up with 2 saves, unless you read on to the next page...
OK, so you had your script:
Dim ws As New notesUIWorkspace
Dim uiDoc As notesUIDocument
Set uiDoc = ws.currentDocument
On Error Resume Next
Call uiDoc.Save
On Error Goto 0
If Err <> 0 Then
Err = 0
Exit Sub
End If
' ... Continue with your code ...
But what if you didn't really want to save that early in your code? You want to set some other fields first and then save? Well, there's a more complicated way to accomplish the methods outlined above.
First, you are going to create a computed for display, text, field that will add some control to the validation formulas. Let's call the field "FlagRefresh". The field can be hidden all the time and it doesn't matter where the field appears on your form. The value for this field will be:
@If(@IsDocBeingLoaded; "0"; FlagRefresh)
What this does is initially set the field to a text zero when the document is opened, and then leaves it alone from that point on.
Next, you'll need to update your validation formulas. Let's give the example again of checking for the field called "Untitled" to be blank:
@If(@IsDocBeingSaved; @If(Untitled = ""; @Failure("Please fill out this field"); @Success); FlagRefresh = "0"; @Success; Untitled = ""; @Failure("Please fill out this field"); @Success)
Hopefully you see what's going on. If the document is being saved, we go through the validation formulas. Then we check to see if that new field is set to "0", which will be the case if the user has pressed F9 or the document is refreshing because of a keyword change, or if you called uiDoc.Refresh in a script. If that's the case, then the validation succeeds. Lastly (the document is not being saved and the FlagRefresh field is not zero), we go through the validation again.
Note that we have to put the @IsDocBeingSaved in the formula because simply checking FlagRefresh being zero would allow the document to be saved without checking validation formulas.
NOTE: You might have thought you could get around that by changing FlagRefresh to "1" if the document is being saved. Like this formula: @If(@IsDocBeingLoaded; "0"; @IsDocBeingSaved; "1"; FlagRefresh). That wouldn't entirely work. Once the user tries to save the document, the field will be set to "1" and remain at "1" even if the document doesn't save. So that means that if the user presses F9 after that point (or if they change a keyword value which causes the document to refresh), all validation formulas will be run through because FlagRefresh is still "1". So it must be done the way that is outlined above.
Now, the script code changes slightly:
Dim ws As New notesUIWorkspace
Dim uiDoc As notesUIDocument
Dim doc As notesDocument
Set uiDoc = ws.currentDocument
Set doc = uiDoc.document
Call doc.replaceItemValue("FlagRefresh", "1")
On Error Resume Next
Call uiDoc.Refresh
On Error Goto 0
Call doc.replaceItemValue("FlagRefresh", "0")
If Err <> 0 Then
Err = 0
Exit Sub
End If
' ... Continue with your code ...
The difference here is that we set the "FlagRefresh" field in the back-end document. Then when the Refresh method is called, the field has been set to "1" which will cause the validation formulas to exectue even though we only called the Refresh method. After calling the Refresh method, the field is set back to "0" for the next refresh by the user or by a keyword field changing. Again, if there was an error trapped trying to refresh, the code quits. If there wasn't an error the code continues and you can do whatever you want.