Calculates values and performs actions for all records of a table.

## Description

The **ForAll** function evaluates a formula for all records of a table. The formula can calculate a value and/or perform actions, such as modifying data or working with a connection.

Fields of the record currently being processed are available within the formula. You simply reference them by name as you would any other value. You can also reference control properties and other values from throughout your app. For more details, see the examples below and working with record scope.

### Return value

The result of each formula evaluation is returned in a table, in the same order as the input table.

If the result of the formula is a single value, the resulting table will be a single column table. If the result of the formula is a record, the resulting table will contain records with the same columns as the result record.

If the result of the formula is a *blank* value, then there will be no record in the result table for that input record. In this case, there will be fewer records in the result table than the source table.

### Taking action

The formula can include functions that take action, such as modifying the records of a data source with the **Patch** and **Collect** functions. The formula can also call methods on connections. Multiple actions can be performed per record by using the **;** operator. You can't modify the table that is the subject of the **ForAll** function.

When writing your formula, keep in mind that records can be processed in any order and, when possible, in parallel. The first record of the table may be processed after the last record. Take care to avoid ordering dependencies. For this reason, you can't use the **UpdateContext**, **Clear**, and **ClearCollect** functions within a **ForAll** function because they could easily be used to hold variables that would be susceptible to this effect. You can use **Collect**, but the order in which records are added is undefined.

Several functions that modify data sources, including **Collect**, **Remove**, and **Update**, return the changed data source as their return value. These return values can be large and consume significant resources if returned for every record of the **ForAll** table. You may also find that these return values are not what you expect, because **ForAll** can operate in parallel and may separate the side effects of these functions from obtaining their result. Fortunately, if the return value from **ForAll** is not actually used, which is often the case with data modification functions, then the return value will not be created and there are no resource or ordering concerns. But if you are using the result of a **ForAll** and one of the functions that returns a data source, think carefully about how you structure the result and try it out first on small data sets.

### Alternatives

Many functions in PowerApps can process more than one value at a time through the use of a single-column table. For example, the **Len** function can process a table of text values, returning a table of lengths, in the same manner that **ForAll** could. This can eliminate the need to use **ForAll** in many cases, can be more efficient, and is easier to read.

Another consideration is that **ForAll** is not delegable while other functions may be, such as **Filter**.

### Delegation

When used with a data source, this function can't be delegated. Only the first portion of the data source will be retrieved and then the function applied. The result may not represent the complete story. A blue dot will appear at authoring time to remind you of this limitation and to suggest switching to delegable alternatives where possible. For more information, see the delegation overview.

## Syntax

**ForAll**( *Table*, *Formula* )

*Table*- Required. Table to be acted upon.*Formula*- Required. The formula to evaluate for all records of the*Table*.

## Examples

### Calculations

The following examples use the **Squares** data source:

To create this data source as a collection, set the **OnSelect** property of a **Button** control to this formula, open Preview mode, and then click or tap the button:

**ClearCollect( Squares, [ "1", "4", "9" ] )**

Formula | Description | Result |

ForAll( Squares, Sqrt( Value ) )Sqrt( Squares ) | For all the records of the input table, calculates the square root of the Value column. The Sqrt function can also be used with a single-column table, making it possible perform this example without using ForAll. | |

ForAll( Squares, Power( Value, 3 ) ) | For all the records of the input table, raises the Value column to the third power. The Power function does not support single-column tables. Therefore, ForAll must be used in this case. |

### Using a connection

The following examples use the **Expressions** data source:

To create this data source as a collection, set the **OnSelect** property of a **Button** control to this formula, open Preview mode, and then click or tap the button:

**ClearCollect( Expressions, [ "Hello", "Good morning", "Thank you", "Goodbye" ] )**

This example also uses a Microsoft Translator connection. To add this connection to your app, see the topic about how to manage connections.

Formula | Description | Result |

ForAll( Expressions, MicrosoftTranslator.Translate( Value, "es" ) ) | For all the records in the Expressions table, translate the contents of the Value column into Spanish (abbreviated "es"). | |

ForAll( Expressions, MicrosoftTranslator.Translate( Value, "fr" ) ) | For all the records in the Expressions table, translate the contents of the Value column into French (abbreviated "fr"). |

### Copying a table

Sometimes you need to filter, shape, sort, and manipulate data. PowerApps provides a number of functions for doing this, such as **Filter**, **AddColumns**, and **Sort**. PowerApps treats each table as a value, allowing it to flow through formulas and be consumed easily.

And sometime you will want to make a copy of this result for later use. Or you will want to move information from one data source to another. PowerApps provides the **Collect** function to copy data.

But before you make that copy, think carefully if it is really needed. Many situations can be addressed by filtering and shaping the underlying data source on demand with a formula. Some of the downsides to making a copy include:

- Two copies of the same information means that one of them can fall out of sync.
- Making a copy can consume a lot of computer memory, network bandwidth, and/or time.
- For most data sources, copying cannot be delegated, limiting how much data can be moved.

The following examples use the **Products** data source:

To create this data source as a collection, set the **OnSelect** property of a **Button** control to this formula, open Preview mode, and then click or tap the button:

**ClearCollect( Products, Table( { Product: "Widget", 'Quantity Requested': 6, 'Quantity Available': 3 }, { Product: "Gadget", 'Quantity Requested': 10, 'Quantity Available': 20 }, { Product: "Gizmo", 'Quantity Requested': 4, 'Quantity Available': 11 }, { Product: "Apparatus", 'Quantity Requested': 7, 'Quantity Available': 6 } ) )**

Our goal is to work with a derivative table that includes only the items where more has been requested than is available, and for which we need to place an order:

We can perform this task in a couple of different ways, all of which produce the same result, with various pros and cons.

#### Table shaping on demand

Don't make that copy! We can use the following formula anywhere we need:

**ShowColumns( AddColumns( Filter( Products, 'Quantity Requested' > 'Quantity Available' ), "Quantity To Order", 'Quantity Requested' - 'Quantity Available' ), "Product", "Quantity To Order" )**

A record scope is created by the **Filter** and **AddColumns** functions to perform the comparison and subtraction operations, respectively, with the **'Quantity Requested'** and **'Quantity Available'** fields of each record.

In this example, the **Filter** function can be delegated. This is important, as it can find all the products that meet the criteria, even if that is only a few records out of a table of millions. At this time, **ShowColumns** and **AddColumns** cannot be delegated, so the actual number of products that needs to be ordered will be limited. If you know the size of this result will always be relatively small, this approach is fine.

And because we didn't make a copy, there is no additional copy of the information to manage or fall out of date.

#### ForAll on demand

Another approach is to use the **ForAll** function to replace the table-shaping functions:

**ForAll( Products, If( 'Quantity Requested' > 'Quantity Available', { Product: Product, 'Quantity To Order': 'Quantity Requested' - 'Quantity Available' } ) )**

This formula may be simpler for some people to read and write.

No part of the **ForAll** is delegable. Only the first portion of the **Products** table will be evaluated, which could be a problem if this table is very large. Because **Filter** could be delegated in the previous example, it could work better with large data sets.

#### Collect the result

In some situations, a copy of data may be required. You may need to move information from one data source to another. In this example, orders are placed through a **NewOrder** table on a vendor's system. For high-speed user interactions, you may want to cache a local copy of a table so that there is no server latency.

We use the same table shaping as the previous two examples, but we capture the result into a collection:

**ClearCollect( NewOrder, ShowColumns( AddColumns( Filter( Products, 'Quantity Requested' > 'Quantity Available' ), "Quantity To Order", 'Quantity Requested' - 'Quantity Available' ), "Product", "Quantity To Order" ) )****ClearCollect( NewOrder, ForAll( Products, If( 'Quantity Requested' > 'Quantity Available', { Product: Product, 'Quantity To Order': 'Quantity Requested' - 'Quantity Available' } ) ) )**

**ClearCollect** and **Collect** can't be delegated. As a result the amount of data that can be moved in this manner is limited.

#### Collect within ForAll

Finally, we can perform the **Collect** directly within the **ForAll**:

**Clear( ProductsToOrder ); ForAll( Products, If( 'Quantity Requested' > 'Quantity Available', Collect( NewOrder, { Product: Product, 'Quantity To Order': 'Quantity Requested' - 'Quantity Available' } ) ) )**

Again, the **ForAll** function can't be delegated at this time. If our **Products** table is large, **ForAll** will look at the first set of records only and we may miss some products that need to be ordered. But for tables that we know will remain small, this approach is fine.

Note that we are not capturing the result of the **ForAll**. The **Collect** function calls made from within it will return the **NewOrder** data source for all the records, which could add up to a lot of data if we were capturing it.