使用 'each' 关键字将 "list" 传递给函数调用
Passing a "list" to a function call with the 'each' keyword
首先,我承认我不是 M 或 Power Query 专家,尽管我确实有一些 Power BI 经验。
我正在尝试开发一个股票投资组合,它将跟踪一个定制的股票列表及其价格历史和其他指标。我的部分代码基于以下博客,由于我正在尝试解决的问题:
https://datachant.com/2016/08/09/sentiment-analysis-power-bi-part-2/
我的项目中有以下函数 getPriceMetrics
,它将采用一个参数 Sym
和 return 单个股票代码的价格指标:
(Sym as any) => let
Source = Json.Document(Web.Contents("
https://finnhub.io/api/v1/stock/metric?metric=price&token=ABCXYZ&symbol=" & Sym))
in
Source
参数 Sym
基于包含股票代码列表的 "Query"。
当我尝试用一个单独的符号调用它时,该函数本身运行良好。但我想 运行 针对股票代码列表的功能 - 因此是上面的博客。
我认为博客中提供的解决方案可以很好地满足我的目的。唯一的障碍是我无法使用 each
关键字正确调用函数,我认为:
Table.Group(#"Renamed Columns", {"Index"},
{{"Data", each getPriceMetrics(_), type record}})
此时,我得到以下错误。
An error occurred in the ‘getPriceMetrics’ query. Expression.Error: We cannot apply operator & to types Text and Table. Details:
Operator = &
Left = https://finnhub.io/api/v1/stock/metric?metric=price&token=ABCXYZ&symbol=
Right = [Table]
如果有人能提供任何有关如何在使用 each
关键字时为函数调用提供列表参数的见解,我将不胜感激。
编辑:这是我最初的方法,从技术上讲是可行的,但由于每秒 30 API 次调用的限制,一些记录被 return 编辑为空。
let
Source = Excel.Workbook(File.Contents("C:\Users\Sikander\Google Drive\Docs\Finance\Investments\Questrade\FIRE_strategy.xlsx"), null, true),
Portfolio_Sheet = Source{[Item="Portfolio",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Portfolio_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Symbol", type text}, {"Company", type text}}),
#"Invoked Custom Function" = Table.AddColumn(#"Changed Type", "getPriceMetrics", each getPriceMetrics([Symbol]))
in #"Invoked Custom Function"
为了解决这个问题,我遵循了博客中建议的方法,该方法允许 "cheat" 这个 API 限制,可以这么说,通过索引和分组,如下所示:
let
Source = Excel.Workbook(File.Contents("C:\Users\Sikander\Google Drive\Docs\Finance\Investments\Questrade\FIRE_strategy.xlsx"), null, true),
Portfolio_Sheet = Source{[Item="Portfolio",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Portfolio_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Symbol", type text}, {"Company", type text}}),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1),
#"Integer-Divided Column" = Table.TransformColumns(#"Added Index", {{"Index", each Number.IntegerDivide(_, 10), Int64.Type}}),
#"Renamed Columns" = Table.RenameColumns(#"Integer-Divided Column",{{"Symbol", "Ticker"}}),
#"Grouped Rows" = Table.Group(#"Renamed Columns", {"Index"}, {{"Data", each getPriceMetrics(_), type record}})
在#"Grouped Rows"
发生错误是因为您向函数传递的是 table 而不是固定符号。对于特定(单个)Index
值,table 是 #"Renamed Columns"
的子 table。根据您的 table 是什么,您可以从 table 中选择一个元素传递给函数。如果您取每个 table _
.
的第一行 {0}
和 [Index]
列,这将是这样的
Table.Group(#"Renamed Columns", {"Index"},
{{"Data", each getPriceMetrics(_{0}[Index]), type record}})
但是,我认为根本没有理由做 Table.Group
。如果您的 "Query" 是一个列表,那么您可以简单地编写以下内容以将函数应用于每个元素:
List.Transform(Query, each getPriceMetrics(_))
如果 "Query" 是一个带有 [Sym]
列的 table,您可以将上面的 Query
替换为 Query[Sym]
,因为 table column 是一个列表。
或者,您可以使用简单的公式 getPriceMetrics([Sym])
在查询编辑器 GUI 中添加自定义列,它将使用以下代码创建一个步骤:
Table.AddColumn(#"Previous Step Name Here", "Custom", each getPriceMetrics([Sym]))
编辑: 我最近的回答有一些在查询编辑器中使用函数的屏幕截图,这些屏幕截图也与此处相关:
编辑 2: 正如下面的评论中所指出的,这个特定问题的解决方案与获得完全正确的语法无关,但需要睡眠功能,因为我在此 linked post.
中指出
Table.AddColumn(#"Changed Type", "PriceMetrics",
each Function.InvokeAfter(()=>getPriceMetrics([Symbol]),#duration(0,0,0,1)))`
首先,我承认我不是 M 或 Power Query 专家,尽管我确实有一些 Power BI 经验。
我正在尝试开发一个股票投资组合,它将跟踪一个定制的股票列表及其价格历史和其他指标。我的部分代码基于以下博客,由于我正在尝试解决的问题:
https://datachant.com/2016/08/09/sentiment-analysis-power-bi-part-2/
我的项目中有以下函数 getPriceMetrics
,它将采用一个参数 Sym
和 return 单个股票代码的价格指标:
(Sym as any) => let
Source = Json.Document(Web.Contents("
https://finnhub.io/api/v1/stock/metric?metric=price&token=ABCXYZ&symbol=" & Sym))
in
Source
参数 Sym
基于包含股票代码列表的 "Query"。
当我尝试用一个单独的符号调用它时,该函数本身运行良好。但我想 运行 针对股票代码列表的功能 - 因此是上面的博客。
我认为博客中提供的解决方案可以很好地满足我的目的。唯一的障碍是我无法使用 each
关键字正确调用函数,我认为:
Table.Group(#"Renamed Columns", {"Index"},
{{"Data", each getPriceMetrics(_), type record}})
此时,我得到以下错误。
An error occurred in the ‘getPriceMetrics’ query. Expression.Error: We cannot apply operator & to types Text and Table. Details:
Operator = &
Left = https://finnhub.io/api/v1/stock/metric?metric=price&token=ABCXYZ&symbol=
Right = [Table]
如果有人能提供任何有关如何在使用 each
关键字时为函数调用提供列表参数的见解,我将不胜感激。
编辑:这是我最初的方法,从技术上讲是可行的,但由于每秒 30 API 次调用的限制,一些记录被 return 编辑为空。
let
Source = Excel.Workbook(File.Contents("C:\Users\Sikander\Google Drive\Docs\Finance\Investments\Questrade\FIRE_strategy.xlsx"), null, true),
Portfolio_Sheet = Source{[Item="Portfolio",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Portfolio_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Symbol", type text}, {"Company", type text}}),
#"Invoked Custom Function" = Table.AddColumn(#"Changed Type", "getPriceMetrics", each getPriceMetrics([Symbol]))
in #"Invoked Custom Function"
为了解决这个问题,我遵循了博客中建议的方法,该方法允许 "cheat" 这个 API 限制,可以这么说,通过索引和分组,如下所示:
let
Source = Excel.Workbook(File.Contents("C:\Users\Sikander\Google Drive\Docs\Finance\Investments\Questrade\FIRE_strategy.xlsx"), null, true),
Portfolio_Sheet = Source{[Item="Portfolio",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Portfolio_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Symbol", type text}, {"Company", type text}}),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1),
#"Integer-Divided Column" = Table.TransformColumns(#"Added Index", {{"Index", each Number.IntegerDivide(_, 10), Int64.Type}}),
#"Renamed Columns" = Table.RenameColumns(#"Integer-Divided Column",{{"Symbol", "Ticker"}}),
#"Grouped Rows" = Table.Group(#"Renamed Columns", {"Index"}, {{"Data", each getPriceMetrics(_), type record}})
在#"Grouped Rows"
发生错误是因为您向函数传递的是 table 而不是固定符号。对于特定(单个)Index
值,table 是 #"Renamed Columns"
的子 table。根据您的 table 是什么,您可以从 table 中选择一个元素传递给函数。如果您取每个 table _
.
{0}
和 [Index]
列,这将是这样的
Table.Group(#"Renamed Columns", {"Index"},
{{"Data", each getPriceMetrics(_{0}[Index]), type record}})
但是,我认为根本没有理由做 Table.Group
。如果您的 "Query" 是一个列表,那么您可以简单地编写以下内容以将函数应用于每个元素:
List.Transform(Query, each getPriceMetrics(_))
如果 "Query" 是一个带有 [Sym]
列的 table,您可以将上面的 Query
替换为 Query[Sym]
,因为 table column 是一个列表。
或者,您可以使用简单的公式 getPriceMetrics([Sym])
在查询编辑器 GUI 中添加自定义列,它将使用以下代码创建一个步骤:
Table.AddColumn(#"Previous Step Name Here", "Custom", each getPriceMetrics([Sym]))
编辑: 我最近的回答有一些在查询编辑器中使用函数的屏幕截图,这些屏幕截图也与此处相关:
编辑 2: 正如下面的评论中所指出的,这个特定问题的解决方案与获得完全正确的语法无关,但需要睡眠功能,因为我在此 linked post.
中指出Table.AddColumn(#"Changed Type", "PriceMetrics",
each Function.InvokeAfter(()=>getPriceMetrics([Symbol]),#duration(0,0,0,1)))`