Forum Discussion
Calling a function and function name is in a data row
Hello everyone,
Sorry for the repost, I think this is more Power Query related so I am posting here again.
I would like to add a new column which calls pre-made functions, and the name of functions are in a column.
I used Expression.Evaluate + Record.Combine to accomplish so previously. However, as #shared only works in Power Query but does not work in Power BI, I need other solutions.
First, turn the functions that I need into a list then use that list.
var_Shared = #shared,
ProcessorFunctionNames = List.Select(Record.FieldNames(var_Shared),each Text.EndsWith(_,"Processor")),
Result = List.Transform(ProcessorFunctionNames, each _ & " = " & _ & ","),
Original expression:
Expression.Evaluate( _[Processor] & "( _[Folder Path] & _[Name] , _[Publisher] )", Record.Combine({[_=_],#shared}))
New expression:
Expression.Evaluate( _[Processor] & "( _[Folder Path] & _[Name] , _[Publisher] )", Record.Combine({[_=_],Result}))
However, I am getting an expression error "Cannot turn values of List type into Record type.
Could someone please help me with the correct M expression?
Thank you so much for the time and help.
I think I understand what your trying to do now... Don't use Expression.Evaluate, it will just make your life harder. Instead use something like:
Record.Field(Output, [Processor])([Folder Path] & [Name], [Publisher])Oh I see what is missing...
Change:
GoogleGSMDailyProcessor = (fileName as text, publisherName as text) => GoogleGSMDailyProcessor,to
GoogleGSMDailyProcessor = (fileName as text, publisherName as text) => GoogleGSMDailyProcessor(fileName, publisherName),Also, if you hit the firewall issue in the online service, go to edit credentialls (for the dataset object, not the report itself) and set "Privacy level setting for this data source" to None
18 Replies
- AnonymousNot applicable
Hi primolee ,
Well, a straight answer to your question is that Result in your code is a List and the second argument of Expression.Evaluate() should be a Record. You can use Record.FromList() for conversion.
However, the problem, I think, is a bit deeper. If you look at the #shared as an example, this is a record where each field has the following template: DelegateName = Function. It is kind of accidental and a matter of convenience that the delegate and the function are called the same, it does not have to be so. For instance, these two lines of code do exactly the same:
Sum1 = Expression.Evaluate("List.Sum(SomeList)", [List.Sum= List.Sum]), Sum2 = Expression.Evaluate("Sum(SomeList)", [Sum= List.Sum])What you seem trying to create is a Record where fields look like Text=Text. This is not going to work for Expression.Evaluate().
You may need to use Field.SelectFields as in the code below:
let var_Shared = #shared, ProcessorFunctionNames = List.Select(Record.FieldNames(var_Shared),each Text.EndsWith(_,"Contains")), Result = Record.SelectFields(var_Shared, ProcessorFunctionNames), Output = Expression.Evaluate("Text.Contains(""asd"", ""a"")", Result) in OutputThis code will work in Power Query and Power BI Desktop, but is not suitable for Power BI Online as it does not like #shared and will not refresh. To make it work for PBI Online you need to list all the functions you are referring to in the Expression.Evaluate manually:
let Output = Expression.Evaluate("Text.Contains(""asd"", ""a"")", [Text.Contains=Text.Contains]) in OutputKind regards,
JB
- primoleeHelper V
Hello jborro,
Thank you so much for your reply. The reason of doing this is in this post.
https://community.powerbi.com/t5/Desktop/Data-won-t-show-in-Power-BI/m-p/866163#M415474
I don't know why but mine is not working in Power BI Desktop, either. Once I get to Expression.Evaluate, there won't be any data shown in Power BI Desktop. All columns are there but there won't be any data. However, all data are there in Power Query.
In worst case, I will simply refer manually as you said...
#"Invoked Custom Function" = Table.AddColumn(#"Check If Publisher Exists", "Processed Tables", each Expression.Evaluate( _[Processor] & "( _[Folder Path] & _[Name] , _[Publisher] )", [GoogleGSMDailyProcessor=GoogleGSMDailyProcessor,GoogleGSMHourProcessor=GoogleGSMHourProcessor,GoogleGDNDailyProcessor=GoogleGDNDailyProcessor,GoogleGDNAdGroupProcessor=GoogleGDNAdGroupProcessor,GoogleGDNSizeProcessor=GoogleGDNSizeProcessor])),But Power Query shows an error saying that #"Invoked Custom Function" is refering to other queries therefore cannot directly access data source.
So far I don't need to use Power BI Service online, I am just trying to make Desktop version work. Could you please help me and see what might be the problem?
Thank you so so much for the reply.
- AnonymousNot applicable
Hi primolee ,
Icey is right on #2, this is for when you need referencing to a current row. My example would look something like:
let var_Shared = #shared, ProcessorFunctionNames = List.Select(Record.FieldNames(var_Shared),each Text.EndsWith(_,"Contains")), Result = Record.SelectFields(var_Shared, ProcessorFunctionNames), Output = Expression.Evaluate("_[Function]", Record.Combine({[_=_], Result}) in OutputIn your post, you did not add [_=_] to the list of references. This should work:
#"Invoked Custom Function" = Table.AddColumn(#"Check If Publisher Exists", "Processed Tables", each Expression.Evaluate( _[Processor] & "( _[Folder Path] & _[Name] , _[Publisher] )", [_=_, GoogleGSMDailyProcessor=GoogleGSMDailyProcessor,GoogleGSMHourProcessor=GoogleGSMHourProcessor,GoogleGDNDailyProcessor=GoogleGDNDailyProcessor,GoogleGDNAdGroupProcessor=GoogleGDNAdGroupProcessor,GoogleGDNSizeProcessor=GoogleGDNSizeProcessor])),Kind regards,
JB