2016-11-30 55 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]