Forum Discussion
Understanding Expression.Evaluate - isn't working
- 6 years ago
When you use Expression.Evaulate you need to include every variable and library function you want to make avialable in a record. In your case:
Expression.Evaulte(#"Need Help", [Long Step Name = #"Long Step Name"])
When you use Expression.Evaulate you need to include every variable and library function you want to make avialable in a record. In your case:
Expression.Evaulte(#"Need Help", [Long Step Name = #"Long Step Name"])
Thanks artemus
So in the Final step below, Expression.Evalute doesn't know what to evaluate, and I have to tell it where Long Step Name is defined?
Why am I saying:
Long Step Name = #"Long Step Name"
Is "Long Step Name" how Evaluate.Expression sees it, and #"Long Step Name" is the reference to the step?
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WUtJR8krMUzAyMDJQitUB88G0Z0lqLpAdnJiTWgwWSATyDMGsJCDLCMxKBrKMlWJjAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t]),
#"Long Step Name" = Source,
#"Need Help" = Expression.Identifier("Long Step Name") & "[" & Table.ColumnNames(#"Long Step Name"){0} & "]",
Final = Expression.Evaluate(#"Need Help", [Long Step Name = #"Long Step Name"])
in
Final
- artemus6 years ago
Microsoft Employee
Yes, you are binding the object to the name it currently is known as.
The second parameter to Evaluate is the environment (which is optional). If you don't include the parameter then your statement cannot refer to any outside variables, or any standard functions like List.Max, the only calls you can make are the constructor for table, date, time, datetime, datetimezone, duration.
If you wanted to be able to reference all previous steps you would have to enumerate all of them in the record. If you wanted to include all top level objects you could use #shared, but if you use this, Power Bi will refuse to load it into the model due to security reasons.
Ex:
Expression.Evaulate("foo + List.Max([bar])", [foo = 9, _ = [bar = {1, 2, 7, 5}]], List.Max = each _{List.Count(_) - 1})
would evaulte to:
14, since foo = 9, and List.Max is bound to a function which returns the last element in a list (5), instead of the max of the list.
- ImkeF6 years ago
Community Champion
Hi edhans ,
My friend LarsSchreiber and I have written an article about the evaluation context in M that might explain a bit of this here (hopefully 😉 ) https://ssbi-blog.de/blog/technical-topics-english/the-environment-concept-in-m-for-power-query-and-power-bi-desktop-part-3/
You can find the official language specification here now: https://docs.microsoft.com/en-us/powerquery-m/power-query-m-language-specification
BTW: The "equivalent" of Table.Column is Record.Field (if you want to do some dynamic field referencing on row-level)
- edhans6 years ago
Community Champion
Thanks ImkeF for the reminder on Record.Field. I've used it before but not enough I could just code with it, so need to go back and refresh my memory with it.
So many ways to do the same or similar things in Power BI, but performance considerations, or just code readability, can be very different. 👍