M(Power Query Formula Language)中打开记录类型的用途和用法

时间:2016-11-30 08:31:43

标签: excel record powerquery m

我已经阅读了Power Query的M语言的语言规范,并且遇到了开放记录类型。我的理解是开放类型允许其他领域,但我没有具体了解这是什么装置

声明正常(已关闭)记录的方法只是

myRecord = [name = "MyName", Age = 30]

从语言规范(5.4:记录类型):

myRecordType1 = type [Name = text, Age = number]       // Closed Record _type_
myRecordType2 = type [Name = text, Age = number, ...]  // Open Record _type_

然而,

myRecord = [Name = "MyName", Age = 30, ...] // Not valid code

所以看起来这个概念只是关于自定义记录类型,而不是一般的记录,但我不知道如何处理它。我试过这个:

testFunc = (inputArg as myRecordType2) => 1 // Not valid code

...期待它可能使该功能仅接受带有Name&amp ;;的记录。年龄字段和可选的其他字段,但没有。认为它可能不适用于as关键字,但即使这样也不起作用:

testTable = Table.AddColumn(Table.FromRecords({[A=1]}), "newcol", each [Name="MyName", Age=30], type myRecordType1) // Not valid code

有人可以为此说明一个用途(案例)吗? 我错过了语言规范中的某些内容吗?

2 个答案:

答案 0 :(得分:3)

我的解释如下。任何评论都表示赞赏(甚至其他想法)。

类型是值的分类。有两种口味:原始类型(数字,文本等)和自定义类型,例如:特定的表类型或记录类型。

例如,表类型是列名称集, - 类型和任何键值。 可以先指定表类型,然后在创建表时使用:

Tabeltype = type table[Key = number, Value = text],
TabletypeWithKey =  Type.AddTableKey(Tabeltype,{"Key"},true), 
TableWithKey = #table(TabletypeWithKey, {{1, "A"},{2, "B"}, {3, "C"}})

同样,您可以创建记录类型。

但是,创建记录时无法直接使用记录类型。 您可以使用Value.ReplaceType将类型“归类”为值,例如如果记录类型已关闭且没有可选字段,则为记录的记录类型。 以下代码中的示例。

我希望有可能验证某个值是否与特定类型匹配,但只能使用基本类型(使用关键字“is”或“as”或“Type.Is”)来完成。

所以我根据我的解释创建了下面的代码来检查记录与记录类型的一致性:我不能保证它是完整的证据。 目前,这是一个查询,因此您可以看到正在发生的事情,但您可以轻松地将其转换为函数,并使用当前已注释掉的代码的下半部分中的示例。

// Mext 2 lines to be decommented to turn the code into a function
//let
//    fnCheckConformity = (Record1 as record, RecordType as type) as logical =>
let
    // Next 2 lines to be removed when turning this code into a function
    Record1 = [x = 1, A = 3, B = 4],
    RecordType = type [x = number, optional y = text,...],
    RecordTypeFields = Type.RecordFields(RecordType),
    ToTable = Record.ToTable(RecordTypeFields),
    RecordTypeTable = Table.ExpandRecordColumn(ToTable, "Value", {"Optional", "Type"}, {"Optional", "Type"}),
    RecordTable = Table.FromColumns({Record.FieldNames(Record1),Record.FieldValues(Record1)},{"Record FieldName", "Record FieldValue"}),
    JoinedTable = Table.Join(RecordTypeTable, "Name", RecordTable, "Record FieldName", JoinKind.FullOuter),
    ConformityCheck = Table.AddColumn(JoinedTable, "Conform", 
                        each if [Optional] = null then Type.IsOpenRecord(RecordType) else
                             if [Optional] then true else
                             if [Record FieldValue] <> null then Value.Is([Record FieldValue], [Type]) else
                             false),
    Result = List.AllTrue(ConformityCheck[Conform])
in
    Result
// Add a comma after Result when turning the code above into a function
/* The code below can be used when turning the code above into a function.
// Examples:
    OpenRecordType = type [x = number, optional y = text,...],
    ClosedRecordType = type [x = number, y = text],
    RecordA = [x = 1],
    RecordB = [x = 1, A = 3, B = 4],
    RecordC = [x = 1, y = "MarcelBeug"],
//  RecordC is ascribed type ClosedRecordType:
    RecordCTyped = Value.ReplaceType(RecordC, ClosedRecordType),
    Conformity1 = fnCheckConformity(RecordA, OpenRecordType),   // true
    Conformity2 = fnCheckConformity(RecordA, ClosedRecordType), // false
    Conformity3 = fnCheckConformity(RecordB, OpenRecordType),   // true
    Conformity4 = fnCheckConformity(RecordB, ClosedRecordType), // false
    Conformity5 = fnCheckConformity(RecordC, OpenRecordType)    // true
in
    Conformity5 */

答案 1 :(得分:1)

马塞尔的答案很棒,但我可以添加更多的背景。

确实,今天“M”中的开放记录类型没有太多用途。

可以有用的一个地方是,如果我们有“粗糙”表格的概念,例如此CSV在不同的行中包含两个,三个和四个数据字段。

A,B,C
1,2
1,2,3
1,2,3,4

将此CSV加载到PQ编辑器/ Excel / PowerBI Desktop / powerbi.com可能会有效,但它不适合表值。在今天的“M”设计中,表基本上是具有非可选字段的已关闭记录的列表(因此您不能拥有比表列更多或更少字段的表行)。

Azure Table或OData等其他一些数据源也可能使用了不规则的表。现在,我们将返回一个包含一些固定列的表格,以及一个记录列[Content][Open Types]