Go beyond basic business rules and learn how to stack visibility, lock, and requirement actions on a single rule, build real AND/OR multi-condition logic, and control when and where rules fire using scope — all without writing a line of code. Built around a realistic service contract scenario with a complete hands-on exercise.

Picture this: your sales team uses a model-driven app to manage service contracts. When a contract type is "Government," several additional fields — procurement officer name, federal contract number, and compliance attestation — need to appear on the form, become required, and lock down once a supervisor has countersigned. When the contract type is anything else, those fields should be invisible, so they don't clutter the form or confuse users. And depending on whether the record is in a draft or active state, some fields should be editable while others lock down entirely.
You could handle all of this with JavaScript. But that means maintaining script files, dealing with browser dependencies, debugging across form loads, and handing off code to a developer every time a business analyst wants to tweak a condition. Business rules let you do the same work declaratively — in a visual editor, stored as solution components, and testable without writing a single line of code. The catch is that they have real scope constraints, ordering behaviors, and interaction patterns that trip up even experienced makers.
By the end of this lesson, you'll have a solid command of how business rules work at the column level in Dataverse: how to stack visibility, lock, and requirement actions in a single rule, how to chain multiple conditions using AND/OR logic, and how scope choices affect where a rule fires. You'll build a realistic multi-condition ruleset for a service contract scenario and learn how to debug the situations where rules don't behave the way you expect.
What you'll learn:
You should already be comfortable with the fundamentals covered in Business Rules in Dataverse: Validation and Field Logic Without Code — meaning you've built at least a basic rule with a condition and a set-field action. You should also have a working model-driven app with a Dataverse table, and understand how forms are structured (tabs, sections, columns). If you need a refresher on form anatomy, check out Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms.
You don't need to know JavaScript or Power Fx to follow this lesson.
Before you combine actions and conditions, you need to nail down scope — because getting this wrong is the single most common reason rules "don't work" in production.
When you open the business rule designer and look at the Scope dropdown in the properties panel, you have two meaningful options for most tables: Entity and a specific Form. (Quick Create forms and the deprecated process form types exist too, but we'll focus on the ones you'll actually use.)
Entity scope means the rule runs on the server when a record is saved, in addition to running on the client inside any form that loads the rule. The rule logic is enforced at the data layer regardless of which form the user is on — or whether they're even using a form at all (for example, if data is being written via the API or Power Automate). However, this comes with an important restriction: Visibility actions do not execute at Entity scope. You cannot show or hide a column at the server level because there's no UI to manipulate. If your rule includes a Visibility action and you set scope to Entity, the Visibility action is simply ignored at the server — it will still fire on forms, but you lose the guarantee that it fires everywhere.
Form scope means the rule runs only on that specific form. It won't execute during API writes, Power Automate flows, or on any other form. This is the right choice when your logic is purely about the user experience — what fields are visible, what's editable — rather than data integrity.
Key insight
Think of it this way — if the rule enforces a business rule that must hold true in the data regardless of how a record is written, use Entity scope and use Set Field Value or Validation actions. If the rule is about guiding the user's experience on a specific form, use Form scope and include Visibility actions freely.
Here's where practitioners get burned: they build a rule with Visibility actions, set the scope to Entity (thinking "more enforcement is better"), and then spend an hour wondering why columns disappear on load regardless of conditions — or why the rule behaves differently across their main form and quick create form. Scope drives behavior more than any other setting.
For our service contract scenario, we'll use two separate rules:
This split approach is the production-ready pattern. Validation and requirement logic at Entity scope; visibility and UX logic at Form scope.
Business rules give you four categories of actions: Set Field Value, Set Business Required, Set Visibility, and Lock/Unlock (referred to as "Set Field Disabled" in the designer). Let's look closely at how these three UX-oriented actions behave at the column level.
This action shows or hides a specific column on the form. A hidden column is not just blank — it is completely removed from the form's visible area, which collapses the space it occupied. This matters for layout design: if you hide a column in a two-column section, the other column in that row shifts to fill the space.
You can set visibility to True (show) or False (hide). Every rule that affects a given column's visibility wins based on which rule evaluates last — and that ordering is configurable (more on this shortly).
Warning
Hiding a column with a business rule does not prevent the field's value from being submitted. If a field has a value, that value saves even if the field was hidden during the session. If you need to clear hidden fields, you'll need a separate Set Field Value action to null out the value when hiding.
This locks the column so the user can read it but cannot change it. This is distinct from column-level security (handled at the Dataverse security layer — see Column-Level Security and Record Sharing in Dataverse for that topic). The Disabled action is purely a form-layer behavior. A user with the right security role could still write to the field via another method.
Lock is especially useful for fields that should be read-only after a workflow milestone — like locking an approved amount once a manager has signed off.
This toggles whether a field must be filled in before the record can be saved. You can set it to Business Required, Business Recommended (which shows a soft indicator but doesn't block save), or Not Required.
Warning
If you use Set Business Required to make a field required at Entity scope, be extremely careful when that rule fires during programmatic record creation. If your Power Automate flow creates a contract record without populating the federal contract number, the flow will fail with a validation error if the condition that triggers the requirement is met. Test your automation paths explicitly when using Entity-scoped requirement rules.
Here's where the power really shows up. Instead of writing three separate rules — one for visibility, one for locking, one for requirement — you can stack all three actions on a single condition branch. The rule evaluates the condition once and fires all actions together.
For our contract scenario, a single rule can say:
IF Contract Type = Government
THEN Show "Federal Contract Number"
AND Make "Federal Contract Number" Business Required
AND Show "Compliance Attestation"
AND Make "Compliance Attestation" Business Required
And the ELSE branch:
ELSE Hide "Federal Contract Number"
AND Clear "Federal Contract Number"
AND Make "Federal Contract Number" Not Required
AND Hide "Compliance Attestation"
This is cleaner than six separate rules and eliminates ordering ambiguity between them.
Simple single-condition rules are easy. Real-world logic is almost never that simple. Let's build out the full conditional logic for the service contract scenario.
Our Service Contract table has these columns:
The business requirements:
Open the business rule designer for the Service Contract table. Create a new rule named "Government Contract Fields." Set scope to Form (Main Form).
In the condition, set:
Then in the action pane, add the following actions for the TRUE branch:
Then click Add Else and build the FALSE branch:
Activate and save. The ELSE branch with the clear actions is the part most tutorials skip — without it, a user could select Government, fill in the Federal Contract Number, then change back to Commercial, and the federal number would persist invisibly and save with the record.
Create a new rule named "Lock Countersigned Fields." Set scope to Form (Main Form).
This rule needs two conditions that must both be true: Contract Type = Government AND Countersigned = Yes.
In the condition editor, you'll see a toggle between AND and OR at the top of the condition group. Leave it set to AND. Add two condition rows:
Then in the TRUE branch:
In the ELSE branch:
Tip
The ELSE branch that re-enables fields is critical. If you skip it and a user sets Countersigned = Yes by mistake, then unchecks it, the fields remain locked because no rule told them to unlock. Always write the full inverse unless you have a specific reason not to.
Create a rule named "High-Value Legal Review Required." Set scope to Entity (because this is a data integrity rule — we don't want anyone bypassing it by saving through the API).
This rule needs a single condition:
Note
The business rule condition editor supports numeric comparison operators (Greater Than, Less Than, Greater Than or Equal To, Less Than or Equal To) for currency and numeric columns. Use these rather than trying to build threshold logic with Choice columns.
TRUE branch:
ELSE branch:
The Show Error Message action is a validation action — it fires when the user tries to save and blocks the save if the condition is true and the field is empty. At Entity scope, this fires on form save and on API writes, which is exactly what you want here.
Create a rule named "Lock Closed Contracts." Set scope to Form (Main Form).
Condition:
TRUE branch — lock every field the user might otherwise edit:
ELSE branch: Set each of the above fields to Enabled.
Key insight
Notice that this rule might conflict with Rule 2 — both rules lock Federal Contract Number. When Status = Closed and Countersigned = Yes, both rules evaluate the lock action for the same column. Fortunately, both agree on the outcome (Disabled). But if they disagreed, you'd need to understand rule ordering, which we'll cover next.
When multiple rules affect the same column with potentially conflicting actions, rule ordering becomes critical. In the business rule list, you can reorder rules by dragging them or using the move controls. Rules execute in the order listed — top to bottom — and the last rule to set a property on a column wins.
This means:
This "last writer wins" model is simple but requires deliberate thought when you have rules that cover overlapping conditions.
The recommended approach for our scenario:
Order the rules like this:
The rationale: Lock Closed Contracts should always have the final say on locking. If a contract is Closed, nothing else should unlock those fields — so that rule runs last. The government visibility rule runs first, establishing the baseline field visibility. The lock rules run after, applying restrictions on top.
To reorder rules, navigate to the table's business rules list in make.powerapps.com (Table → Business Rules tab), and use the sequence controls on the list.
Warning
The rule order in the list view is the execution order. But there's a nuance: rules only fire when their conditions change or when the form loads. If multiple rules are active on load, they all evaluate in sequence at that moment. Mid-session, individual rules fire when their trigger columns change. This means a mid-session condition change only triggers the rules watching that specific column — not all rules. Design your rules so that any single column change fires all rules that depend on it, not just rules that list it as the only condition.
The standard condition editor handles most cases, but sometimes you need logic that crosses columns in ways the AND/OR grid can't express cleanly. For these situations, business rules support a Formula condition type, where you write an expression directly.
Formula conditions use a subset of Power Fx-like syntax (actually closer to classic CRM expression syntax). Here are some patterns that come up in real projects:
Check if a field is null or empty:
Federal Contract Number = null
Compare two date columns:
End Date > Start Date
Numeric range check:
Contract Value >= 100000 && Contract Value <= 500000
Check multiple choice values (OR condition in formula):
Contract Type = "Government" || Contract Type = "Federal Education"
Tip
Formula conditions shine when you need OR logic across different fields in a way that can't be expressed as a simple AND group. For example: "Show the override field if Status = Draft OR (Status = Active AND Contract Value < 10000)." That nested OR/AND structure is awkward in the visual grid but clean as a formula expression.
To use a formula condition: in the condition pane of the rule designer, click the condition block and look for the Formula tab alongside the Field tab. Switch to Formula, and type your expression directly. The editor will validate the syntax when you click away.
Be aware that formula conditions at Entity scope are evaluated server-side, and the syntax is validated against the Dataverse expression engine — not Power Fx. Test them carefully on save events.
One form type that catches practitioners off guard is the Quick Create form. When a user creates a record via a lookup field's quick create panel, the Quick Create form loads — not the Main form. Business rules scoped to the Main form do not fire here.
This creates a practical problem: if your requirement rule is Form-scoped to the Main form, a user creating a Government contract through a Quick Create form won't see those fields at all, and won't be required to fill them in — until they open the full record.
Your options:
Option 2 paired with option 3 is the cleanest production pattern. Use the full Main form for complex records and keep Quick Create simple.
Note
Quick View forms are read-only panels embedded in related record forms. Business rules do not apply to Quick View forms — there are no editable fields in them. Don't try to configure business rules on Quick View form components.
You'll build the complete service contract ruleset from scratch. This exercise assumes you have a model-driven app with a Service Contract table set up, or can create one quickly.
If you're starting fresh, create a table called Service Contract with the following columns:
Add all columns to the Main form. Add the government-specific columns (Federal Contract Number, Procurement Officer, Compliance Attestation) to a dedicated section called "Government Contract Details."
For form design guidance, refer to Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms.
Navigate to your table → Business Rules → New. Name it Government Contract Fields, set scope to Main Form.
Build the condition (Contract Type = Government) and add all six TRUE and ELSE actions as described in the multi-action section above. Activate the rule.
Test: Open a new Service Contract record. The government fields should be hidden. Change Contract Type to Government — fields should appear and become required. Change it back — fields should disappear and clear.
Create rule Lock Countersigned Fields, scope to Main Form. Add both AND conditions (Government + Countersigned = Yes). Add lock actions in TRUE branch, unlock in ELSE. Activate.
Test: With Contract Type = Government, check Countersigned. The three government-specific fields should become read-only. Uncheck Countersigned — they should become editable again.
Create rule High-Value Legal Review Required, scope to Entity. Set condition Contract Value > 500000. Add Business Required action and Show Error Message in TRUE branch. Add Not Required in ELSE. Activate.
Test: Enter Contract Value = 600000 and try to save without filling Requires Legal Review. The save should be blocked with your error message. Set Contract Value = 400000 — save should proceed without that requirement.
Create rule Lock Closed Contracts, scope to Main Form. Set Status = Closed. Add disabled actions for all editable fields in TRUE, enabled in ELSE. Activate.
Test: Change Status to Closed — all listed fields should lock. Change Status to Draft — they should unlock.
Go to the business rules list for the table. Reorder so the sequence is: Government Contract Fields → High-Value Legal Review → Lock Countersigned Fields → Lock Closed Contracts.
Create a Government contract with Contract Value = 750000. Fill all government fields, check Countersigned, and set Status to Active. Verify: government fields visible, required, and locked after countersign. Now change Status to Closed — verify all fields lock. Change Status back to Active — verify fields unlock but remain locked due to countersign rule.
Mistake 1: Rules that fire but seem to have no effect
The most common cause is a Visibility action on an Entity-scoped rule. Check scope first. If you need both server enforcement and visibility control, split into two rules.
Mistake 2: Fields re-enabling after Status change due to ELSE branch
If your Lock Closed Contracts rule has an ELSE that enables all fields, and a user changes Status from Closed to Active on a Government Countersigned record, the enable ELSE fires and overrides the Lock Countersigned Fields rule — because the status-based rule fires after the countersign rule in the sequence (it runs last). Fix: reorder so Lock Countersigned Fields runs after Lock Closed Contracts. But now you're in a conflict. The real fix is using a formula condition in Lock Countersigned Fields that accounts for Status ≠ Closed, so it doesn't try to enable fields on a closed record.
Mistake 3: Required fields blocking save even when hidden
If your ELSE branch hides a government field but doesn't remove the Business Required flag, and a separate Entity-scoped rule marks it as required, the field will block save even though it's invisible. Always pair hide actions with Not Required actions and clear-value actions on the same branch.
Mistake 4: Business rules not updating mid-session
Business rules re-evaluate when a field in their condition changes. If a condition uses Contract Type, the rule fires when Contract Type changes. It also fires on form load. It does not fire when an unrelated field changes. If you're expecting a rule to react to an external change (like a related record update), that won't happen — you'd need a Power Automate flow to update a column on the record itself to trigger the rule.
Mistake 5: Duplicate rules creating contradictory states
If you accidentally activate two similar rules with overlapping conditions and contradictory actions (one requiring, one unrequiring the same field under the same condition), the last one in the sequence wins — but the behavior becomes confusing. Audit your active rules regularly. In make.powerapps.com, filter the Business Rules list to "Active" to see what's actually running.
Tip
When debugging unexpected business rule behavior, open the form in your browser's developer console and look for Mscrm.BusinessRuleManager log entries. The form logs rule evaluation results including which rules fired and which conditions evaluated to true or false. This is the fastest way to diagnose rule conflicts without guessing.
Mistake 6: Forgetting that Quick Create forms ignore Main Form rules
A user creates a Government contract via quick create, skips the required fields (because the rule isn't firing), and saves a record with missing data. Then the main form opens and shows an inconsistent state. Use Entity-scope requirement enforcement as the backstop.
Business rules are more powerful than they first appear — not because any individual action is complex, but because combining Visibility, Lock, and Requirement actions with multi-condition AND/OR logic, across the right scope, lets you build a genuinely responsive form experience without code. The key concepts to lock in from this lesson:
From here, there are two natural directions to explore. If your form logic is getting complex enough that business rules are becoming hard to maintain — particularly if you need logic that reacts to subgrid data or related record values — it's worth looking at JavaScript-based form handlers, which handle cases business rules can't. But before going there, consider whether Business Process Flows: Guiding Users Through Multi-Stage Processes in Power Apps might handle some of the progression logic (like moving from Draft to Active to Closed) in a way that reduces the condition complexity your business rules need to handle.
On the security side, remember that business rules control the form experience but not data access. If you need to genuinely prevent users from seeing or writing certain field values — not just hide them on a form — you need column-level security profiles, covered in Column-Level Security and Record Sharing in Dataverse. And if your rules are becoming complex enough that you're managing multiple table interactions, revisit your data model design using the patterns in Designing a Dataverse Data Model: Relationships, Lookups, and Choice Columns — sometimes the right fix is structural, not more rules.