了解画布应用中的记录引用和多态查找
当您在学校撰写研究论文时,您可能在最后提供了一份参考文献清单。 您没有提供您所使用的实际背景材料的副本,而是提供了一个 Web 链接、书名和作者或其他信息,让他人可以找到原始来源。 您将不同种类的来源混合在一个列表中,在录音旁边配上新闻文章,每一条都分别配上了正当引用的特定详细信息。 例如,维基百科文章通常包含一个很长的参考文献列表。
在画布应用中,您会经常使用从数据源下载的记录的副本。 您使用 LookUp 和 Filter 函数,以及 库 控件的 Selected 属性,来标识所需的特定记录。 Filter 或 Selected 中的所有记录都将具有相同的表类型,因此您可以使用带有简单 .Field 表示法的字段。 这些副本通常包含引用信息,因此您可以使用 Patch 函数来更新原始源。
画布应用还支持记录引用。 与研究论文引用非常相似,记录引用是引用一条记录,不包括记录的完整副本。 此类引用可以引用任何表中的记录。 同时与研究论文引用一样,您可以将来自不同表的记录混合在一个列中。
针对记录引用的许多操作与使用记录相同。 您可以相互比较记录引用,也可以将其与完整记录进行比较。 您可以使用 Patch 函数设置记录引用的值,就像处理具有完整记录的查找那样。
有一个重要的使用差别:不先建立它所引用的表,您不能直接访问记录引用的字段。 这是因为画布应用需要在编写公式时知道所有类型。 由于在应用运行之前您不知道记录引用的类型,因此您无法直接使用简单的 .Field 表示法。 您必须首先使用 IsType 函数动态确定表类型,然后在 AsType 函数的结果上使用 .Field 表示法。
表类型是指表中每个记录的架构。 每个表有一组具有不同名称和数据类型的唯一字段。 表的每个记录继承这一结构;如果两个记录来自同一个表,它们将具有相同的表类型。
备注
您可以从许多不同的连接器中选择连接器来连接到画布应用的不同类型的数据源。 但是,在 Power Apps Studio 中使用画布应用时,Microsoft Dataverse 中的列被称为字段,类似于所有其他数据源。 列仅在提到 Dataverse 中的列时使用。 详细信息:Dataverse 术语更新
多态查找
Microsoft Dataverse 支持记录之间的关系。 客户表中的每个记录都有一个对应联系人表中的记录的主要联系人查找列。 查找只能引用联系人中的记录,不能引用团队表(举例)中的记录。 最后一个详细信息很重要,因为您始终知道哪些列可用于查找。
Dataverse 还支持多态查找,它可以引用集中任何表中的记录。 例如,负责人列可以引用用户表或团队表中的记录。 不同记录中的相同查找列可以引用不同表中的记录。 在这种情况下,您并不总是知道哪些列可用。
画布记录引用设计用于处理 Dataverse 中的多态查找。 您还可以在此上下文之外使用记录引用,这是两个概念的不同之处。
在下一节中,您将通过使用负责人查找来开始探索这些概念。
显示记录负责人的列
Dataverse 中的每个表都包含一个负责人列。 此列无法删除,您也无法添加其他列,它始终需要有值。
在客户表中显示此列:
登录到 Power Apps。
在左侧窗格栏中,选择数据 > 表。
在表列表中,选择客户。
在右上角,打开筛选器列表(默认情况下设置为默认),然后选择所有。
向下滚动,直到出现负责人列。
此查找列可以引用团队表或用户表中的记录。 并非这些表中的每个记录都有权成为负责人;如果遇到问题,请检查支持的角色。
此图显示了一个简单的客户库,其中客户表已作为数据源添加到应用中:
重要
在此主题通篇,各个图中都显示了一些名称和另外一些值,这些名称和值不属于 Dataverse 附带的示例数据。 这些步骤准确演示了如何为特定结果配置控件,但是您的体验会根据组织的数据而有所不同。
要显示库中每个客户的负责人,您可能会想要使用公式 ThisItem.Owner.Name。 但是,团队表中的名称字段是团队名称,而用户表中的名称字段是全名。 在您运行应用之前,应用无法知道您在使用哪种类型的查找,它可能随客户表中的记录变化。
您需要一个可以适应这种差异的公式。 您还需要为负责人可能属于的表类型(在本例中为用户和团队)添加数据源。 将这三个数据源添加到您的应用中:
有了这些数据源后,请使用以下公式显示用户或团队的名称:
If( IsType( ThisItem.Owner, Teams ),
"Team: " & AsType( ThisItem.Owner, Teams ).'Team Name',
"User: " & AsType( ThisItem.Owner, Users ).'Full Name' )
在此公式中,IsType 函数对团队表测试负责人字段。 如果是该表类型,AsType 函数会将其转换为团队记录。 此时,您可以使用 .Field 表示法访问团队表的所有字段,包括团队名称。 如果 IsType 确定负责人不是团队表中的记录,该字段必须是用户表中的记录,因为负责人字段为必填项(不能为空白)。
要使用记录引用的任何字段,您必须首先使用 AsType 函数将其转换为特定的表类型。 您无法直接从负责人字段访问字段,因为系统不知道您要使用哪种表类型。
如果负责人字段与请求的表类型不匹配,AsType 函数将返回错误,因此您可以使用 IfError 函数来简化此公式。 首先,打开试验功能公式级错误管理:
然后用以下公式替换之前的公式:
IfError(
"Team: " & AsType( ThisItem.Owner, Teams ).'Team Name',
"User: " & AsType( ThisItem.Owner, Users ).'Full Name' )
基于负责人筛选
恭喜,您已经完成了使用记录引用最困难的工作。 其他用例更为直接,因为它们不访问记录的字段。 例如,筛选,您将在本节中进行探索。
在库上方添加一个 组合框 控件,并设置新控件的以下属性:
- Items:
Users
- SelectMultiple:
false
要按从此组合框中选择的特定用户筛选库,请将库的 Items 属性设置为以下公式:
Filter( Accounts, Owner = ComboBox1.Selected )
重要
如果完全按照这些步骤操作,本主题中的说明是准确的。 但是,如果控件具有不同名称,任何以其名称引用控件的公式都将失败。 如果删除并添加相同类型的控件,控件名称末尾的数字会更改。 对于任何显示错误的公式,请确认它包含所有控件的正确名称。
您不需要使用 IsType 或 AsType,因为您在将记录引用与其他记录引用或完整记录进行比较。 应用知道 ComboBox1.Selected 的表类型,因为它派生自用户表。 负责人是团队的客户不会与筛选条件匹配。
您可能会更愿意支持按用户或团队进行筛选。
通过调整库的大小并移动组合框,在屏幕顶部附近留出一些空间,在库上方插入一个 单选 控件,然后为新控件设置这些属性:
- Items:
[ "All", "Users", "Teams" ]
- Layout:
Layout.Horizontal
- Items:
对于 组合框 控件,请设置此属性(如果组合框消失,请在单选按钮控件中选择 Users):
- Visible:
Radio1.Selected.Value = "Users"
- Visible:
复制并粘贴 组合框 控件,将副本直接移到原始副本上,然后为副本设置以下属性:
- Items:
Teams
- Visible:
Radio1.Selected.Value = "Teams"
应用一次将仅显示一个组合框,具体取决于单选按钮控件的状态。 由于它们直接位于彼此的上方,因此它们看起来就像是更改自己内容的同一个控件。
- Items:
最后,将 库 控件的 Items 属性设置为以下公式:
Filter( Accounts, Radio1.Selected.Value = "All" Or (Radio1.Selected.Value = "Users" And Owner = ComboBox1.Selected) Or (Radio1.Selected.Value = "Teams" And Owner = ComboBox1_1.Selected) )
通过这些更改,您可以显示所有记录或基于用户或对其进行筛选:
此公式完全可委派。 比较单选按钮值的部分是所有记录中的常数,它在筛选器的其余部分被发送到 Dataverse 之前计算。
如果您想要对负责人的类型进行筛选,可以使用 IsType 函数,但是它尚不可委派。
使用 Patch 更新负责人
您可以采用与其他任何查找相同的方式更新负责人字段。 要将当前所选客户的负责人设置为第一个团队,请执行以下操作:
Patch( Accounts, Gallery1.Selected, { Owner: First( Teams ) } )
此方法与常规查找没有区别,因为应用知道 First( Teams ) 的类型。 如果您想要使用第一个用户,请将该部分替换为 First( Users )。 Patch 函数知道负责人字段可以设置为这两种表类型中的任何一种。
若要向应用添加此功能,请执行以下操作:
在树视图窗格中,同时选择 单选 控件和两个 组合框 控件。
在省略号菜单上,选择复制这些项。
在同一个菜单上,选择粘贴。
将复制的控件移到库的右侧。
选择复制的 单选 控件,然后更改以下属性:
- Items:
[ "Users", "Teams" ]
- 默认:
If( IsType( Gallery1.Selected.Owner, Users ), "Users", "Teams" )
- Items:
在 单选 控件中,选择 Users,让列出用户的 组合框 控件可见。
选择可见的 组合框 控件,然后将 DefaultSelectedItems 属性设置为以下公式:
If( IsType( Gallery1.Selected.Owner, Users ), AsType( Gallery1.Selected.Owner, Users ), Blank() )
在 单选 控件中,选择 Teams,让列出团队的 组合框 控件可见。
选择 单选 控件,将所作选择从用户现在不可见的 组合框 控件中移走。
选择团队的可见 组合框 控件,然后将其 DefaultSelectedItems 属性设置为以下公式:
If( IsType( Gallery1.Selected.Owner, Teams ), AsType( Gallery1.Selected.Owner, Teams ), Blank() )
插入一个 按钮 控件,将其移至 组合框 控件下,然后将按钮的 Text 属性设置为
"Patch Owner"
。将按钮的 OnSelect 属性设置为此公式:
Patch( Accounts, Gallery1.Selected, { Owner: If( Radio1_1.Selected.Value = "Users", ComboBox1_2.Selected, ComboBox1_3.Selected ) } )
复制的 单选 和 组合框 控件显示库中当前所选客户的负责人。 使用相同的控件,您可以通过选择按钮将客户的负责人设置为任何团队或用户:
使用窗体显示负责人
您可以通过添加自定义卡在窗体内显示负责人字段。 截至本文撰写时,您无法使用窗体控件更改字段的值。
插入 编辑窗体 控件,然后调整大小并将其移动到右下角。
在屏幕右侧附近的属性选项卡上,打开数据源列表,然后选择客户。
将窗体的 Item 属性设置为
Gallery1.Selected
。在屏幕右侧附近的属性选项卡上,选择编辑字段。
在字段窗格中,选择省略号,然后选择添加自定义卡。
新卡将显示在窗体控件的底部。
根据需要调整卡的大小以显示所有文本。
将 标签 控件插入自定义卡,然后将标签的 Text 属性设置为您在库中使用的公式:
If( IsType( ThisItem.Owner, Teams ), "Team: " & AsType( ThisItem.Owner, Teams ).'Team Name', "User: " & AsType( ThisItem.Owner, Users ).'Full Name' )
对于库中的每个选择,客户的更多字段(包括记录的负责人)将显示在窗体中。 如果使用 Patch 按钮更改负责人,窗体控件还会显示这一更改。
显示客户的列
在 Dataverse 中,客户查找列是另一个与负责人非常相似的多态查找。
负责人限制为每个表一个,但表可以包含零个、一个或多个客户查找列。 联系人系统表包括公司名称列,这是一个客户查找列。
通过为新列选择客户数据类型,您可以向表中添加更多客户查找列。
客户查找字段可以引用客户表或联系人表中的记录。 您将对这些表使用 IsType 和 AsType 函数,因此现在是将它们添加为数据源的好时机(您可以将团队和用户留在原地)。
客户和负责人字段的处理非常相似,您可以直接复制应用(文件 > 另存为,然后指定一个不同的名称),然后进行以下简单的替换:
Location | 负责人示例 | 客户示例 |
---|---|---|
整个 | 负责人 | 客户名称 |
整个 | 用户 | 客户 |
整个 | 团队 | 联系人 |
库的 Items 属性 | 客户 | 联系人 |
窗体的 Items 属性 | 客户 | 联系人 |
Patch 的第一个参数 在按钮的 OnSelect 属性中 |
客户 | 联系人 |
筛选单选按钮的 Items 属性 | [ "All", "Users", "Teams" ] | [ "All", "Accounts", "Contacts" ] |
修补单选按钮的 Items 属性 | [ "Users", "Teams" ] | [ "Accounts", "Contacts" ] |
组合框的 Visible 属性 | "Users" 和 "Teams" | "Accounts" 和 "Contacts" |
例如,新库应具有此 Items 属性:
Filter( Contacts,
Radio1.Selected.Value = "All"
Or (Radio1.Selected.Value = "Accounts" And 'Company Name' = ComboBox1.Selected)
Or (Radio1.Selected.Value = "Contacts" And 'Company Name' = ComboBox1_1.Selected)
)
客户和负责人之间的两个重要区别需要对库和窗体中的公式进行更新:
当您按名称引用这些表类型时,客户和联系人之间的一对多关系优先。 不使用 Accounts,而是使用 [@Accounts];不使用 Contacts,使用 [@Contacts]。 使用全局消除歧义运算符,您可以确保您指的是 IsType 和 AsType 中的表类型。 此问题仅在库和窗体控件的记录上下文中存在。
负责人字段必须有一个值,但是客户字段可以为空白。 若要不带类型名称显示正确结果,请使用 IsBlank 函数对此情况进行测试,然后显示空文本字符串。
这两个更改使用相同的公式,该公式显示在窗体中的自定义卡中,以及库的标签控件的 Text 属性中:
If( IsBlank( ThisItem.'Company Name' ), "",
IsType( ThisItem.'Company Name', Accounts ),
"Account: " & AsType( ThisItem.'Company Name', Accounts ).'Account Name',
"Contact: " & AsType( ThisItem.'Company Name', Contacts ).'Full Name'
)
通过这些更改,您可以查看和更改联系人表中的公司名称字段。
了解相关项查找列
相关项查找列与您在本主题中已经使用过的查找列略有不同。 您将从应用本主题前面介绍的模式开始,然后学习其他技巧。
您可以直接从传真表开始。 此表有一个多态的相关项查找列,它可以引用客户、联系人和其他表。 您可以为客户获取应用,并针对传真对其进行修改。
Location | 客户示例 | 传真示例 |
---|---|---|
整个 | 客户名称 | 关于 |
库的 Items 属性 | 联系人 | 传真 |
窗体的 Items 属性 | 联系人 | 传真 |
Patch 的第一个参数 在按钮的 OnSelect 属性中 |
联系人 | 传真 |
同样,您需要添加一个数据源:这次是传真。 在视图选项卡上,选择数据源:
相关的一个重要区别是它不限于客户和联系人。 实际上,表列表可使用自定义表扩展。 大多数应用无需修改即可适应这一点,但是您必须更新库和窗体中标签的公式:
If( IsBlank( ThisItem.Regarding ), "",
IsType( ThisItem.Regarding, Accounts ),
"Account: " & AsType( ThisItem.Regarding, Accounts ).'Account Name',
IsType( ThisItem.Regarding, Contacts ),
"Contacts: " & AsType( ThisItem.Regarding, Contacts ).'Full Name',
""
)
进行了这些更改之后,您就可以像使用负责人和客户查找一样使用相关查找。
了解“相关”关系
相关与负责人和客户不同,前者涉及多对一关系。 根据定义,反向的一对多关系使您可以编写 First( Accounts ).Faxes。
我们来备份一下,然后看一下表定义。 在 Dataverse 中,传真、任务、电子邮件、注释、电话联络、信件和聊天等表被指定为活动。 您还可以创建自己的自定义活动表。 当您查看或创建活动表时,其设置会显示在更多设置下。
如果其他表在表的设置中作为活动任务启用,它们可以与活动表关联。 客户、联系人和很多其他标准表都如此指定(同样,在更多设置下)。
所有活动表和活动-任务表都有隐含的关系。 如果将屏幕顶部的筛选器更改为所有,选择传真表,然后选择关系选项卡,所有可以作为相关项查找目标的表将显示。
如果您显示客户表的关系,所有可以作为相关项查找字段来源的表将显示。
这都是什么意思?
- 在编写公式时,您必须考虑到活动表的列表不是固定的,您可以创建自己的表。 公式必须能够适当地处理您没有预料到的活动表。
- 活动任务和活动具有一对多关系。 您可以轻松地要求与某个客户有关的所有传真。
在应用中探索此概念:
添加另一个屏幕。
插入一个库控件,调整其大小,然后将其移动到屏幕的左侧。
在屏幕右侧附近的属性选项卡上,将库的 Items 设置为 Accounts。
将库的布局设置为标题,然后将标题字段设置为客户名称。
添加第二个库,调整其大小,然后将其移动到屏幕的右侧。
将新库的 Items 属性设置为
Gallery2.Selected.Faxes
。此步骤将返回给定客户的经过筛选的传真列表。
将库的布局设置为标题和副标题,然后将标题字段设置为显示主题字段(可能是小写的主题)。
在客户列表中选择一项时,传真列表将仅显示该客户的传真。
活动表
如上一节所述,您可以显示某个客户的所有传真。 不过,您还可以显示客户的所有活动,包括传真、电子邮件、电话联络和其他交互。
对于后一种情况,您将使用活动表。 您可以打开右上角的所有从表列表中删除筛选器,以此来显示此表。
活动表是一个特殊表。 每当您向传真表中添加记录时,系统也会在活动表中创建一个记录,其中的列在所有活动表中是共有的。 在这些列中,主题是最有趣的列之一。
您可以通过仅更改上一个示例中的一行来显示所有活动。 将 Gallery2.Selected.Faxes
替换为 Gallery2.Selected.Activities
。
记录来自活动表,但您仍然可以使用 IsType 函数来识别它们是哪种类型的活动。 同样,在对表类型使用 IsType 之前,必须添加数据源。
使用此公式,可以在库中的标签控件中显示记录类型:
If( IsType( ThisItem, Faxes] ), "Fax",
IsType( ThisItem, 'Phone Calls' ), "Phone Call",
IsType( ThisItem, 'Email Messages' ), "Email Message",
IsType( ThisItem, Chats ), "Chat",
"Unknown"
)
您还可以使用 AsType 访问特定类型的字段。 例如,此公式确定每个活动的类型,对于电话联络,显示电话号码表中的电话号码和联络方向:
If( IsType( ThisItem, Faxes ), "Fax",
IsType( ThisItem, 'Phone Calls' ),
"Phone Call: " &
AsType( ThisItem, 'Phone Calls' ).'Phone Number' &
" (" & AsType( ThisItem, 'Phone Calls' ).Direction & ")",
IsType( ThisItem, 'Email Messages' ), "Email Message",
IsType( ThisItem, Chats ), "Chat",
"Unknown"
)
因此,应用将显示活动的完整列表。 所有类型的活动都将显示主题字段,无论公式是否考虑它们。 对于您了解的活动类型,您可以显示其类型名称和有关每个活动的特定于类型的信息。
注释表
到目前为止,所有相关项示例都基于活动,但注释表代表另一种情况。
创建表时,可以启用附件。
如果选中启用附件的复选框,您将创建与注释表的相关关系,如下图所示为客户表:
除此区别外,您将以与使用活动相同的方式使用相关查找。 为附件启用的表与注释具有一对多关系,如下例所示:
First( Accounts ).Notes
备注
在撰写本文时,相关项查找不能用于注释表。 您无法根据相关项列读取或筛选,也无法使用 Patch 设置列。
但是,反向的注释一对多关系可用,因此您可以对为附件启用的记录的注释列表进行筛选。 您还可以使用 Relate 函数将注释添加到记录的注释表中,但是必须首先创建注释,如此示例所示:
Relate( ThisItem.Notes, Patch( Notes, Defaults( Notes ), { Title: "A new note" } ) )
活动方
截至撰写本文时,画布应用不支持活动方。