NotesForm: Reading a Database's Forms, Fields, and Who Can Use Them in Code
You inherit an NSF nobody documented, and you want to figure out what forms it actually has, what each one looks like, and who’s allowed to create documents with it. Clicking through Designer one by one works — but what if you’re writing an audit agent that sweeps dozens of databases for an inventory?
That’s the job of NotesForm. The definition is plain — “Represents a form in a database” — but the point is that it lets you read a form’s design information from code, no Designer required. Beyond “working with documents”, on the rarely-touched “reading the design” side, NotesForm is one of the main entry points.
TL;DR
- Get it from
NotesDatabase:db.Forms(all, returns an array) ordb.GetForm("name")(a specific one) - Read the design:
Name,Aliases,Fields(all field names, an array) - Read access control:
FormUsers(who can create documents with this form — the$FormUsersfield),Readers($Readers) IsSubFormtells you whether it’s a subform;GetFieldType(name)gets a field’s data type- Replication protection:
ProtectReaders/ProtectUsers(read-writeBoolean) stop$Readers/$FormUsersbeing overwritten by replication Remove()permanently deletes a form; most properties are read-only, with FormUsers / Readers / Protect* read-write
Getting forms: db.Forms and db.GetForm
Forms belong to a database, so you get them from NotesDatabase. To list them all, use db.Forms (returns an array) — the official example does exactly this:
Sub Initialize Dim session As New NotesSession Dim db As NotesDatabase Set db = session.CurrentDatabase Forall form In db.Forms Messagebox form.Name End ForallEnd SubFor a specific one, use db.GetForm("Memo"). One official caveat: “You can’t get access to private forms belonging to other people.” — you only get shared forms and your own.
Reading the design: Name / Aliases / Fields
Once you have form, these three read-only properties do the most work for “inventory”:
| Property | Holds |
|---|---|
Name | the form name |
Aliases | the form’s aliases (an array) — forms often have “display name | alias”, and code usually references the alias |
Fields | an array of every field name on the form |
Fields is especially handy — one line lists what fields a form defines, without opening the form design in Designer:
Dim form As NotesFormSet form = db.GetForm("Order")Forall fld In form.Fields Print fld & " : " & form.GetFieldType(fld) ' field name + typeEnd ForallGetFieldType(name) returns that field’s data type, which paired with Fields gives you a “form’s fields + types” listing.
Reading access: FormUsers and Readers
NotesForm also lets you read (and change) form-level access control:
FormUsers(read-write) — per the docs, when you create a form and specify who can create documents with it, those names are stored in the$FormUsersfield, and this property reads it.Readers(read-write) — reads the$Readersfield’s contents.
Paired with these are two replication-protection switches: ProtectReaders and ProtectUsers (read-write Boolean). They “protect $Readers / $FormUsers items from being overwritten by replication.” If you change a form’s reader/user settings in code in a multi-server environment, these flags decide whether your change survives replication.
Also worth knowing
IsSubForm(read-onlyBoolean) — whether this is a subform.Remove()— permanently deletes the form (use with care).HttpURL/NotesURL— the form’s Domino URL under HTTP / Notes protocols.Lock()/LockProvisional()/UnLock()— design-element locking, for when multiple people edit design.
What about Java and SSJS?
| Language | Counterpart | Obtained via |
|---|---|---|
Java (lotus.domino.*) | Form | db.getForm(name) / db.getForms() |
| SSJS / XPages | Form | database.getForm(name) |
Consistent across all three: obtained from the database, all read Name / Fields / FormUsers and so on. Note that in Java/SSJS Fields and Aliases are getFields() / getAliases() returning string arrays. When you write a Java audit tool scanning design, the property mapping here carries straight over.