Forum Discussion
Looping through a table in an m function
- 7 years ago
So given the edits to your question I would do this in two steps, first doing an add column to produce the row by row operation where you subtract 1000 from the year and multiply the price by 2. Then do a List.Accumulate over that column adding line breaks between each row.
eg
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjIwMFDSUTI1VYrVAfMMQTxzGM8IxDNQio0FAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Year = _t, Price = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Year", Int64.Type}, {"Price", Int64.Type}}), #"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each Number.ToText([Year] - 1000) & "," & Number.ToText( [Price]*2)), Custom = #"Added Custom"[Custom], result = List.Accumulate(Custom, "", (state, current) => state & current & "#(cr)#(lf)" ) in resultPS. The Binary.FromText in the first line is just the pasted data from your question
Awesome! I just made Source=lineData and it all worked as expected. I will look into some of the code there and work out how it all works so I can pull it apart and use it where needed. I notice that even though we added a column here, it does not show in the table we added it to. Is this because the added column is only on the instance of the table in this function (so the variable of Source), so once the function completes it ceases to exist?
I notice that even though we added a column here, it does not show in the table we added it to. Is this because the added column is only on the instance of the table in this function (so the variable of Source), so once the function completes it ceases to exist?
Yes, that's correct. The table with the added column is sort of like a tempory variable that only exists for the duration of the query. Note that it's also possible that the optimizer in PowerQuery could "fold" the logical addcolumns and accumulate steps into one physical loop over the source data (it's a pretty smart engine most of the time)
- d_gosbell7 years agoSuper User
Anonymous wrote:Another quick question, I send a table in as (thisTable as table)=> is it possible to send a field in that way? So in this case I have (thisTable as table, field1 as field, field2 as field)=> and would send in Year Prices as the table name, Year as field1 and Price as field2.
Or would I have to send in the field names as text and reference them that way?
I think you'd have to send in the field names as text. Checking out the M type system here I can't see any way of strongly typing to a field. So you'd probably need to write the code as something like the following:
let fnAccumulate = (sourceTable as table,field1 as text, field2 as text ) as text => let #"Added Custom" = Table.AddColumn(sourceTable, "Custom", each Number.ToText(Record.Field(_,field1) - 1000) & "," & Number.ToText( Record.Field(_,field2) *2)), Custom = #"Added Custom"[Custom], result = List.Accumulate(Custom, "", (state, current) => state & current & "#(cr)#(lf)" ) in result in fnAccumulate - d_gosbell7 years agoSuper User
Anonymous wrote:Yeh, thats what I did, just figured it would be cool to have a selector like with the table as it saves typos. Thanks for that. I also wanted to have a whole number come in, but params only support decimal (number) and no other types! Have to convert it once in there to int64. This seem right?
Yes, that sounds correct. The base type system only has "number", it does not differentiate between decimal or int or anything like that.
- Anonymous7 years agoNot applicable
Another quick question, I send a table in as (thisTable as table)=> is it possible to send a field in that way? So in this case I have (thisTable as table, field1 as field, field2 as field)=> and would send in Year Prices as the table name, Year as field1 and Price as field2.
Or would I have to send in the field names as text and reference them that way?
- Anonymous7 years agoNot applicable
Yeh, thats what I did, just figured it would be cool to have a selector like with the table as it saves typos. Thanks for that. I also wanted to have a whole number come in, but params only support decimal (number) and no other types! Have to convert it once in there to int64. This seem right?