2016-11-30 39 views
3

我已经阅读了Power Query的M语言的语言规范,并且遇到了开放记录类型,我的理解是开放类型允许其他领域,但我没有什么,这意味着一个具体的了解M(Power Query Formula Language)中开放记录类型的用途和用法

宣布正常(关闭)记录的方法就是

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 

...期待它可能使函数只接受名称&年龄字段,以及可选的其他领域,但没有一个记录。认为它可能无法与as关键字的工作,但即使这样也不行:

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

可能有人说明了这是一个用(情况)? 我错过了语言规范中的一些东西吗?

+0

下面的答案当然有助于理解它有什么更好,但我仍然在这方面会有所损失_useful_。任何想法/用例? – alazyworkaholic

回答

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

马塞尔的答案是伟大的,但我可以添加多一点背景。

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

其中一个地方,它可能一直是有用的是,如果我们有“破烂”表的概念,例如,此CSV包含不同行中的两个,三个和四个数据字段。

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

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

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