Power Apps 中的数据类型

信息以小的离散值流经应用,与电子表格的单元格非常类似。 例如,生日 字段和 纪念日 字段中的数据都将作为包含年份、月份和日期的 日期 值流经。 应用知道如何设置这些值的格式,将输入限制为适合每个值的值,并与数据库共享这些值。 生日与人们的纪念日不同,但系统以完全相同的方式处理生日。 这种情况,数据类型的一个示例 日期

本文提供画布应用支持的数据类型的详细信息。 当应用连接到外部数据源时,该源中的每种数据类型都将映射到画布应用的数据类型。

数据类型 描述 示例
布尔值 truefalse 值。 无需比较即可直接在 IfFilter 和其他函数中使用。 true
颜色 颜色规范,包括 alpha 通道。 Color.Red
ColorValue( "#102030" )
RGBA( 255, 128, 0, 0.5 )
货币 存储在浮点数中的货币值。 货币值与带有货币格式选项的数字值相同。 123
4.56
日期 没有时间的日期,以应用用户所在时区计。 Date( 2019, 5, 16 )
日期时间 带时间的日期,以应用用户所在时区计。 DateTimeValue( "May 16, 2019 1:23:09 PM" )
GUID 一个全局唯一标识符 GUID()
GUID( "123e4567-e89b-12d3-a456-426655440000" )
超链接 用于保留超链接的文本字符串。 "https://powerapps.microsoft.com"
图像 .jpeg、.png、.svg、.gif 或其他常见 Web 图像格式的图像的统一资源标识符 (URI) 文本字符串。 MyImage 添加为应用资源
"https://northwindtraders.com/logo.jpg"
"appres://blobmanager/7b12ffa2..."
媒体 用于视频或音频录制的 URI 文本字符串。 MyVideo 添加为应用资源
"https://northwindtraders.com/intro.mp4"
"appres://blobmanager/3ba411c..."
数量 一个浮点数。 123
-4.567
8.903e121
单选 对一组选项的选择,以数字方式支持。 此数据类型将可本地化的文本标签与数字值组合在一起。 标签出现在应用中,数字值被存储并用于比较。 ThisItem.OrderStatus
记录 数据值的记录。 此复合数据类型包含本主题中列出的其他数据类型的实例。 详细信息:使用表 { Company: "Northwind Traders",
Staff: 35,
NonProfit: false }
记录引用 对表中记录的引用。 此类引用通常与多态查找一起使用。 详细信息:使用引用 First(Accounts).Owner
Table 一个记录表。 所有记录中数据类型相同的字段都必须具有相同名称,省略的字段将被视为 空白。 此复合数据类型包含本主题中列出的其他数据类型的实例。 详细信息:使用表 Table( { FirstName: "Sidney",
LastName: "Higa" },
{ FirstName: "Nancy",
LastName: "Anderson" } )
文本 一个 Unicode 文本字符串。 "Hello, World"
时间 没有日期的时间,以应用用户所在时区计。 Time( 11, 23, 45 )
双选项 对一组双重选项的选择,以布尔值方式支持。 此数据类型将可本地化的文本标签与布尔值组合在一起。 标签出现在应用中,布尔值被存储并用于比较。 ThisItem.Taxable

这些数据类型中有许多是相似的,并且具有相同的基础表示形式,如 超链接 字段被作为 文本 处理。 其他数据类型在窗体和其他控件中提供更好的默认体验。

Blank

所有数据类型都可以有一个 空白 值(即没有值)。 术语“null”通常用于此概念的数据库。

Blank 函数与 SetPatch 函数一起使用,可以将变量或字段设置为 空白。 例如,Set( x, Blank() ) 将删除全局变量 x 中的任何值。

使用 IsBlank 函数测试 空白 值。 使用 Coalesce 函数将可能的 空白 值替换为非 空白 值。

由于所有数据类型都支持 空白,因此 布尔双选项 数据类型实际上具有三个可能的值。

所有这四种数据类型均基于 Unicode 文本字符串。

嵌入文本

公式中的嵌入文本字符串用双引号括住。 同时使用两个双引号表示文本字符串中的单个双引号。 例如,在 Button 控件的 OnSelect 属性中使用以下公式:

Notify( "Jane said ""Hello, World!""" )

按下按钮时会出现横幅,这里省略了第一个和最后一个双引号(因为它们分隔文本字符串),Hello, World! 周围的重复双引号 被替换为单个双引号:

弹出通知,显示消息 Jane said "Hello, World."

单引号不用于包含特殊字符且在文本字符串中没有任何含义的标识符名称

图像和媒体资源

通过 文件 菜单,您可以将图像、视频和音频文件添加为应用资源。 导入文件的名称将成为应用中的资源名称。 在此图形中,名为 nwindlogo 的罗斯文商贸徽标已添加到应用:

Northwind 资源。

要在应用中使用此资源,请在 Image 控件的 图像 属性中指定它:

Northwind 图像。

图像和其他媒体的 URI

您可以通过将 标签控件的 文本 属性设置为 nwindlogo,来深入一些地探索最后一个示例。 标签显示文本字符串:

Northwind 文本。

画布应用通过 URI 文本字符串引用每个图像或其他媒体文件,无论是在云中还是作为应用资源添加。

例如,图像控件的 图像 属性不仅接受应用资源,还接受指向 Web 上图像的链接,如“https://northwindtraders.com/logo.jpg”。 此属性还接受使用数据 URI 架构的内联图像,如以下示例:

"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAFAQMAAACtnVQoAAAABlBMVEUAAAB0J3UMNU6VAAAAAXRSTlMAQObYZgAAABRJREFUCNdjUGJgCGVg6GgAkkA2AA8/AffqCEBsAAAAAElFTkSuQmCC"

该 URI 显示两个紫色钻石的放大版本:

双菱形。

如果将图像控件的 图像 属性设置为相机控件的 Photo 属性,则可以显示 Camera 控件中捕获的最新图像。 应用将图像保存在内存中,相机控件的 Photo 属性返回对图像的 URI 引用。 例如,您可能会拍摄一张照片,相机的 Photo 属性可能返回 "appres://blobmanager/7b12ffa2ea4547e5b3812cb1c7b0a2a0/1"

您使用 URI 来引用存储在数据库中的图像或另一个媒体文件。 这样,应用只有在实际需要时才检索实际数据。 例如,Microsoft Dataverse 表中的附件可能会返回 “appres://datasources/Contacts/table/...” 与相机示例中一样,您可以通过将图像控件的 Image 属性设置为此引用来显示此图像,这将检索二进制数据。

当您将媒体数据类型(如图像)保存到数据库时,应用会发送实际的图像或媒体数据,而不是 URI 引用。

大小限制

作为文本字符串和 URI,这些数据类型的长度没有预设的限制。

这些数据类型引用的二进制数据也没有大小的预设限制。 例如,通过相机控件捕获的图像现在引用为 "appres://...",其大小和分辨率可与设备相机要求的一样大。 媒体文件的分辨率、帧速和其他属性不受数据类型的限制,但是用于播放和捕获媒体的特定控件可能会有其自身的限制。

但是,所有数据大小均取决于应用中的可用内存量。 在台式计算机上运行的浏览器通常支持超过 100 MB 的数据。 但是,诸如手机之类的设备上的可用内存量可能要低得多,通常在 30-70 MB 之间。 要确定您的应用是否将在这些限制内运行,请在应运行它的所有设备上测试常见场景。

最佳做法是仅在必要时将数据保留在内存中。 尽快将图像上传到数据库;仅在应用用户请求下载时才下载图像。

数字和货币

数字货币 数据类型使用 IEEE 754 双精度浮点标准。 此标准提供很大的可选择数字范围,从 –1.79769 x 10308 到 1.79769 x 10308。 可表示的最小值为 5 x 10–324

画布应用可以准确表示介于 –9,007,199,254,740,991 (–(253 – 1)) 和 9,007,199,254,740,991 (253 – 1)(包括)之间的整数。 此范围大于数据库通常使用的 32 位(或 4 字节)整数数据类型。 但是,画布应用不能表示 64 位(或 8 字节)整数数据类型。 您可能希望将数字存储在文本字段中,或使用计算所得的列在文本字段中建立数字副本,以将其映射到画布应用中的 文本 数据类型中。 通过这种方式,您可以保留、显示和输入这些值,也可以将它们进行比较以确定它们是否相等;但是,您不能以这种形式对它们执行数值计算。

浮点算术是近似的,因此在许多记录的示例中,有时它可能会给出意外的结果。 您可能预期公式 55 / 100 * 100 会精确返回 55,(55 / 100 * 100) - 55 精确返回零。 但是,后一个公式将返回 7.1054 x 10–15,此值非常小,但不为零。 这种微小差异通常不会导致问题,应用会在显示结果时对其进行舍入。 但是,小差异会在随后的计算中加重并给出错误的答案。

数据库系统通常使用十进制数学来存储货币和执行计算,这提供了较小的范围,但对精度的控制更大。 默认情况下,画布应用将货币映射到浮点值之中或之外;因此,结果可能与以本机十进制数据类型进行的计算不同。 如果这种类型的差异会引起问题,可能需要将这些值作为 文本 进行处理,就像使用本节前面所述的大整数一样。

日期、时间和日期/时间

时区

日期/时间值属于以下类别:

  • 用户当地时间:这些值以 UTC(协调世界时)存储,但是应用用户的时区会影响应用如何显示这些值以及应用用户如何指定它们。 例如,相同的时刻对于加拿大用户与日本用户看起来会有所不同。
  • 时区无关:应用以相同的方式显示这些值,应用用户以相同的方式指定它们,而不管时区如何。 相同的时刻对于加拿大用户和日本用户看起来相同。 不希望自己的应用在不同时区运行的应用作者会使用这些值,因为它们总体上更简单。

下表显示了一些示例:

日期/时间类型 存储在数据库中的值 显示并进入 UTC 以西 7 小时的值 显示并进入 UTC 以东 4 小时的值
用户当地时间 Sunday, May 19, 2019
4:00 AM
Saturday, May 18, 2019
9:00 PM
Sunday, May 19, 2019
8:00 AM
时区无关 Sunday, May 19, 2019
4:00 AM
Sunday, May 19, 2019
4:00 AM
Sunday, May 19, 2019
4:00 AM

对于 用户当地时间 日期/时间,画布应用使用浏览器或设备的时区,而模型驱动应用使用 Dataverse 中的用户设置。 这些设置通常匹配,但是如果这些设置不同,则结果会有所不同。

使用 DateAddTimeZoneInformation 函数将本地时间转换为 UTC,然后返回。 请参阅这些函数的文档结尾处的示例。

数字等效项

画布应用以 UTC 保留和计算所有日期/时间值,无论是 用户当地时间 还是 时区无关。 在显示值和应用用户指定值时,应用将根据应用用户的时区转换这些值。

当画布应用从数据源读取 时区无关 值或将此类值写入数据源时,应用会自动调整值来补偿应用用户的时区。 然后,应用将该值视为 UTC 值,与应用中的所有其他日期/时间值一致。 由于此补偿,当应用针对应用用户的时区调整 UTC 值时,原始的 时区无关 值将出现。

您可以通过使用 Value 函数访问日期/时间值的基础数字值来更接近地观察此行为。 此函数以 1970 年 1 月 1 日 00:00:00.000 UTC 以来的毫秒数返回日期/时间值。

由于每个日期/时间值都以 UTC 保留,因此在世界上大部分地区,公式 Value( Date( 1970, 1, 1 ) ) 都不会返回零,因为 Date 函数返回 UTC 日期。 例如,此公式将以与 UTC 偏移八个小时的时区返回 28,800,000。 此数字反映八小时的毫秒数。

从上面回到我们的示例:

日期/时间类型 存储在数据库中的值 显示并进入 UTC 以西 7 小时的值 Value 函数返回
用户当地时间 Sunday, May 19, 2019
4:00 AM
Saturday, May 18, 2019
9:00 PM
1,558,238,400,000
(Sunday, May 19, 2019
4:00 AM UTC)
时区无关 Sunday, May 19, 2019
4:00 AM
Sunday, May 19, 2019
4:00 AM
1,558,263,600,000
(Sunday, May 19, 2019
11:00 AM UTC)

转换 Unix 时间

Unix 时间反映自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数。 由于画布应用使用毫秒而不是秒,因此可以通过乘以除以 1,000 来在两者之间进行转换。

例如,Unix 时间将 2001 年 9 月 9 日上午 1:46:40 UTC 显示为 1,000,000,000。 要在画布应用中显示该日期/时间值,将该数字乘以 1,000 以将其转换为毫秒,然后在 Text 函数中使用它。 公式 Text( 1000000000 * 1000, DateTimeFormat.UTC ) 将返回字符串 2001-09-09T01:46:40.000Z

但是,如果您在 UTC 偏移 -7 小时(UTC 以西 7 小时)的时区使用 DateTimeFormat.LongDateTime24 格式,该函数将返回 Saturday, September 8, 2001 18:46:40。 此结果将根据本地时区正确显示 日期/时间 值。

要转换为 Unix 时间,将 的结果除以 1,000:
RoundDown( Value( UnixTime ) / 1000, 0 )

如果需要 日期 值中的 Unix 时间来进行进一步计算或在 Power Apps 中显示,请使用以下公式:
DateAdd( Date( 1970,1,1 ), UnixTime, Seconds )

SQL Server

SQL Server 具有 日期/时间日期/时间 2 和其他日期/时间数据类型,这些数据类型不包含时区偏移,也不指示它们所在的时区。 画布应用假定这些值以 UTC 存储,并将它们视为 用户当地时间。 如果这些值与时区无关,请使用 TimeZoneOffset 函数针对 UTC 转换进行更正。

将值转换为应用的内部 UTC 表示形式时,画布应用会使用 Datetimeoffset 字段中包含的时区信息。 这些应用在写入数据时始终使用 UTC 作为时区(零时区偏移)。

画布应用以 ISO 8601 持续时间格式的文本字符串读取和写入 SQL Server 中 时间数据类型的值。 例如,您必须解析此字符串格式,然后使用 Time 函数将文本字符串 "PT2H1M39S" 转换为 时间 值:

With( 
    Match( "PT2H1M39S", "PT(?:(?<hours>\d+)H)?(?:(?<minutes>\d+)M)?(?:(?<seconds>\d+)S)?" ),
    Time( Value( hours ), Value( minutes ), Value( seconds ) )
)
// Result: 2:01 AM (as shown in a label control, use the Text function to see the seconds)

混合日期和时间信息

日期时间日期/时间 具有不同的名称,但是它们都会保留关于日期和时间的相同信息。

日期 值中可能包含时间信息,通常是午夜。 时间 值可能携带日期信息,通常为 1970 年 1 月 1 日。 Dataverse 还使用 仅限日期 字段存储时间信息,但默认情况下仅显示日期信息。 同样,画布应用有时会区分这些数据类型,来确定默认格式和控件。

不建议直接添加和减去日期和时间值,因为时区和其他转换可能会导致结果混乱。 您可以使用 Value 函数将日期/时间值首先转换为毫秒,然后考虑应用用户的时区,或者使用 DateAddDateDiff 函数在其中一个值上进行加减。

选择项和“是/否”

选择项和双选项数据类型为应用用户提供两个或多个可以选择的选择项。 例如,订单状态 选择项可能会提供 已发货已开票已结束 选择项。 双选项数据类型仅提供两个选择。

这两种数据类型均在文本字符串上下文中显示其标签。 例如,如果控件的 Text 属性设置为引用该选择项的公式,标签控件会显示订单状态选项之一。 选项标签可能已针对不同位置的应用用户进行了本地化。

当应用用户选择一个选项并保存更改时,应用会将数据传输到数据库,该数据库以独立于语言的表示形式存储该数据。 选择项中的选项作为数字传输和存储,双选项数据类型中的选项作为布尔值传输和存储。

标签仅用于显示目的。 您无法对标签进行直接比较,因为它们特定于语言。 而每个选择项都有一个与基础数字或布尔值一起使用的枚举。 例如,您不能使用以下公式:

If( ThisItem.OrderStatus = "Active", ...

但您可以使用以下公式:

If( ThisItem.OrderStatus = OrderStatus.Active, ...

对于全局选择项(哪些表共享),选项集枚举的名称将与全局选择项的名称匹配。 对于本地选择项(范围划定为表),名称可能包含表的名称。 如果多个表具有名称相同的选择项,此行为可避免冲突。 例如,客户 表可能有一个 OrderStatus 选择项,其名称可能是 OrderStatus(客户)。 该名称包含一个或多个空格和括号,因此,如果在公式中引用它,则必须用单引号括住。

此外,双选项值也可以充当布尔值。 例如,一个名为 TaxStatus 的双选项值可能具有标签 应纳税非应纳税,它们分别对应于 truefalse。 要进行演示,您可以使用以下公式:

If( ThisItem.Taxable = TaxStatus.Taxable, ...

您还可以使用以下等效公式:

If( ThisItem.Taxable, ...