
Picture this: You're managing a company's expense approval process. Every submitted expense report needs to follow different paths based on the amount, department, and approval status. Small expenses under $100 go straight to accounting. Larger ones need manager approval first. Expenses over $5,000 require both manager and director sign-off. Meanwhile, you need to track the total expenses processed each day and send different notifications to different people based on various criteria.
This scenario requires three fundamental programming concepts that Power Automate handles beautifully: conditions (making decisions), loops (repeating actions), and variables (storing and manipulating data). These aren't just technical concepts—they're the building blocks that transform simple automation into intelligent, responsive workflows that adapt to real business logic.
By the end of this lesson, you'll understand how to build flows that think, decide, and adapt automatically. You'll move beyond basic trigger-to-action flows and create sophisticated automation that handles complex business scenarios with ease.
What you'll learn:
Before diving into conditions and loops, let's understand variables—the foundation that makes intelligent flows possible. Think of variables as your flow's short-term memory. Just like you might jot down notes while working through a complex task, variables let your flow remember information and use it later.
Power Automate offers several variable types, each designed for specific kinds of data:
String variables store text data like names, descriptions, or status messages. Integer variables hold whole numbers for counting, calculations, or thresholds. Float variables handle decimal numbers for precise calculations like monetary amounts or percentages. Boolean variables store true/false values perfect for tracking states or flags. Array variables contain lists of items, ideal for collecting multiple values. Object variables store complex data structures with multiple properties.
Let's create a practical example using an expense processing scenario. Start by creating a new flow with a manual trigger. Add the "Initialize variable" action and configure it:
Variable name: TotalExpenses
Type: Float
Value: 0
Add another variable:
Variable name: ProcessedCount
Type: Integer
Value: 0
And one more:
Variable name: RequiresApproval
Type: Boolean
Value: false
These variables will track our running totals and processing state throughout the flow execution. The beauty of variables becomes apparent when you start updating them based on conditions and using them to drive decisions later in your flow.
To update a variable, use the "Set variable" action for complete replacement or "Increment variable" for numeric additions. The key insight is that variables maintain their values throughout the entire flow execution, allowing different parts of your flow to communicate with each other.
Conditions transform linear flows into intelligent decision-makers. Every condition evaluates to true or false, creating two possible paths your flow can take. This binary choice is the foundation of all business logic automation.
Power Automate's condition action presents a clean interface: choose a value, select an operator, and specify what to compare against. But the real power lies in understanding when to use different comparison types and how to structure complex decision trees.
Let's build a realistic expense approval condition. Add a "Condition" action to your flow and configure it:
Left side: Dynamic content or manual value (expense amount)
Operator: is greater than
Right side: 100
In the "Yes" branch, add actions for manager approval workflow. In the "No" branch, add actions for automatic processing. But real business logic is rarely this simple. You'll often need nested conditions to handle multiple criteria.
Inside the "Yes" branch, add another condition:
Left side: Dynamic content (expense amount)
Operator: is greater than
Right side: 5000
This creates a decision tree: expenses under $100 get automatic approval, expenses between $100-$5000 need manager approval, and expenses over $5000 need both manager and director approval.
Advanced conditions become powerful when you use expressions and multiple criteria. Click "Edit in advanced mode" to write complex logic:
@and(greater(float(triggerBody()?['amount']), 100), equals(triggerBody()?['department'], 'Marketing'))
This condition checks if the expense is both over $100 AND from the Marketing department. The @and() function requires all conditions to be true, while @or() requires only one condition to be true.
Pro tip: Use parentheses liberally in complex expressions to ensure proper evaluation order. Power Automate evaluates expressions left to right, but parentheses override this behavior.
String comparisons offer several operators beyond simple equality. "Contains" checks if one string appears within another, perfect for checking if an email subject contains specific keywords. "Starts with" and "ends with" are ideal for file naming conventions or email routing based on addresses.
For arrays and objects, conditions become even more sophisticated. You can check if an array contains specific values, if an object has particular properties, or compare lengths and counts. This flexibility allows conditions to handle virtually any business scenario you encounter.
Loops solve a fundamental problem in automation: efficiently processing multiple items without creating dozens of identical actions. Power Automate provides several loop types, each optimized for different scenarios.
The "Apply to each" loop is your workhorse for processing arrays of data. It takes a collection—like rows from a spreadsheet, items from a SharePoint list, or files in a folder—and executes the same set of actions on each item automatically.
Let's create a practical example processing multiple expense reports. Imagine you receive a daily email with an Excel attachment containing all submitted expenses. Here's how to process each row:
First, add the "List rows present in a table" action to get data from your Excel file. This returns an array of objects, each representing one expense report.
Next, add "Apply to each" and select the dynamic content from your Excel action. Inside the loop, you can access properties of the current item using expressions like:
Current item: items('Apply_to_each')?['ExpenseAmount']
Current item: items('Apply_to_each')?['Department']
Current item: items('Apply_to_each')?['SubmitterEmail']
Within the loop, add your business logic. For each expense, you might:
@add(variables('TotalExpenses'), float(items('Apply_to_each')?['ExpenseAmount']))The "Do until" loop continues executing until a specific condition becomes true. This is perfect for scenarios where you don't know in advance how many iterations you'll need. For example, polling an API until data becomes available or processing items from a queue until it's empty.
Configure a "Do until" loop like this:
Condition: Length of array
Operator: is equal to
Value: 0
Inside the loop, add actions that gradually work toward the exit condition. Always include a safeguard to prevent infinite loops—Power Automate has built-in limits, but it's good practice to design your own exit strategies.
Warning: "Do until" loops can consume significant processing time if not designed carefully. Always ensure your loop actions move closer to the exit condition with each iteration.
For simple counting scenarios, consider using the "Apply to each" loop with a range. Create an array of numbers using the range() function:
Expression: range(1, 10)
This creates an array [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], perfect for loops that need to execute a specific number of times.
Loops become particularly powerful when combined with variables. Use variables to accumulate data, track progress, or maintain state across iterations. For instance, you might collect all expense reports requiring manager approval into an array variable, then process that array in a separate loop.
The real magic happens when you combine conditions, loops, and variables into sophisticated workflows. Let's build a comprehensive expense processing system that demonstrates these concepts working together.
Our scenario: Process a daily batch of expense reports, categorize them by approval requirements, calculate departmental totals, and send appropriate notifications to various stakeholders.
Start by initializing several variables:
TotalExpenses (Float): 0
ManagerApprovalRequired (Array): []
DirectorApprovalRequired (Array): []
AutoApproved (Array): []
DepartmentTotals (Object): {}
The object variable will store department totals as key-value pairs, where each department name is a key pointing to its total expenses.
Next, create your main processing loop using "Apply to each" on your expense data. Inside this loop, implement layered conditions:
First condition: Check expense amount
If expense amount > 5000:
- Add to DirectorApprovalRequired array
- Set RequiresApproval to true
Else if expense amount > 100:
- Add to ManagerApprovalRequired array
- Set RequiresApproval to true
Else:
- Add to AutoApproved array
Within each branch, update your running totals. Add the expense amount to TotalExpenses and update the department-specific total in your DepartmentTotals object.
Updating object variables requires careful use of expressions:
@setProperty(variables('DepartmentTotals'), items('Apply_to_each')?['Department'], add(coalesce(variables('DepartmentTotals')?[items('Apply_to_each')?['Department']], 0), float(items('Apply_to_each')?['Amount'])))
This expression checks if the department already exists in your object, adds the new expense amount to the existing total (or starts at 0), and updates the object.
After processing all expenses, use additional loops to handle the categorized arrays. Create separate "Apply to each" loops for each approval category:
For ManagerApprovalRequired array:
For DirectorApprovalRequired array:
For AutoApproved array:
Use conditions within these loops to customize processing based on additional criteria like department, expense type, or submitter role.
Finally, create summary reporting using your accumulated variables. Send different reports to different audiences:
Let's build a complete invoice processing workflow that combines all three concepts. This exercise will process a list of invoices, categorize them by priority, calculate totals, and route them appropriately.
Scenario: Your company receives invoices that need processing based on amount, vendor type, and urgency. Small invoices (under $500) from preferred vendors get fast-tracked. Large invoices (over $10,000) require additional approvals. You need to track totals by vendor type and send different notifications.
Step 1: Set up your flow Create a new instant flow triggered manually. In a real scenario, this might be triggered by receiving an email or updating a SharePoint list.
Step 2: Initialize variables Add these variables:
TotalInvoices (Float): 0
FastTrackCount (Integer): 0
StandardCount (Integer): 0
HighValueCount (Integer): 0
VendorTotals (Object): {}
ProcessingSummary (Array): []
Step 3: Create sample data Add a "Compose" action to simulate invoice data:
[
{"vendor": "TechCorp", "amount": 750, "type": "preferred", "urgency": "normal"},
{"vendor": "Office Supplies Inc", "amount": 250, "type": "standard", "urgency": "urgent"},
{"vendor": "Consulting Group", "amount": 15000, "type": "preferred", "urgency": "normal"},
{"vendor": "Equipment Rentals", "amount": 1200, "type": "standard", "urgency": "normal"}
]
Step 4: Process each invoice Add "Apply to each" using the output from your Compose action. Inside the loop:
Add a condition checking if amount < 500 AND type equals "preferred":
In each branch, update TotalInvoices and VendorTotals using the expressions we discussed earlier.
Step 5: Generate reports After the main loop, create summary conditions:
Step 6: Test and refine Run your flow and examine the outputs. Check that variables update correctly and conditions route invoices appropriately.
This exercise demonstrates real-world complexity: multiple decision points, data accumulation, and varied output paths based on business rules.
Variable scope confusion is the most frequent issue newcomers encounter. Variables initialized within loops or condition branches are only available within that scope. Always initialize variables at the flow level if you need them throughout the entire flow. If your flow can't find a variable, check where it was created versus where you're trying to use it.
Infinite loops can occur with "Do until" conditions that never become true. Always trace through your loop logic manually: does each iteration move closer to your exit condition? Include counter variables as safeguards, incrementing them each iteration and adding secondary exit conditions when counters reach maximum values.
Data type mismatches cause mysterious failures, especially in conditions. Power Automate is flexible with type conversion, but explicit is better than implicit. Use functions like string(), int(), and float() to ensure consistent data types. When comparing dynamic content to static values, make sure the types match.
Complex condition logic can become unreadable quickly. Break complex conditions into smaller, named variables. Instead of one massive expression, create intermediate Boolean variables with descriptive names. This makes debugging much easier and improves flow readability.
Array and object manipulation often trips up new users. Remember that arrays are zero-indexed, and accessing non-existent indices returns null. Use length() function to check array sizes before accessing elements. For objects, use coalesce() to provide default values when properties might not exist.
Performance issues typically stem from unnecessary loops or inefficient conditions. Review your logic: can you filter data before processing rather than checking conditions inside loops? Can you combine similar operations? Power Automate has execution limits, so efficient design matters for complex flows.
Dynamic content disappearing happens when you reference content from actions that might not execute. If a dynamic content option becomes unavailable, it's usually because it's inside a condition branch or loop that might not run. Consider restructuring your flow or using variables to store values you'll need later.
Debugging tip: Use "Compose" actions as debugging checkpoints. Add Compose actions that output variable values at key points in your flow. This makes troubleshooting much easier when flows don't behave as expected.
Expression syntax errors are common when building complex formulas. Power Automate's expression editor provides some syntax checking, but not comprehensive validation. Test complex expressions in simple Compose actions before using them in critical logic. Common issues include mismatched parentheses, incorrect function names, and improper quoting of string literals.
You've now mastered the three fundamental building blocks of intelligent automation: variables for memory, conditions for decision-making, and loops for efficient repetition. These concepts transform Power Automate from a simple connector tool into a sophisticated business logic engine capable of handling complex, real-world scenarios.
Variables give your flows memory, allowing them to accumulate data, track progress, and maintain state across multiple actions. You've learned when to use different variable types and how to update them throughout flow execution.
Conditions enable intelligent decision-making, letting your flows adapt their behavior based on data, user input, or external factors. You can now build complex decision trees that mirror your organization's business rules and approval processes.
Loops eliminate repetitive manual work by automating the processing of multiple items, whether that's rows in a spreadsheet, files in a folder, or items in a list. You understand when to use "Apply to each" versus "Do until" and how to design efficient loop structures.
Most importantly, you've seen how combining these three concepts creates powerful automation that can handle sophisticated business scenarios. The expense processing and invoice routing examples demonstrate patterns you can adapt to countless real-world situations.
Your next steps should focus on applying these concepts to actual business challenges in your organization. Look for processes that involve decision-making, data processing, or repetitive tasks that vary based on certain criteria. These are perfect candidates for the techniques you've learned.
Consider exploring Power Automate's connector ecosystem to see how these fundamental concepts apply when working with specific applications like SharePoint, Excel, Outlook, or your organization's custom systems. The logic patterns remain the same, but each connector adds unique capabilities and considerations.
Advanced topics to explore include error handling within loops and conditions, parallel processing for improved performance, and integration with Power Apps for user-driven decision flows. You might also investigate custom connectors and Azure Logic Apps for even more sophisticated automation scenarios.
Remember that great automation isn't just about technical capability—it's about understanding business processes deeply enough to encode them in logical, maintainable flows. Keep practicing with real scenarios, and don't hesitate to start simple and iterate toward complexity.
Learning Path: Flow Automation Basics