When to use a Workflow vs a Trigger to Populate a Field

Pop Quiz: When you need to populate a field with a value, should you use a workflow or a trigger?

Answer: This is a trick question. 

Even for an experienced Salesforce developer this can be a tricky question. In theory both can result in the same intended outcome of a setting a field to a specific value. But are there any caveats to either, and do both cover all scenarios? Let’s list explore the pros and cons of each option:

Using a Workflow to populate a field value:
Pros :
• Fast & easy to implement and does not require APEX
• Can be configured on the fly
• Uses can enable/disable readily

• Users cannot control order in which field updates are made
• Performs a subsequent update on a record, which may cause triggers to fire again.

Using a Trigger to populate a field value:
• Users have more control of process.
• Triggers can be written to do all updates on a record in one operation.

• You’ll need an APEX developer
• Should create and update in sandbox, so it’s not easy to enable/disable
• Requires a unit test

Based on list above, it appears using a workflow to populate a field value is the best option. However, there are a few more factors to consider:
• Does something else need this new value?
• Is there another process that is dependent on this value being set?
• If so, are you certain that that process will occur after the workflow has fired set the value?

Let’s explore a use case: 

Recently I worked on a system where a Customer Number on a custom object needed to populate from the Parent Account. So, I created a workflow that would populate the Customer Number from the account when the record was created, or when the Account lookup field was changed. Our client also wanted to enforce that Customer Number on the object always had a value, so we created a validation rule. For the most part it worked, until someone discovered you could move the object record from one Account to another one that did not have a Customer Number. I was scratching my head wondering how this could happen? We have all the pieces in place, we always update the field from the parent and we always validate that it has a value. I realized the problem was the order of operations. At the bottom of this blog there is an excerpt from Force.com’s Order of Execution Guide.

Following along with the order of execution  you can see that the record gets updated, changing the Account Id and then the triggers run. The system then runs the validation rules (step 4 below), and sees that the Customer Number still has a value because we didn’t change it in the trigger. Then the workflow fires (step 10 below) to update the field, which in this case it is blanking it out since the new account doesn’t have a Customer Number. It is step 12 though that is the kicker; the system will re-run standard validation rules again, but custom validation rules are not run again.

So both the workflow and the validation rule were written correctly and both executing, but they were executing at the wrong time. Ultimately I ended up re-doing this functionality as a trigger, where I could better control when things would happen and know that the field has its final value early in the process.

The moral of the story here isn’t necessarily that workflows are bad and triggers are good. It is more that you have to be mindful of the many other things that are happening in Salesforce. A workflow might be perfect in some scenarios but not great in others. When you can afford the time and have the properly trained resources a trigger can almost always give you the control you need.

Excerpt of Salesforce Order of Execution:

  1. Loads the original record from the database or initializes the record for an upsert statement.
  2. Loads the new record field values from the request and overwrites the old values. Salesforce runs some system validation rules depending on if request came from UI Edit page
  3. Executes all before triggers.
  4. Runs most system validation steps again, such as verifying that all required fields have a non-null value, and runs any user-defined validation rules.
  5. Executes duplicate rules. If the duplicate rule identifies the record as a duplicate and uses the block action, the record is not saved and no further steps, such as after triggers and workflow rules, are taken.
  6. Saves the record to the database, but doesn’t commit yet.
  7. Executes all after triggers.
  8. Executes assignment rules.
  9. Executes auto-response rules.
  10. Executes workflow rules.
  11. If there are workflow field updates, updates the record again.
  12. If the record was updated with workflow field updates, fires before update triggers and after update triggers one more time (and only one more time), in addition to standard validations. Custom validation rules and duplicate rules are not run again.