Power BI 系列 - M语言 -2 使用函数调用WebAPI以及Javascrirpt函数
场景介绍:
有一组数据需要显示当天温度及说明。当天的温度和说明是动态变化的。有以下解决方案,
1.通过ETL对数据进行整合后写入到表中。
2.调度WebAPI 取得对应城市天气 在数量不大的情况, 如果几十万条记录每次记录都要调一次WebAPI,可能有性能问题.
我们使用第2种方案进行讲解,数据格式如下
城市 气温说明
北京 13度 ( 昼夜温差大,风力较强,易发生感冒,请注意适当增减衣服,加强自我防护避免感冒)
成都 17度 (天凉,昼夜温差较大,较易发生感冒,请适当增减衣服,体质较弱的朋友请注意适当防护)
准备知识工作:
编号 | 类别 | 内容 | 说明 |
1 | WebAPI | https://www.apiopen.top/weatherApi?city=成都 | 调度API接口,例如成都天气(city=成都) |
2 | PowerBI 函数 |
fun1 (v_city)=> let source=xxxxxxxxxxxxxxxx, x=xxxxxxxx in fun1
|
PoweBI 函数 1.fun1 (v_city)=> 定义函数调用函数 2. let xxx xxxx 相当于函数体逻辑 3. in fun1 最后返回函数本身, 如果 in fun1("成都") 那么相当于直接返回结果. 那么就不是自定义函数了 |
3 | 获取WebAPI M语言 |
源 = Json.Document(Web.Contents("https://www.apiopen.top/weatherApi", [Query=[#"city"="成都"]])), |
1. Json.Document(xxxxx) 获取JSON 格式 2. Web.Contents(XXX) 调用WEBAPI 3. 其中 [Query=[#"city"="成都"]] 是 获得WEBAPI接口中参数值 如果这里需要做M函数,那么"成都" 将会是一个变量替换.例: [Query=[#"city"=v_city]] |
4 | 获最网页HTML |
源=Web.Page("<script> document.write('Hello,Barry'); </script>") |
获取网页内容DOM元素, 这段代码是通过JAVASCRIPT输出元素的 <script> document.write('Hello,Barry'); </script> 像正式表达,替换字符,改变字符,可以通过 javascript使用正则输出相应结果 |
开始步聚:
1.打开Power BI ,在开始菜单栏中,点新建空查询, 打开高级编辑器,如图所示
构建样例数据(当然样例数据也可以通过设计窗口 "输入数据" 或其它方式获得) 此例使用 M语言构造 把下列代码复制到高级编辑器中 ,并且重命名 "城市表"
let 源 = #table({"编号", "城市"}, {{1, "北京"}, {2, "成都"},{3,"三亚"} }) in 源
#table说明 ,#table({字段名..},{ {数据1..},{数据2...} } 相当于 select 1 as 编号,'北京' as 城市 union all select 2,'成都' ........
2.新建web查询, 点击菜单中 "数建源" 在URL中添入 https://www.apiopen.top/weatherApi?city=成都 然后点击确认
确认完成,进行导航并且提取需要信息, 过程如下图所示
M语言代码如下:
let 源 = Json.Document(Web.Contents("https://www.apiopen.top/weatherApi?city=成都")), data = 源[data], ganmao = data[ganmao] in ganmao
请求WebAPI的时候,返回JSON字符串 ,通过JSON格式数据结构,最终找到 气候的信息提示 并将其返回 ,
3.改造callWebAPI 查询为M函数. 上面只返回气候提示,需要把温度 合并到一起.
let fun1=(v_city)=> let 源 = Json.Document(Web.Contents("https://www.apiopen.top/weatherApi",[Query=[#"city"=v_city]])), // weatherapi&city=xxx 可以改造 [Query=[#"city"=v_city]] data = 源[data], ganmao = data[ganmao], wendu=data[wendu] // 温度也带出来,温度是json格式的wendu字段的数值 in "温度:"&wendu&" 说明("& ganmao&")" in fun1
这种写法相当于javascript var fun1=function(v_ctiy) { .... return xxxx } 其中返回JSON格式如下 上面M语言找到对应信息,通过JSON结果格式去寻找对应信息
最后结果
4.在样例数据中调用自定义函数,选中城市表,在菜单中选择"添加列",再选择"调用自定义函数"
最终 M语言
let 源 = #table({"编号", "城市"}, {{1, "北京"}, {2, "成都"},{3,"三亚"} }), 已调用自定义函数 = Table.AddColumn(源, "温度提示", each CallWebAPI([城市])) //增加列 用AddColumn, 调用函数是 CallWebAPI(xxxx) in 已调用自定义函数
JAVSCRIPT使用正则表达式进行格式化函数:
通过上面讲解,下面简单演示一下步聚. 例如字符串"zengxinwen barry" 替换化成 "zengxinwen,barry"
1.网页演示简单的javascript ,自定义一下javascript 函数,然后调用它,并且输出到网页body DOM元素中.
2.M语言转成函数,修改查询名称为 Call_JavaScript
let CallJavaScript=(v_Name)=> let Source=Web.Page("<script> var Customer=function(Name){ var re = /(\w+)\s(\w+)/; var str =Name ; var newstr = str.replace(re, '$2, $1'); document.write(newstr); } Customer('"&v_Name&"'); </script>"), Data = Source{0}[Data], Children = Data{0}[Children], Children1 = Children{1}[Children], Text = Children1{0}[Text] in Text in CallJavaScript
注: 这里数据源 使用的是 Web.Page, 里面是可以是具体的HTML 代码.
编辑一个样例数据,然后进行调用 M语言如下:
let 源 = #table({"姓名"}, {{ "zengxinwen barry"} }), 自定义列 = Table.AddColumn(源, "格式化的姓名", each Call_JavaScript([姓名])) in 自定义列
结束语:
最终效果
下载地址https://github.com/zengxinwen/PowerBI