备注

Microsoft Power Fx 是画布应用公式语言的新名称。 当我们从画布应用中提取语言,将其与其他 Microsoft Power Platform 产品集成并使其作为开放源代码提供时,这些文章还在撰写。 从 Microsoft Power Fx 概述开始,了解对此语言的介绍。

在 Microsoft Power Fx 中,您可以编写一个公式来访问 Microsoft Excel、SharePoint、SQL Server 和其他一些将数据存储在记录和表中的源中的信息。 若要最有效地处理此类数据,请查看这些结构的基本概念。

  • 记录包含有关个人、地点或事物的一个或多个类别的信息。 例如,记录可能包含单个客户的姓名、电子邮件地址和电话号码。 其他工具将记录称作“行”或“项”。
  • 表保存一个或多个记录,这些记录包含相同类别的信息。 例如,表可以包含 50 个客户的姓名、电子邮件地址和电话号码。

可以构建采用表名称作为参数的各种公式,就像 Excel 中的公式采用一个或多个单元格引用作为参数。 Power Fx 中的某些公式返回一个反映所指定的其他参数的表。 例如,可以创建以下公式:

  • 通过将某个表指定为 Patch 函数的多个参数之一,来更新该表中的记录
  • 通过将某个表指定为 AddColumnsDropColumnsRenameColumns 函数的参数,在该表中添加、删除和重命名列。 其中的任何函数都不会修改原始表。 函数根据指定的其他参数返回另一个表。

表中的元素

表的元素。

记录

每条记录包含个人、地点或事物的至少一个类别的信息。 上面的示例针对每种产品(巧克力面包)显示一条记录,针对每个类别的信息(价格现有数量订购量)显示一列。

在公式中,可以使用大括号在表的上下文外部引用记录本身。 例如,此记录 { Name: "Strawberries", Price: 7.99 } 不与表关联。 请注意,如该示例中的名称价格等字段名称未括在双引号中。

字段

字段是记录中的单个信息片段。 可在特定记录的列中将此类字段可视化为值。

就像控件一样,通过对记录使用小数点 . 运算符引用记录的字段。 例如,First(Products).Name 返回 Products 表中第一条记录的 Name 字段。

字段可以包含另一个记录或表,如 GroupBy 函数的示例中所示。 可以嵌套任意数量的记录和表级别。

列数

列引用表中一个或多个记录的同一字段。 在上面的示例中,每种产品包含一个价格字段,该价格在所有产品的同一列中。 上面的表从前到后显示四列:

  • 名字
  • 价格
  • 手头数量
  • 订购数量

列的名称反映该列中的字段。

列中的所有值具有相同的数据类型。 在上面的示例中,“现有数量”列始终包含一条记录的数字,而不能包含诸如“12 件”之类的字符串。 任何字段的值也可以保留空白

在其他工具中,列可能称为“字段”。

表由一条或多条记录组成,每条记录包含多个字段,字段包含记录中的一致名称。

数据源或集合中存储的任何表都有一个名称,可以使用该名称来引用该表,并将它传递给采用表作为参数的函数。 表也可以是函数或公式的结果。

在下面的示例中,可以通过将 Table 函数与在大括号中表示的一组记录结合使用,在公式中表示表:

Table( { Value: "Strawberry" }, { Value: "Vanilla" } )

还可以使用方括号定义单列表。 上述公式的同等编写方式为:

[ "Strawberry", "Vanilla" ]

表公式

在 Excel 和 Power Fx 中,可以使用公式以类似的方式来处理数字和文本字符串:

  • 在 Excel 的单元格 A1 中键入一个值(例如 42),然后在另一个单元格中键入公式(例如 A1 + 2)即可显示值 44
  • 在 Power Apps 中,将 Slider1Default 属性设置为 42,将标签的 Text 属性设置为 Slider1.Value + 2,即可显示值 44

在这两种情况下,如果更改参数的值(例如,更改单元格 A1 中的数字或 Slider1 的值),计算出的值将自动更改。

同样,可以使用公式来访问和处理表与记录中的数据。 在某些公式中可以使用表的名称作为参数,例如,Min(Catalog, Price) 显示 Catalog 表的 Price 列中的最小值。 其他公式提供整个表作为返回值,例如,RenameColumns(Catalog, "Price", "Cost") 返回 Catalog 表中的所有记录,但会将 Price 列的名称更改为 Cost

与使用数字时一样,涉及到表和记录的公式会在基础表或记录更改时自动重新计算。 如果 Catalog 表中产品的成本低于前一个最小值,Min 公式的返回值将自动更改以匹配该成本。

表函数和控件属性

考虑 Lower 函数。 如果变量 welcome 包含文本字符串 "Hello, World",公式 Lower( welcome ) 将返回 "hello, world"。 此函数在任何情况下都不会更改该变量中的值。 Lower 是一个纯函数,因为它只处理 input 并产生 output。 这就是它的全部作用;没有副作用。 Excel 中的所有函数以及 Power Fx 中的大多数函数都是纯函数,这些函数允许自动重新计算工作簿或应用。

Power Fx 提供一组以相同方式对表执行操作的函数。 这些函数将表作为输入,对整个数据表进行筛选、排序、转换、减小和汇总。 实际上,Lower 以及许多其他通常采用单个值的函数也可以采用单列表作为输入。

许多函数使用单列表作为输入。 如果整个表只有一列,您可以按名称指定列。 如果表有多个列,您可以使用 Table.Column 语法指定其中一个列。 例如,Products.Name 将返回仅有 Products 表中的 Name 值的单列表。

您可以使用 AddColumnsRenameColumnsShowColumnsDropColumns 函数根据需要对表进行彻底调整。 同样,这些函数仅更改其输出,而不更改源。

行为公式

其他函数专门设计用于修改数据,它们具有副作用。 由于这些函数不是纯函数,因此必须仔细构建它们,它们不能参与自动重新计算应用程序中的值。 只能在行为公式中使用这些函数。

记录范围

某些函数可针对表的所有记录单独计算一个公式。 可通过多种方式使用该公式的结果:

  • AddColumns - 公式提供添加的字段的值。
  • Average,Max,Min,Sum,StdevP,VarP - 公式提供要聚合的值。
  • Filter,Lookup - 公式确定是否应将记录包含在输出中。
  • Concat - 公式确定要连接在一起的字符串。
  • Distinct - 公式返回一个值,用于标识重复记录。
  • ForAll - Formula 可以返回任何值,但可能会有副作用。
  • Sort - Formula 提供对记录进行排序的值。
  • With - 公式可以返回任何值,但可能会有副作用。

在这些公式中,可以引用所要处理的记录的字段。 其中的每个函数创建一个“记录范围”,将在该范围中计算公式,记录的字段可用作顶级标识符。 您还可以从整个应用程序中引用控件属性和其他值。

例如,获取在全局变量中放置的产品表。

请求的表。

Set( 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 }
    )
)

若要确定其中任何产品的请求数是否大于可供数,可使用以下公式:

Filter( Products, 'Quantity Requested' > 'Quantity Available' )

Filter 的第一个参数是要处理的记录表,第二个参数是公式。 Filter 创建一个记录范围来评估此公式,其中每条记录的字段都可用,在本例中 为 ProductQuantity RequestedQuantity Available。 比较结果确定是否应在函数的结果中包含每条记录:

所需的表。

作为此示例的延伸,我们可以计算要订购的每种产品的数量:

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

此处,我们将在结果中添加一个计算列。 AddColumns 有自己的记录范围,用于计算已请求的内容与可用内容之间的差异。

添加列。

最后,我们可以缩减结果表,以便只显示所需的列:

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

仅订单。

请注意,在上面的公式中,有些位置使用了双引号 ("),有些位置使用了单引号 (')。 引用名称中包含空格的对象(例如字段或表)的值时,需要使用单引号。 不是引用对象的值而是讨论该对象时,需要使用双引号,尤其是该对象尚不存在的情况下(例如 AddColumns)。

消除歧义

使用记录作用域添加的字段名称将替代应用中来自其他位置的同一名称。 在此情况下,仍可以使用 @ 消除歧义运算符访问来自记录范围以外的值:

  • 若要访问来自嵌套记录作用域的值,请使用 @ 运算符,其中所操作的表名称使用该模式:
    表格[@FieldName]
  • 若要访问全局值,如数据源、集合和上下文变量,请使用模式 [@ObjectName](无需指派表)。

如果所操作的表是一个表达式,如 Filter(Table, ... ),则不能使用消除歧义运算符。 只有最里面的记录范围可以在不使用消除歧义运算符的情况下从此表表达式访问字段。

例如,假设有一个集合 X

X 值。

可以使用 ClearCollect( X, [1, 2] ) 创建此集合。

和另一个集合 Y

Y 值。

可以使用 ClearCollect( Y, ["A", "B"] ) 创建此集合。

此外,使用公式 UpdateContext( {Value: "!"} ) 定义名为 Value 的上下文变量

我们将这些公式组合在一起。 在此上下文中,以下公式:

Ungroup(
    ForAll( X,
        ForAll( Y,
            Y[@Value] & Text( X[@Value] ) & [@Value]
        )
    ),
    "Value"
)

生成此表:

XY 值。

公式中的每个组成部分有什么作用? 最外面的 ForAll 函数定义 X 的记录范围,以便访问它所处理的每条记录的 Value 字段。 只需使用单词 Value 或使用 X[@Value] 即可访问该字段。

最里面的 ForAll 函数定义 Y 的另一个记录范围。由于此表还包含定义的 Value 字段,因此此处使用了 Value 来引用 Y 记录中的字段,而不再引用 X 中的字段。此处,为了访问 XValue 值,我们必须结合消除歧义运算符使用更长的版本。

由于 Y 是最里面的记录范围,因此访问此表的字段不需要消除歧义,可以使用以下公式实现相同的结果:

Ungroup(
    ForAll( X,
        ForAll( Y,
            Value & Text( X[@Value] ) & [@Value]
        )
    ),
    "Value"
)

所有 ForAll 记录范围将替代全局范围。 在不使用消除歧义运算符的情况下,不可以按名称使用定义的 Value 上下文变量。 若要访问此值,请使用 [@Value]

Ungroup 将拼合结果,因为嵌套 的 ForAll 函数会导致嵌套的结果表。

单列表

要对表中的单个列进行操作,请使用 ShowColumns 函数,如以下示例所示:

ShowColumns( Products, "Product" )

此公式将生成此单列表:

单列。

要使用更简短的公式,请指定 Table.Column,这将提取仅有 Table 中的 Column 的单列表。 例如,此公式生成的结果与使用 ShowColumns 完全相同。

Products.Product

内联记录

可以使用包含命名字段值的大括号来表示记录。 例如,可以使用以下公式来表示本主题开头所示的表中的第一条记录:

{ Name: "Chocolate", Price: 3.95, 'Quantity on Hand': 12, 'Quantity on Order': 10 }

还可以在其他公式中嵌入公式,如下面的示例所示:

{ Name: First(Products).Name, Price: First(Products).Price * 1.095 }

可以通过嵌套大括号来嵌套记录,如以下示例所示:

{ 'Quantity': { 'OnHand': ThisItem.QuantOnHand, 'OnOrder': ThisItem.QuantOnOrder } }

将包含特殊字符(例如空格或冒号)的每个列名称括在单引号中。 若要在列名称中使用单引号,请双击该名称。

请注意,Price 列中的值不包含货币符号,如美元符号。 显示值时,将应用该格式。

内联表

可以使用 Table 函数和一组记录创建表。 可以使用以下公式来表示本主题开头所示的表:

Table( 
	{ Name: "Chocolate", Price: 3.95, 'Quantity on Hand': 12, 'Quantity on Order': 10 },
	{ Name: "Bread", Price: 4.95, 'Quantity on Hand': 34, 'Quantity on Order': 0 },
	{ Name: "Water", Price: 4.95, 'Quantity on Hand': 10, 'Quantity on Order': 0 } 
)

还可以嵌套表:

Table( 
	{ Name: "Chocolate", 
	  'Quantity History': Table( { Quarter: "Q1", OnHand: 10, OnOrder: 10 },
	                             { Quarter: "Q2", OnHand: 18, OnOrder: 0 } ) 
	}
)

内联值表

可以通过在方括号中指定值来创建单列表。 生成的表包含名为 Value 的单个列。

例如,[ 1, 2, 3, 4 ] 等效于 Table( { Value: 1 }, { Value: 2 }, { Value: 3 }, { Value: 4 } ),返回此表:

内联表。