Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel M(电力查询公式语言)中打开记录类型的用途和用法_Excel_Record_Powerquery_M - Fatal编程技术网

Excel M(电力查询公式语言)中打开记录类型的用途和用法

Excel M(电力查询公式语言)中打开记录类型的用途和用法,excel,record,powerquery,m,Excel,Record,Powerquery,M,我通读了Power Query的“M”语言的语言规范,发现了开放记录类型。我的理解是开放类型允许其他字段,但我对这意味着什么没有具体的理解 声明正常(关闭)记录的方法很简单 myRecord = [name = "MyName", Age = 30] 根据语言规范(5.4:记录类型): 但是, myRecord = [Name = "MyName", Age = 30, ...] // Not valid code 因此,这个概念似乎只是关于自定义记录类型,而不是一般的记录,但我不知道如何处

我通读了Power Query的“M”语言的语言规范,发现了开放记录类型。我的理解是开放类型允许其他字段,但我对这意味着什么没有具体的理解

声明正常(关闭)记录的方法很简单

myRecord = [name = "MyName", Age = 30]
根据语言规范(5.4:记录类型):

但是,

myRecord = [Name = "MyName", Age = 30, ...] // Not valid code
因此,这个概念似乎只是关于自定义记录类型,而不是一般的记录,但我不知道如何处理它。我尝试了以下方法:

testFunc = (inputArg as myRecordType2) => 1 // Not valid code
…预期它可能会使函数只接受包含名称和年龄字段以及可选其他字段的记录,但不会。认为它可能无法将
作为
关键字使用,但即使这样也不起作用:

testTable = Table.AddColumn(Table.FromRecords({[A=1]}), "newcol", each [Name="MyName", Age=30], type myRecordType1) // Not valid code
有人能举例说明这方面的用途吗?
我是否遗漏了语言规范中的某些内容?

我的解释如下。任何评论(甚至其他想法)都将不胜感激

类型是值的分类。有两种风格:基本类型(数字、文本等)和自定义类型,例如特定的表类型或记录类型

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

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

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

我希望能够验证值是否与特定类型匹配,但这只能通过基本类型来完成(使用关键字“is”或“as”或“type.is”)

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

//Mext要取消注释的两行代码,以将代码转换为函数
//让
//FNCheckConformance=(Record1作为记录,RecordType作为类型)作为逻辑=>
让
//将此代码转换为函数时要删除的下两行
记录1=[x=1,A=3,B=4],
RecordType=类型[x=编号,可选y=文本,…],
RecordTypeFields=Type.RecordFields(RecordType),
ToTable=记录。ToTable(RecordTypeFields),
RecordTypeTable=Table.ExpandRecordColumn(ToTable,“Value”、{“Optional”、“Type”}、{“Optional”、“Type”}),
RecordTable=Table.FromColumns({Record.FieldName(Record1),Record.FieldValues(Record1)},{“Record FieldName”,“Record FieldValue”}),
JoinedTable=Table.Join(RecordTypeTable,“Name”,RecordTable,“RecordFieldName”,JoinKind.FullOuter),
ConformityCheck=Table.AddColumn(JoinedTable,“Conform”,
如果[可选]=null,则键入.IsOpenRecord(记录类型)else
如果为[可选],则为true,否则为
如果[Record FieldValue]为空,则值为([Record FieldValue],[Type])否则
假),,
结果=List.AllTrue(符合性检查[符合])
在里面
结果
//将上述代码转换为函数时,在结果后添加逗号
/*将上面的代码转换为函数时,可以使用下面的代码。
//示例:
OpenRecordType=类型[x=数字,可选y=文本,…],
ClosedRecordType=类型[x=编号,y=文本],
记录A=[x=1],
记录B=[x=1,A=3,B=4],
RecordC=[x=1,y=“MarcelBeug”],
//记录C属于闭合类型记录类型:
RecordCTyped=Value.ReplaceType(RecordC,ClosedRecordType),
Conformity1=fnCheckConformance(RecordA,OpenRecordType),//true
Conformity2=fnCheckConformance(RecordA,ClosedRecordType),//false
Conformity3=fnCheckConformance(RecordB,OpenRecordType),//true
Conformity4=fnCheckConformance(RecordB,ClosedRecordType),//false
Conformity5=fnCheckConformance(RecordC,OpenRecordType)//true
在里面
一致性5*/

Marcel的回答很好,但我可以添加一些上下文

的确,现在“M”中的开放记录类型并没有太多用途

它可能有用的一个地方是,如果我们有“不规则”表的概念,例如,这个CSV在不同的行中有两个、三个和四个数据字段

A,B,C
1,2
1,2,3
1,2,3,4
将此CSV加载到PQ editor/Excel/PowerBI Desktop/PowerBI.com可能会起作用,但它不适合表格值。在今天的“M”设计中,表格基本上是一个包含非可选字段的封闭记录列表(因此,表格行中的字段不能多于或少于表格列)


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

下面的答案当然有助于更好地理解它是什么,但我仍然不知道这在哪里有用。有什么想法/用例吗?
Tabeltype = type table[Key = number, Value = text],
TabletypeWithKey =  Type.AddTableKey(Tabeltype,{"Key"},true), 
TableWithKey = #table(TabletypeWithKey, {{1, "A"},{2, "B"}, {3, "C"}})
// 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 */
A,B,C
1,2
1,2,3
1,2,3,4