Power Query - 从零件变更登记册创建历史记录 table
Power Query - Creating a History table from a Part Change Register
希望 Power Query Ninja 能帮助解决这个问题……
参考附件,我有 2 tables,第一个 [ChangeRegTBL] 是一个动态的 table(目前有 7500 多行),它将我们已经实施的更改附加到 build/assembly 行。在某些情况下,这些零件号更改会再次更改为新编号……在某些情况下会更改 7-8 次!
我想要的是一个 table(在参考附件中显示为 [ChangeHistTBL]),它列出了每个旧部分的历史记录以及它被取代的新部分是什么,如果更改了不止一次,则计数最后是历史 table 总结日期、变更请求和零件细节。
现在我已经进行了多次合并等等......但它只是混乱、缓慢而且肯定不会处理动态 table。
正在努力掌握列表。 Accumulate 功能...因为我觉得解决方案就在这个范围内
干杯
好的,我似乎无法将工作簿添加为附件,但如果需要可以发送!
尝试使用 List.Generate
为每个零件编号生成零件历史记录,如您的 table 所示,并使用 List.PositionOf
在 [=] 中找到 New Part
14=] 下一个历史步骤的列。
算法在旧零件列中进行一系列的新零件查找,然后将相应的历史条目添加到与旧零件关联的零件历史列表中。
不确定这种方法是否会更快,但应该是动态的:
查看代码中的注释。有不清楚的地方请教
M码
编辑以将“新零件”列更改为列表中的最后一个
已编辑以在当前行开始 List.Generate 循环
编辑以消除重新使用原始零件号时的无限循环
let
Source = Csv.Document(File.Contents("C:\Users\ron\OneDrive\Documents\ChangeReg.csv"),[Delimiter=",", Columns=5, Encoding=1252, QuoteStyle=QuoteStyle.None]),
#"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Index", Int64.Type}, {"Change Ref", type text}, {"Part Old", type text}, {"Part New", type text}, {"Part Description", type text}}),
//Create Part History column
ph = Table.AddColumn(#"Changed Type", "hist", each
let
cr = Text.Split([Change Ref]," ")
in cr{1} & "_" & [Part New] & "_" & cr{0} & "_" & [Part Description]),
#"Removed Columns" = Table.RemoveColumns(ph,{"Change Ref", "Part Description"}),
//create list of part histories and successor part number
#"Added Custom" = Table.AddColumn(#"Removed Columns", "phList", each
let
//start search at current row
newPart = List.RemoveFirstN(ph[Part New],[Index]),
oldPart = List.RemoveFirstN(ph[Part Old],[Index]),
partHist = List.RemoveFirstN(ph[hist],[Index]),
index = List.RemoveFirstN(ph[Index],[Index]),
trace = List.Generate(()=> [newP=newPart{0}, hist=partHist{0}, idx= index{0}],
each [idx] <> null,
each
let
//note that if [newP] not found then List.PositionOf => -1
i = List.PositionOf(oldPart,[newP])
in if i > index{0} then
[newP = newPart{List.PositionOf(oldPart,[newP])},
hist = partHist{List.PositionOf(oldPart,[newP])},
idx = index{List.PositionOf(oldPart,[newP])}]
else
[idx=null])
in
trace),
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom",{"Part New", "hist"}),
//Add last part number in the sequence
#"Added Custom1" = Table.AddColumn(#"Removed Columns1", "Part New", each List.Last([phList])[newP]),
//count number of times the part number changed
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Superceded Count", each List.Count([phList])),
//concatenate history of all the changes in the part numbers
#"Added Custom3" = Table.AddColumn(#"Added Custom2", "Part History", each List.Accumulate([phList],"",
(state,current)=> if state = "" then current[hist] else state & "#(lf)" & current[hist])),
#"Removed Columns2" = Table.RemoveColumns(#"Added Custom3",{"phList"})
in
#"Removed Columns2"
来源
结果
希望 Power Query Ninja 能帮助解决这个问题……
参考附件,我有 2 tables,第一个 [ChangeRegTBL] 是一个动态的 table(目前有 7500 多行),它将我们已经实施的更改附加到 build/assembly 行。在某些情况下,这些零件号更改会再次更改为新编号……在某些情况下会更改 7-8 次!
我想要的是一个 table(在参考附件中显示为 [ChangeHistTBL]),它列出了每个旧部分的历史记录以及它被取代的新部分是什么,如果更改了不止一次,则计数最后是历史 table 总结日期、变更请求和零件细节。
现在我已经进行了多次合并等等......但它只是混乱、缓慢而且肯定不会处理动态 table。
正在努力掌握列表。 Accumulate 功能...因为我觉得解决方案就在这个范围内
干杯
好的,我似乎无法将工作簿添加为附件,但如果需要可以发送!
尝试使用 List.Generate
为每个零件编号生成零件历史记录,如您的 table 所示,并使用 List.PositionOf
在 [=] 中找到 New Part
14=] 下一个历史步骤的列。
算法在旧零件列中进行一系列的新零件查找,然后将相应的历史条目添加到与旧零件关联的零件历史列表中。
不确定这种方法是否会更快,但应该是动态的:
查看代码中的注释。有不清楚的地方请教
M码
编辑以将“新零件”列更改为列表中的最后一个
已编辑以在当前行开始 List.Generate 循环
编辑以消除重新使用原始零件号时的无限循环
let
Source = Csv.Document(File.Contents("C:\Users\ron\OneDrive\Documents\ChangeReg.csv"),[Delimiter=",", Columns=5, Encoding=1252, QuoteStyle=QuoteStyle.None]),
#"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Index", Int64.Type}, {"Change Ref", type text}, {"Part Old", type text}, {"Part New", type text}, {"Part Description", type text}}),
//Create Part History column
ph = Table.AddColumn(#"Changed Type", "hist", each
let
cr = Text.Split([Change Ref]," ")
in cr{1} & "_" & [Part New] & "_" & cr{0} & "_" & [Part Description]),
#"Removed Columns" = Table.RemoveColumns(ph,{"Change Ref", "Part Description"}),
//create list of part histories and successor part number
#"Added Custom" = Table.AddColumn(#"Removed Columns", "phList", each
let
//start search at current row
newPart = List.RemoveFirstN(ph[Part New],[Index]),
oldPart = List.RemoveFirstN(ph[Part Old],[Index]),
partHist = List.RemoveFirstN(ph[hist],[Index]),
index = List.RemoveFirstN(ph[Index],[Index]),
trace = List.Generate(()=> [newP=newPart{0}, hist=partHist{0}, idx= index{0}],
each [idx] <> null,
each
let
//note that if [newP] not found then List.PositionOf => -1
i = List.PositionOf(oldPart,[newP])
in if i > index{0} then
[newP = newPart{List.PositionOf(oldPart,[newP])},
hist = partHist{List.PositionOf(oldPart,[newP])},
idx = index{List.PositionOf(oldPart,[newP])}]
else
[idx=null])
in
trace),
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom",{"Part New", "hist"}),
//Add last part number in the sequence
#"Added Custom1" = Table.AddColumn(#"Removed Columns1", "Part New", each List.Last([phList])[newP]),
//count number of times the part number changed
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Superceded Count", each List.Count([phList])),
//concatenate history of all the changes in the part numbers
#"Added Custom3" = Table.AddColumn(#"Added Custom2", "Part History", each List.Accumulate([phList],"",
(state,current)=> if state = "" then current[hist] else state & "#(lf)" & current[hist])),
#"Removed Columns2" = Table.RemoveColumns(#"Added Custom3",{"phList"})
in
#"Removed Columns2"
来源
结果