动态值

Dynamic 是 Power Fx 中的数据类型,可以保存任何数据结构、复杂或简单。 它不能直接使用,也不能在运行时显式或隐式转换为另一种数据类型。 可以使用点表示法访问 动态 值中的记录字段,并且字段的存在仅在运行时进行验证。

可通过两种方法创建 动态 值:

注释

Dynamic 以前称为 UntypedObject。 只有名称已更改,语义中没有变化。 名称出现在公式中的唯一位置是用户定义函数和用户定义的类型的实验版本。

简单类型

不能直接使用包含 动态 值的变量的值。 始终必须使用相应的类型构造函数正确键入它,或者使用 AsTypeParseJSON 函数将其转换为特定类型。

以下示例转换名为 动态变量的值。

Text(DynValue)
Value(DynValue)

下表列出了要将 Dynamic 转换为该数据类型的数据类型和相应的函数。

数据类型 函数 说明
布尔 Boolean() Dynamic 转换为 布尔值时,基础值必须表示可自动转换的布尔值或类型(如字符串“true”)。
Color ColorValue() 或 RGBA() 颜色可以在级联样式表 (CSS) 颜色定义表示法中表示为字符串,或表示为单独的 RGBA 组件。 动态可以直接从使用 ColorValue() 函数的级联样式表(CSS)颜色定义字符串转换为颜色,也可以使用 RGBA() 函数将单个 RGBA 数字转换为颜色。
货币、数字 Value() 动态 转换为 数字时,基础值必须表示可以自动转换的数字或类型(如字符串“123.456”)。
日期、日期/时间、时间 DateValue()、TimeValue() 或 DateTimeValue() 以 ISO 8601 格式表示时,日期、时间和日期时间可以直接从 Dynamic 转换为各自的类型。 其他格式必须首先使用 Text() 函数转换为文本,然后传递到默认将使用当前用户设置的语言解释日期和时间的 DateValue()、TimeValue() 或 DateTimeValue() 函数。
GUID GUID() 如果基础对象表示 GUID,或者表示字符串,则可以将 动态 值直接转换为 GUID。
超链接、图像和媒体 Text() 这些数据类型是文本数据类型,可以转换为文本,然后在 Power Fx 中使用。
选择项、双选项 Switch() 或 If() 选择项双选项在 Power Fx 中显示为本地化字符串。 选择项使用数字和双选项以布尔值形式作为后备。 没有从布尔值、数字或字符串到选择项双选项的直接转换,但 Switch()If() 函数可用于布尔值、文本或数字值,以正确分配选择项双选项值。
记录 没有从 动态 到记录结构的直接转换,但可以从 Dynamic 检索单个字段以创建新记录。
记录引用 记录引用对数据源是唯一的,在 Dynamic 中没有有意义的表示形式。
Table()ForAll() Dynamic 可以表示可转换为表的数组。 这些对象可以是记录数组,也可以是实际上是单列表的值数组。 ForAll() 可用于创建具有完全类型化记录的表。 查看本文后面的示例了解更多信息。
文本 Text() 文本可以直接转换。 如果动态值表示数字,则需要先使用 Value()动态转换为数字,然后再转换为文本。

记录类型

可以使用用于记录的常规点表示法来访问代表 动态 记录的变量上的字段。 但是,要到运行时才会验证字段的存在。 因此,也没有 Intellisense。 如果字段不存在或具有基础 null 值,访问它会产生 Blank() 值。

记录上的每个字段也是 Dynamic 类型的,需要正确键入。 该字段可以是简单类型的动态记录。 如果是记录,您可以链接点符号。 如果链中的任何字段都不存在,将返回 Blank()

以下示例使用名为 DynRecord变量中的字段。

Text(DynRecord.StringField)
Value(DynRecord.Field.ChildField)

如果字段名包含无效的标识符名称,例如,当字段名以数字开头或包含无效字符(如连字符)时,可以将字段名放在单引号内:

dynamic.'01'
dynamic.'my-field'

动态列访问

有时,记录中的列名是动态的。 使用 ColumnNames 函数确定记录中可用的列名称,然后使用 Column 函数检索命名列的值。

例如:

LettersUsed = ParseJSON( "{ ""d"": 2, ""p"": 3 }" );

Concat( ColumnNames( LettersUsed ) As Names, Names.Value, ", " )
// returns "d, p"

Sum( ForAll( ColumnNames( LettersUsed ) As Names, Column( LettersUsed, Names.Value ) ), Value )
// returns 5

数组

动态变量可以包含数组。 尽管该数组可以是记录数组或简单类型的数组,但使用 Table() 函数将动态数组转换为表将始终生成 Dynamic 的单列表。 ForAll()Index() 等函数不需要您首先创建 Table(),因此不需要您使用单列 Value 字段。

例如,若要获取 Dynamic 包含数字值的数组中的第二个数字( [1, 2, 3] ),以下公式可用于检索表中的第二行,并将列转换为数字:

Value( Index( UOArray, 2 ) )

如果 Dynamic 首先转换为 Table(), 则结果单列表中的第二行是 Value 包含 Dynamic 的列:

Value( Index( Table( UOArray ), 2 ).Value )

对于具有名为 Field 的文本列的记录数组,适用同样的逻辑。 可以直接访问 Dynamic ,或使用 Table() 函数将导致 动态的单列表。

Field该列可以直接从 Index() 函数返回的 Dynamic 进行访问。

Text( Index( UORecordArray, 2 ).Field )

使用 Table() 函数时,首先检索单列 Value 列以获取 Dynamic,然后访问 Field 该列:

Text( Index( Table( UORecordArray ), 2 ).Value.Field )

要将记录数组转换为类型化表,可以使用 ForAll() 函数并转换每个字段。

ForAll( UORecordArray, { FirstField: Value(ThisRecord.FirstField), SecondField: Text(ThisRecord.SecondField) } )

如果 Dynamic 首先转换为表,则 生成的 Dynamic 单列表将需要使用该 Value 列来获取字段。

ForAll( Table(UORecordArray), { FirstField: Value(ThisRecord.Value.FirstField), SecondField: Text(ThisRecord.Value.SecondField) } )

转换为类型化的记录和表

重要

ParseJSONIsTypeAsType 函数可用于批量将 Dynamic 转换为类型化对象,而不是单独转换每个简单值。 使用 Type 函数创建将动态结构映射到类型化结构的类型。

例如,这里我们将 JSON 字符串解释为日期/时间值,而无需调用 DateTimeValue 函数

Eclipse = ParseJSON( "{ ""Start"": ""2026-08-12T18:26:00.000Z"", ""End"": ""2026-08-12T18:33:00.000Z"" }",
                     Type( { Start: DateTime, End: DateTime } ) );

DateDiff( Eclipse.Start, Eclipse.End, TimeUnit.Minutes )
// 7