PowerApps 中的 ForAll 函数ForAll function in PowerApps

针对中的所有记录计算值和执行操作。Calculates values and performs actions for all records of a table.

说明Description

ForAll 函数针对表中的所有记录对公式求值。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

公式可以包含用于执行操作的函数,例如使用 PatchCollect 函数修改数据源的记录。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. 无法修改作为 ForAll 函数的使用者的表。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. 因此,你不能在 ForAll 函数内使用使用 UpdateContextClearClearCollect 函数,因为它们很容易用来存放易受此效果影响的变量。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. 你可以使用 Collect,但添加记录的顺序是不确定的。You can use Collect, but the order in which records are added is undefined.

多个可修改数据源的函数(包括 CollectRemoveUpdate)会将更改后的数据源作为其返回值来返回。Several functions that modify data sources, including Collect, Remove, and Update, return the changed data source as their return value. 如果针对 ForAll 表的每条记录进行返回,则这些返回值可能很大并占用大量资源。These return values can be large and consume significant resources if returned for every record of the ForAll table. 你还可能会发现这些返回值不是你想要的,因为 ForAll 可以并行操作并且可能会将这些函数的副作用与获取其结果分离开来。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. 幸运的是,如果来自 ForAll 的返回值实际上未使用(对于数据修改函数这是常见情况),则不会创建返回值,因此不需要考虑资源或排序。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. 但是,如果你使用 ForAll 的结果并且使用了返回数据源的函数之一,请仔细考虑如何安排结果的结构并首先针对小型数据集进行测试。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

PowerApps 中的许多函数可以通过使用单列表一次处理多个值。Many functions in PowerApps can process more than one value at a time through the use of a single-column table. 例如,Len 函数可以采用与 ForAll 相同的方式处理包含文本值的表,返回包含长度的表。For example, the Len function can process a table of text values, returning a table of lengths, in the same manner that ForAll could. 这样,在很多情况下将不需要使用 ForAll,因此可以更高效并且更容易阅读。This can eliminate the need to use ForAll in many cases, can be more efficient, and is easier to read.

另一个需要注意的事项是 ForAll 不可委派,而诸如 Filter 之类的其他函数则可以。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 )ForAll( Table, Formula )

  • Table - 必需。Table - Required. 要对其执行操作的表。Table to be acted upon.
  • Formula - 必需。Formula - Required. 用于对 Table 中的所有记录进行求值的公式。The formula to evaluate for all records of the Table.

示例Examples

计算Calculations

以下示例使用 Squares 数据源The following examples use the Squares data source:

若要将此数据源创建为集合,请将某个按钮控件的 OnSelect 属性设置为以下公式,打开“预览”模式,然后单击或点击按该钮: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" ] )ClearCollect( Squares, [ "1", "4", "9" ] )
公式Formula 说明Description 结果Result
ForAll( Squares, Sqrt( Value ) )ForAll( Squares, Sqrt( Value ) )

Sqrt( Squares )Sqrt( Squares )
针对输入表中的所有记录计算 Value 列的平方根。For all the records of the input table, calculates the square root of the Value column. Sqrt 函数还可以与单列表一起使用,从而可以在不使用 ForAll 的情况下执行此示例。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 ) )ForAll( Squares, Power( Value, 3 ) ) 针对输入表中的所有记录计算 Value 列的三次幂。For all the records of the input table, raises the Value column to the third power. Power 函数不支持单列表。The Power function does not support single-column tables. 因此,在本例中必须使用 ForAllTherefore, ForAll must be used in this case.

使用连接Using a connection

以下示例使用 Expressions 数据源The following examples use the Expressions data source:

若要将此数据源创建为集合,请将某个按钮控件的 OnSelect 属性设置为以下公式,打开“预览”模式,然后单击或点击按该钮: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" ] )ClearCollect( Expressions, [ "Hello", "Good morning", "Thank you", "Goodbye" ] )

此示例还使用一个 Microsoft Translator 连接。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" ) )ForAll( Expressions, MicrosoftTranslator.Translate( Value, "es" ) ) 针对 Expressions 表中的所有记录将 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" ) )ForAll( Expressions, MicrosoftTranslator.Translate( Value, "fr" ) ) 针对 Expressions 表中的所有记录将 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 提供了许多用于执行这些操作的函数,例如 FilterAddColumnsSortPowerApps provides a number of functions for doing this, such as Filter, AddColumns, and Sort. PowerApps 将每个表视为一个值,允许它在公式中流动和并可轻松使用。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 提供了 Collect 函数来复制数据。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.

以下示例使用 Products 数据源The following examples use the Products data source:

若要将此数据源创建为集合,请将某个按钮控件的 OnSelect 属性设置为以下公式,打开“预览”模式,然后单击或点击按该钮: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 } ) )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" )ShowColumns( AddColumns( Filter( Products, 'Quantity Requested' > 'Quantity Available' ), "Quantity To Order", 'Quantity Requested' - 'Quantity Available' ), "Product", "Quantity To Order" )

FilterAddColumns 函数分别会创建一个记录范围来使用每条记录的 'Quantity Requested''Quantity Available' 字段执行比较和减法操作。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.

在此示例中,Filter 函数可以委派。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. 同时,ShowColumnsAddColumns 无法委派,因此,需要订购的实际产品数量将是有限的。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.

按需 ForAllForAll on demand

另一种方法是使用 ForAll 函数来替换表整形函数: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' } ) )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.

ForAll 的任何部件都不可委派。No part of the ForAll is delegable. 只会对 Products 表的第一部分进行评估,如果此表非常大,这可能是一个问题。Only the first portion of the Products table will be evaluated, which could be a problem if this table is very large. 因为 Filter 在上一示例中是可委派的,因此它可能更适用于大型数据集。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. 在此示例中,订单是通过供应商的系统上的 NewOrder 表下达的。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, 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( NewOrder, ForAll( Products, If( 'Quantity Requested' > 'Quantity Available', { Product: Product, 'Quantity To Order': 'Quantity Requested' - 'Quantity Available' } ) ) )

ClearCollectCollect 无法委派。ClearCollect and Collect can't be delegated. 因此,可以通过此方式移动的数据量是有限的。As a result the amount of data that can be moved in this manner is limited.

ForAll 内的 CollectCollect within ForAll

最后,我们可以直接在 ForAll 内执行 CollectFinally, 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' } ) ) )Clear( ProductsToOrder ); ForAll( Products, If( 'Quantity Requested' > 'Quantity Available', Collect( NewOrder, { Product: Product, 'Quantity To Order': 'Quantity Requested' - 'Quantity Available' } ) ) )

同样,ForAll 函数此时无法委派。Again, the ForAll function can't be delegated at this time. 如果我们的 Products 表很大,则ForAll 将仅查找第一组记录,我们可能会错过一些需要订购的产品。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.

注意,我们未捕获 ForAll 的结果。Note that we are not capturing the result of the ForAll. 从其中调用的 Collect 函数将返回所有记录的 NewOrder 数据源,如果我们捕获结果,这可能会增加大量的数据。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.