ShowTable of Contents
Introduction
The Designer help mentions that you can write a formula to calculate the section editors on a Notes form and gives a few examples, but it's a little vague about how this formula works and what value it's expected to return. This document provides those details.
How These Formulas Work
The section access list is essentially a field, and if you don't select "computed for display," the value of the field is stored in the document.
There are a few basic rules that govern the behavior of section access lists:
- When you open the document, Notes looks at the stored value to decide whether this user has access to edit the contents of the section.
- Only if there is no stored value will Notes calculate the value on document open, and use that value to control access.
- Changes you make while the document is open, do not affect the user's access.
This last point often trips people up. They write a formula, change some field that the formula uses which should result in the current user getting access to the section, and they still can't edit it. Refreshing the document (F9 key) doesn't help. This is why; Notes only cares about the value when you open the document.
The second point is often a problem also, as people tend to select "Computed" and write formulas that return @Username to give the current user access. But since the value of the field is stored, Notes doesn't need to calculate it on opening the document. So it would still contain the username of the last user to edit the document, not the current user.
The value returned by the formula, should be the list of people, groups and roles who are allowed to edit the section contents. Developers occasionally make the mistake of thinking of this as similar to the hide formula, and have it return a true-false value.
These and other errors are addressed in greater detail below.
Common Errors
Returning a true/false value
Users who are used to writing hide formulas, often assume this formula is like a hide formula. It's not. This formula returns a list of usernames, group or role names. If the current user is in that list, or is a member of a group or role in the list, they are allowed to edit the section (provided they also have access to edit the document).
Incorrect formula | Corrected formula |
@If(@Username = Approver; @True; @False)
or
@Username = Approver | Approver |
Returning a delimited string rather than a list
The editors list is multivalued, so you can return multiple users, groups or roles, or a mixture of these. But you must use the correct list notation to distinguish the multiple values. A comma or semicolon in a string, will not work.
Incorrect formula | Corrected formula |
"[Approver],[Admin]" | "[Approver]" : "[Admin]" |
DesignatedSigner+",[BackupApprovers]" | DesignatedSigner : "[BackupApprovers]" |
Abbreviated or Common Names
Try to avoid using usernames in section editor lists; group names are better, and roles are best of all. But as with all access control lists, if you do use a username, use the full canonical name ("CN=Abra Bean/O=TerrorByte Corp") not the abbreviated or common syntax, which only work in some situations.
Changing access while the document is open
Like a computed field, the value of the section editors list can change while you are editing the document, if it's of the "Computed" type and you refresh the document. However, the Notes client only cares what the value of the field is when the document is opened. So, suppose you have the following formula (copied from Designer help examples):
@If(Status = "Submitted"; "[Editors]":"[Admins]"; Status = "Draft"; OriginalAuthor; "-nobody-")
If you have a control that changes the Status to Draft while the document is still open, and your name is in the OriginalAuthor field, you might expect to immediately be able to edit the contents of the section. But to make Notes notice that the list has changed, you will have to save, close and reopen the document. That's why, when there's a workflow process, the button to change the status normally will also save and close the document.
Note: it's possible to close and reopen a document without saving it, as described in the "update rich text tip" in the references.
Returning @UserName when you could use a role
We often see formulas such as this:
Incorrect formula | Corrected formula |
@If(@UserRoles = "[Approver]"; @UserName; "-nobody-")
or
@If(@Contains(@UserRoles; "[Approver]"); @UserName; "-nobody-") | "[Approver]" |
The first formula will sometimes work, but it's unnecessarily complicated. The formula using @Contains is just plain wrong (see "How to write a hide formula" in the references). If you just want people in one or a few roles to edit the section, your formula should just return a list of those roles. The Notes client takes care of testing whether the current user is a member of the role; you don't have to.
It's nearly always wrong to use @UserRoles or @UserNamesList in a section access formula.
Your formula doesn't need to test the user's memberships. Just return the list of groups or roles that should have access.
Plus, @UserName fails if the editors list is not "Computed for display". With other field types, you've saved the current username in the document. When the next user opens the document, the formula is not recalculated, so even if the new user is a member of the role, they don't have access to the section unless they save and reopen the document.
Thinking the formula will recalculate when the document is opened
The section editors list is much like a hidden form field. If it's "computed for display," the field's value is not stored in the document, so it has to be recalculated every time a user opens the document.
For all other field types, however, the editor list formula is not recalculated on opening the document, unless it is not already stored in the document (e.g. when the document is composed). If you write a formula that's based on information about the current user, it will not work in a "Computed" editors list because the formula is not computed when the document is opened, and recalculating to the correct value later on during editing, doesn't help.
Incorrect formula | Corrected formula |
REM {formula is "Computed"}; @If(Status = "Draft"; @UserName; "-nobody-") | REM {formula is "Computed for display"}; @If(Status = "Draft"; @UserName; "-nobody-") |
Not realizing that a design change may also require re-editing the document
When you make a change such as in the previous section, switching a section access list formula from "Computed" to "Computed for display", you might then go open one of your documents and try whether the change has worked.
It hasn't. That's because even for a "Computed for display" value, the rule is the same. When you open the document, the field value is computed only if it is not already stored in the document. Because the formula was previously "Computed", existing documents already have a value stored. When you change the form design, you will have to edit and save the document once with the new design, to make it remove the old stored value. Now when you open the document, the value is calculated on open, and everything works.
Instead of manually editing documents, you can write an agent to update documents. This is a common technique that's extensively documented elsewhere, including in the Designer help. Please note the section fieldname is an editable property of the section when you're designing the form; this is the fieldname you would refer to in your agent code, and in general you would want to delete the item (in formula language, FIELD sectionname := @DeleteField), though in some cases you have just changed the formula and want to make all existing documents store the new computed value.
Another way that might work is to use @Command([ToolsRefreshSelectedDocs]), however this is a bit riskier since it may modify other fields that you didn't wish to change.
References
- How to Write a Hide Formula contains useful tips on writing formulas generally, and was referenced above for its information about @Contains.
- Update rich text tip shows how to close and reopen a document without saving it, which is useful if your section access list has been updated and you need to reapply it during the current editing session.