博客:www.jiaopengzi.com

焦棚子的文章目录

请点击下载附件

一、背景

最近在玩钉钉日志,企业填写简单数据后方便汇总到一起比较实用的工具,但数据填写以后还是需要下载日志报表,比较麻烦。

在做BI的时候,可不可以用pq(power query)获取这些数据同步更新呢?查阅钉钉开发文档,日志是可以通过api接口获取。

那么写个pq(power query)自定义函数获取即可。

二、数据结构

为了方便演示,新建一个日志填写模板。

标题:测试日志

字段:日期,测试项目,测试值


设计日志模板

填写测试数据


填写好的日志

三、上M

1、自定义函数Fxdingding

看到这一串不要慌,直接复制到自己的pq中保存为Fxdingding即可。

let
fx=(AppKey as text ,AppSecret as text,Month as date,RecodeName as text,NameList as list ) as table=>
let
token=Json.Document( Text.FromBinary(Web.Contents("https://oapi.dingtalk.com/gettoken?appkey="&AppKey&"&appsecret="&AppSecret)))[access_token], //时间戳转北京时间===================================================

BeijingTime=(x as number) =>

let

t=DateTime.FromFileTime((11644473600000+x)*10000)

in

t, //日期转换为时间戳===================================================

UnixTimestampStart=(m as date)=>

let

源 = ((Number.From(m)-70365-19)86400-83600)1000,

tf=Text.From(源)

in

tf, //提供日期的月末最后一天转换为时间戳===================================

UnixTimestampEnd=(m as date)=>

let

t=Date.EndOfMonth(m),

st = ((Number.From(t)-70365-19)86400-83600)1000+86399999,

tf=Text.From(st)

in

tf, //根据cursor获取每页recode===========================================

fxrl=(n as number,name as text)=>

let

fx=Json.Document(

Web.Contents("https://oapi.dingtalk.com/topapi/report/list?"

, [Query=[access_token=token]

,Content=Text.ToBinary("{'start_time':"&UnixTimestampStart(Month)&",'end_time':"&UnixTimestampEnd(Month)&",'template_name':'"&name&"','cursor':"&Text.From(n)&",'size':20}")

]

)

)[result]

in

fx, //每页的recode转换成表===============================================

fxrt = (listr as list)=>

let

fx=Table.Combine(List.Transform(listr,(R)=> Table.FromRecords({Record.TransformFields( R,{"contents", each Record.FromList(Table.FromRecords()[value],Table.FromRecords()[key])})})))

in

fx, //获取corsorlist====================================================

//其中100是个参数,表2000条数据,多数需求能满足,大约这个数用条数除以20得到向上取整数字替换100

corsorlist={0} & List.Distinct( List.Transform({1..100},(L)=>List.Accumulate({1..L},0,(x,y)=>

if y=1 then

Json.Document(Web.Contents("https://oapi.dingtalk.com/topapi/report/list?"

,[Query=[access_token=token]

,Content=Text.ToBinary("{'start_time':"&UnixTimestampStart(Month)&",'end_time':"&UnixTimestampEnd(Month)&",'template_name':'"&RecodeName&"','cursor':"&Text.From(0)&",'size':20}")])

)[result][next_cursor]

else

Json.Document(Web.Contents("https://oapi.dingtalk.com/topapi/report/list?"

, [Query=[access_token=token]

,Content=Text.ToBinary("{'start_time':"&UnixTimestampStart(Month)&",'end_time':"&UnixTimestampEnd(Month)&",'template_name':'"&RecodeName&"','cursor':"&Text.From(x)&",'size':20}")])

)[result][next_cursor]))

), //获取每页数据的record组成datalist====================================

datalist = List.Transform(corsorlist,each fxrl(_,RecodeName)[data_list]), //datalist转换成表===================================================

tables = Table.Buffer(Table.Combine(List.Transform(datalist,each fxrt(_)))), //判断是否为空表,容错机制=============================================

TF=Table.IsEmpty(tables),//tables=#table({},{}) //用namelist展开recode得到表==========================================

展开 = if TF then #table(NameList,{}) else Table.ExpandRecordColumn(tables, "contents", NameList), //删除其他列得到目标列=================================================

删除 = Table.SelectColumns(展开,NameList) in

删除,

metadata=[

Documentation.Name="钉钉日志数据获取函数:Fxdingding",

Documentation.LongDescription="AppKey:登录钉钉开放平台获得(需要组织管理员权限);AppSecret:登录钉钉开放平台获得(需要组织管理员权限);Month:表示要获取数据的月份的1号填写为:#date(2019,1,1);RecordName:要获取的日志标题名称;NameList:日志的标题名称,使用list形式。"

]
in

Value.ReplaceType(fx,Value.Type(fx) meta metadata)

2、自定义函数的说明

function(AppKey as text ,AppSecret as text,Month as date,RecodeName as text,NameList as list ) as table

AppKey:登录钉钉开放平台获得(需要组织管理员权限);

AppSecret:登录钉钉开放平台获得(需要组织管理员权限);

Month:表示要获取数据的月份的1号填写为:#date(2019,1,1),为什么要设置这个参数,因为钉钉api获取数据是由日期限制的,好像是180天,所以数据就按照每月获取的;

RecordName:要获取的日志标题名称;

NameList:日志的标题名称,使用list形式。


自定义函数Fxdingding

3、调用函数得到结果

4、以上,对于pq了解多一些人操作起来没有问题,接下来再把函数和字段名称管理一起封装,让更多对pq不是很了解的人直接拿来就用(详细见附件)

步骤1:配置《01名称管理》Excel文件表名、ID、原始名称、统一名称;

步骤2:配置好Power BI文件4个参数;

步骤3:直接一个简单的函数Fxtable得到结果,是不是非常简单。

四、总结

1、直接调用自定函数fxdingding输入五个参数,即可得到结果;

2、注意参数的格式,详见上图《结果》

3、AppKey、AppSecret 获取需要管理员权限并登录钉钉开放平台获得;

钉钉开放平台​

4、具体步骤见开发文档;

钉钉开发文档​

5、服务器公网出口IP名单要提前设置好,不然数据会跑不出来。

6、由于每页20条数据限制,我们设置了获取2000条数据为上限,若数据超过这个限制,请参看自定义函数中说明,自行修改。

by焦棚子

焦棚子的文章目录

131_Power Query之获取钉钉日志自动刷新Power BI报告的更多相关文章

  1. 141_Power Query之获取钉钉审批流自动刷新Power BI报告

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 钉钉办公给很多企业带来了很多方便,比如审批流线上化,通用化.线上化填写后,数据自动获取又是一个硬伤了,虽然数据可 ...

  2. SpringBoot整合Nacos自动刷新配置

    目的 Nacos作为SpringBoot服务的注册中心和配置中心. 在NacosServer中修改配置文件,在SpringBoot不重启的情况下,获取到修改的内容. 本例将在配置文件中配置一个 cml ...

  3. 150_1秒获取Power BI Pro帐号

    博客:www.jiaopengzi.com 请点击[阅读原文]获取帐号 一.背景 当你来到这篇文章的时候,我想你已经在网上搜索了一圈了.网上有一大把教你如何注册Power BI帐号的方法,我们这里就不 ...

  4. 149_1秒获取Power BI Pro帐号

    一.背景 当你来到这篇文章的时候,我想你已经在网上搜索了一圈了.网上有一大把教你如何注册Power BI帐号的方法,我们这里就不在赘述了.因为各种因素的限制确实比较麻烦.我们直接提供Power BI ...

  5. 基础架构之日志管理平台及钉钉&邮件告警通知

    接上一篇,我们继续解释如何把ELK跟钉钉及发送邮件功能结合起来,让我们及时的了解重要日志并快速反馈. Sentinel 安装,项目介绍在https://github.com/sirensolution ...

  6. 一个人的安全部之ELK接收Paloalto日志并用钉钉告警

    起因 通报漏洞后,开发未能及时修复漏洞,导致被攻击,领导说我发现被攻击的时间晚了,由于一个人安全部精力有限未能及时看IPS告警,于是做了个钉钉告警. 本人环境介绍 ubuntu 14.04 pytho ...

  7. 【06】Jenkins:Gitlab 自动触发构建以及钉钉通知

    写在前面的话 在某些时候,我们希望能够实现这样一个功能,当用户提交东西到 gitlab 上的时候,希望它能够自动触发构建,发布到我们需要的环境. 目前我们内部有做类似的需求:产品提交原型到 gitla ...

  8. Python 实现 T00ls 自动签到脚本(邮件+钉钉通知)

    T00ls 每日签到是可以获取 TuBi 的,由于常常忘记签到,导致损失了很多 TuBi .于是在 T00ls 论坛搜索了一下,发现有不少大佬都写了自己的签到脚本,签到功能实现.定时任务执行以及签到提 ...

  9. Jenkins 实现Gitlab事件自动触发Jenkins构建及钉钉消息推送

    实现Gitlab事件自动触发Jenkins构建及钉钉消息推送 实践环境 GitLab Community Edition 12.6.4 Jenkins 2.284 Post build task 1. ...

随机推荐

  1. HTML入门学习笔记(二)

    第三章 文本 段落 p <p>毫不奇怪,p是最常用到的HTML元素之一</p> 作者联系信息 address address并不是用于标记邮政地址,而是定义与HTML页面或页面 ...

  2. Mac 安装WordPress

    Mac 安装WordPress 一.环境要求 PHP 5.2.4或更新版本 MySQL 5.0或更新版本 WebServer(可以选择Apache.nginx等支持PHP的,这里我选择Apache) ...

  3. css3 nth-child选择器

    css3 nth-child选择器 css3的nth-child选择器,乍看起来很简单,其实不是那么容易. 简单用法 p:nth-child(n) // 选择属于其父元素的第n个子元素的每个 < ...

  4. android:text 文字阴影设置

    <SPAN style="FONT-SIZE: 16px"><TextView  android:id="@+id/text"       a ...

  5. 【Android Studio】Gradle统一管理版本号引用配置

    1.在根目录下的build.gradle文件下添加 ext{ .... } 中的内容 ...... // Define versions in a single place ext { // SDK ...

  6. CSS简单样式练习(二)

    运行效果: 源代码: 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta char ...

  7. three车辆自由转弯(vue 极品飞车)

    //最近没有时间整理代码,就这样吧 <template> <div> <div id="map"></div> </div&g ...

  8. 【FAQ】应用集成HMS Core部分服务出现“ 6003报错”情况的解决方法来啦

    背景 开发者在应用中集成HMS Core部分服务时,android sdk 以及flutter等跨平台sdk,会出现编译打包后,运行报6003错误码的情况.根据查询可以得知,错误代码 6003 表示证 ...

  9. C语言结构体指针与结构体变量作形参的区别

    区别 结构体变量 结构体变量作为形参,传递的是结构体变量本身,是一种值传递 形参结构体变量成员值的改变不影响对应的实参构体变量成员值的改变 结构体指针 结构体指针作为函数参数,传递的是指向结构体变量的 ...

  10. 【简单dfs】Bubble Cup 14 - Finals Online Mirror (Unrated, ICPC Rules, Teams Preferred, Div. 2), problem: (J) Robot Factory,

    传送门  Problem - 1600J - Codeforces 题目   题意 给定n行m列, 求每个连通块由多少格子组成,并将格子数从大到小排序输出 对于每个格子都有一个数(0~15),将其转化 ...