Monday, September 16, 2024

Power Platform (MS CRM/CE) Business Rule Best Practices

Here are my top things I would do when creating a business rule:
  1. Set the Scope to a specific form (unless there is a really good reason to make it Entity scope)
  2. Make it affect only one field on a specific form
  3. Give it a name using the one form / field it is tied to
  4. Give it a description that explains WHY it is necessary, not a description of what it does
  5. Include the inverse action (ex: lock AND unlock) after the condition
I recommend using a scope that is specific to a form, because it is common to have multiple forms, and if you set the scope to All Forms or Entity, then you run the risk of having the logic have unexpected results. 

The reason to make it affect only one field is that it is very common for someone to remove a field from a form without realizing that the field is part of a business rule, and it causes the entire business rule to stop running. If you have a complex business rule that updates multiple fields, then you run the risk that future form maintenance will break the rule. By making a separate business rule for each field is that you can very clearly "declare" that one fields behavior separate from every other field on the form, thus removing a field from a form will not break all the other logic on the form. This is the same way that Canvas apps operate, using declarative approach, instead of procedural. 

Naming the business rule something like "Main Form Account Sync locked" is more meaningful than trying to invent a name that describes the logic that affects 10 fields. 

A description should inform the person that is maintaining the code "why" you have the business rule, for example "After the account is synchronized, this field is read-only so that users don't try to change it back to No". Imagine trying to write a useful description for multiple fields. 

The reason to have both branches of the condition covered is that (in most cases) a user is likely to start to enter a value in a field which triggers the business rule, then they change their mind and want to choose a different option, but if there is no alternate action to 'undo' what was set in the Yes condition, then the user is stuck. 

Wednesday, August 21, 2024

PowerAutomate Flows Trigger Multiple Times - a proposed workaround

Every now and then, I get a PowerAutomate Flow that seems to trigger more than once, and most of the time it is not a problem, but sometimes they are running in parallel and end up creating duplicate records which is undesirable. It happens most often when a Dataverse trigger Change Type is "Added or Modified". I suspect that something in the API is updating the record right after creating it. 

There is a "Concurrency Control" feature under the trigger settings that allows you to control running the flow in parallel. If you set this to 1, and save the flow, you cannot turn it off, so consider your options first. What this feature does is make your flows run one after the other, rather than at the same time (in parallel). While it can solve some of the problems with flows running in parallel, I have had situations where it did not. 

Recently I needed to generate a single record in an unrelated table, but the flow was running twice in parallel so two records were created. I came up with a workaround to get around this issue. Create a "Token Gate" field on the trigger table (single line of text) and follow these steps:
  1. When the flow starts, initialize a string variable called "Token" with a "guid()" expression
  2. Update the triggering record's Token Gate field using the Token from step #1
  3. Delay a few seconds (or up to 1 minute) to allow any parallel flows to complete step #2
  4. Get the trigger record (the one you updated in step #2)
  5. If the token generated in step #1 is not equal to the token received in step #4, then terminate the flow. 
Be sure that the trigger action uses Select Columns or Trigger Conditions so that step #2 does not trigger an endless loop of flows.