A little story…
Back in ye olden days (circa 2011), the Nonprofit Starter Pack started collecting and categorizing the errors being created by the package. Sometimes they were problems in the code. Other times, they were things we had little to no control over. Most of the time though, they were related to errors during a regular NPSP action that were org-specific (meaning they didn’t occur in most orgs), most commonly rollups and 1×1 Account creation. Almost always, those errors were either custom validation rules or required field related problems. In this pie chart from data in the last half of 2012, green means stop: its a DML Exception, and means we tried to insert or update something in the NPSP, but couldn’t.
This problem was getting so bad that it was crowding out actionable data around NPSP errors that we COULD fix. Finally we just built an error console into the NPSP directly so users could view and handle at least the rollup errors by themselves.
Really though, this is just a way to help us triage the issue, and doesn’t address the underlying problem. Ultimately that can only be done by the Salesforce administrators (either by title or by accident) themselves. This post is to try and explain some options around how to make fields required, and the best use cases for each approach.
If types of requiredness were political philosophies, this is the fascist option. Creating a required field is simple, and seems like a straightforward answer to that dang intern who just can’t remember to ask members for their birthdates. To require a field is easy, when you’re creating it, just check the box next to ‘Required’. In fact, its probably too easy, as most people don’t realize just how required a required field is.
Its not terrible if there’s not data in your database and you’re starting from scratch. However, if you have existing data, here’s a quick test to apply to the field creation before checking that box:
Am I comfortable with deleting every record in my database that does NOT have a value for this field?
If that answer is ‘No’, you probably don’t want a required field. Read on.
If required fields are fascist, then Page Layouts are communist. Ultimately they have the same authoritarian streak, but with layouts, there are exceptions. Those exceptions are called the “politburo”, errr… system administrators. This makes the field required for the proletariat (users) and completely optional for the ruling class (system administrators). Most importantly, requiring a field in this manner doesn’t affect existing processes that may run as part of the NPSP or other types of code. Its also really easy to do. Just edit your page layout, hover over the field you want to require, click the little wrench icon, select ‘Required’. Click ‘OK’, save your layout. You’ll need to do it to each of the layouts you want the field to be required on, but its fast, effective, and easy.
You can also easily edit the page layout requiredness for a field based on profile by going to the field in the setup menu, selecting Field Accessibility at the top, then clicking on the value next to the profile you want to edit.
Custom Validation Rules
Custom validation rules are the oligarchy of our requiredness. There are complex, convoluted systems of negotiation ultimately controlled by a handful of skilled administrators and rule creators to better there own profit margins. (This ‘governance’ metaphor is really starting to breakdown quickly, eh?) Custom validation rules actually provide an amazing tool for complex forms of validation. If you have fields that have dependencies tied to their requiredness (field X should be required only if field Y is set to true), then validation rules are for you. Keep in mind that validation rules, like required fields apply to everybody. However, because validation rules provide so much flexibility, you do have some options. I’ll share two that I used at this past year’s Dreamforce NPSP Hands on Training Session.
Lets suppose you want to make sure a new field is required only for newly created records. Think about the question I asked about required fields: Could I delete every record that doesn’t have a value for the field? If you answered ‘no’, chances are this kind of validation rule may be a better fit. Its easy to create the syntax also:
We’re saying: If the field is new and the value of MyFieldName__c is blank, then throw a validation exception. This is a great way to apply requiredness to field that won’t come back to bite you when running updates, etc.
Another approach is to only make a field required for a certain user profile or type of user. This is somewhat similar to the advantages of page layout requiredness, but with much more fine grained control:
AND($User.ProfileId != '
This is somewhat similar to the above, but instead would fire on update as well. The other big difference is that it won’t fire if the user modifying the record is a system administrator. To make this work, you’ll need to get the Salesforce Id for your local system administrator profile and replace the text
Finally, Apex is the weird dystopian self-aware-robot form of governance. (Okay, the metaphor is officially dead.) This is the ultimate in control. Need to check inventory in a different object before making a field required? Done. Need to calculate a complex value based on multiple objects? No problem. The syntax is pretty easy too in a before trigger. Here’s an example on a Contact that looks for any other Contacts named ‘Kevin Bromer’. If it finds any, it will reject any attempt to insert a new ‘Kevin Bromer’ Contact into the database:
When a user attempts to insert a new ‘Kevin Bromer’ Contact, the trigger rejects the value and adds its own error message to the Contact page:
For the vast majority of use cases I see, requiring a field at the page layout level is more than sufficient. Keep in mind, its been said that true socialism has never been tried, so give page layout requiredness a chance before relegating your users to life of fascism (required fields) or the manipulative control of an unnecessary oligopoly (custom validation rules).