One of those little Access quirks that can make you question your sanity is when a function works perfectly in a query, form, report, or VBA procedure, but suddenly gets rejected when you put it in a table-level validation rule. The classic example is Nz. You know it works. Access knows it works. Yet the table validation property looks at it and says, "Unknown function." Thanks, Access.
The important thing to understand is that table-level validation rules do not use the exact same expression environment as queries, forms, reports, and VBA. They support many common expressions, but not every Access function is available there. So when Access complains that Nz is unknown in a validation expression, the problem usually is not spelling, syntax, broken references, or anything else you did wrong. It is simply an unsupported function in that particular context.
Nz is normally used to replace a Null value with something more useful. For example, in a query you might use it to treat a missing amount as zero. In a form control, you might use it so the user sees a blank string instead of Null. It is one of the handiest functions in Access, and I use it constantly.
But if you try to use something like Nz([Amount],0) in a table-level validation rule, Access can reject it with an "unknown function" message. That error is misleading because Nz is not unknown to Access in general. It is unknown to the validation-rule engine.
So what do you use instead? For table validation rules, rely on the expressions that Access does allow in that property. The most useful tools for dealing with missing values are Is Null and IIf, depending on the rule you are trying to enforce.
For example, suppose an Amount field is optional, but if a user enters a value, it cannot be negative. A table-level validation rule can allow either a missing value or a value greater than or equal to zero. The basic logic is: the field is Null or the value is non-negative.
That distinction matters because Null is not zero. A Null means "no value has been entered." Zero is an actual value. Sometimes treating Null as zero is exactly what you want, especially for calculations. Other times, it can hide missing data that ought to remain missing. Before automatically converting Null to zero, make sure that zero genuinely means the same thing for your business rules.
If your validation depends on more than one field, table-level validation rules can still be useful. For example, you might require an end date to be later than a start date, unless the end date has not been entered yet. In that situation, test for Null explicitly before applying the comparison. Otherwise, Null can cause the validation expression to behave in ways that are not immediately obvious.
This is also a good reason to keep table-level validation rules reasonably simple. They are excellent for protecting the data regardless of how it gets entered: through a form, directly in the table, through an append query, or from some other process. That is a big advantage. A form's validation code only runs when someone uses that form. Table rules help protect the data at the source.
On the other hand, if the validation starts getting complicated, you may be better off handling the user-facing part in a form's Before Update event. There, you have much more flexibility, better error messages, and access to the full range of VBA functions. Just remember that form-level code is not a substitute for table-level protection when the data can be edited through other paths.
The practical takeaway is simple: do not copy an expression from a query or form into a table validation rule and assume every function will be supported. If Nz gets rejected, you are not crazy, and it does not mean that your database is broken. Rewrite the rule using explicit Null checks such as Is Null, along with the comparison logic the rule needs.
Watch the embedded video for the full walkthrough and demonstration of this odd little Access limitation. Once you know table validation rules have their own expression restrictions, this particular error becomes much less mysterious.
Live long and prosper,
RR