PowerBI中动态处理梯度类型的多条件判断

这个例子是我实际工作中需要,但方法不是我原创,我在大牛代码基础上夹带了一丁点私货做了一点点改进而已。

需求

先来看需求:如下图,订单数量居于不同区间获得不同数额的提成。而梯度划分和每个区间的提成数额都会发生变化,要求能快捷更新。


梯度

如果梯度和各区间提成数额都是固定的,很好办。但是如果梯度表要动态变化,就比较头大。

解决方案

我本来想用DAX来做,没搞定;转而求其次用PowerQuery来处理。

首先,如果梯度表要动态更新,那么它必须成为数据源表,而不能写死在公式里。

其次,既然梯度表是数据源,而又需要根据不同订单量从其每一行提取数据,那么这里就需要一个函数来动态取值。这个函数如下:

(单数,fn) => 
  let 提成区间 = Expression.Evaluate("{" & fn &"}"), 
  Result = Number.From(List.First(List.Select(提成区间, each _{0}(单数))){1})*(单数) 
in 
  Result

“提成区间”这一行,本来应该是这样子:

let
  提成区间=
   { 
        {(x)=>x<40, 0}, 
        {(x)=>x<50, 40}, 
        {(x)=>x<60, 60}, 
        {(x)=>x<70, 70}, 
        {(x)=>x<80, 80}, 
        {(x)=>x<95, 90}, 
        {(x)=>true, 100} 
    }, 

但是梯度表本身会发生变化,所以不能像上面那样写死。爬网之后,找到了利用Expression.Evaluate()来根据源表数据构造计算表达式的方法,这样源表数据发生变化,表达式也就跟着变化了。

为什么要用{}构造一个list?因为“Result=……”那一行就是从list中取数的。
为什么要用{(x)=>x<40, 0}这样的形式而不是{(单数)=>单数<40, 0}呢?其实这个问题我也问过,当时没想清楚,现在想清楚了——因为(x)=>x<40是一个嵌套函数,如果采用和主函数一样的变量“单数”,反而容易让人犯晕,用(x)=>x<40这样的方式就不会弄混淆。当然,如果确实要用{(单数)=>单数<40, 0}这样的,也是没问题的。因为函数的变量名只要遵循PowerQuery的规范,就不会有问题。

那为什么用这样的方式就能保证循环没有遗漏呢?这个我也没搞懂。但是我估计和梯度区间设置有关系——设置区间要保证任意一个数只能同时落在一个区间内,否则就会出错。

那么,“fn”是个什么东西?这个是我自己夹带的私货——因为我有无数个梯度表,这些梯度表最后都要利用Expression.Evaluate()生成计算表达式,我偷懒就用一个参数代替了,这样我就只需要一个函数,要不然我每个梯度表都要生成一个函数,而每个函数结构又是一模一样,那样就不“优雅”了。

接下来看

  Result = Number.From(List.First(List.Select(提成区间, each _{0}(单数))){1})*(单数)

each _{0}后面跟一个括号括起来的参数是什么意思呢?“ _{0}”的结果是提成区间那个list中每个子元素的第一行,这个第一行是什么呢?是类似于“(x)=>x<40”这样的函数,既然是函数就要有参数,这个函数的参数是“单数”,因此“ _{0}”后面跟了个“(单数)”。

接下来的重点是如何构造Expression.Evaluate()所需的计算表达式。这就需要对梯度源表进行改造。
改造后的梯度表

就是新增了初值和终值两列。这样当把改造后的梯度表引入到PowerBI中后,用下面的代码生成计算表达式:

let
源 = Excel.Workbook(File.Contents("D:\Path\提成系数.xlsx"), null, true),
筛选的行 = Table.SelectRows(源, each ([Kind] = "Table")),
选择表格 = 筛选的行{[Item="大区经理新客户上线提成",Kind="Table"]}[Data],
更改的类型 = Table.TransformColumnTypes(选择表格,{{"梯度", type text}, {"初值", Int64.Type}, {"终值", Int64.Type}, {"每单提成", Int64.Type}}),
计算规则 = Table.AddColumn(更改的类型, "计算规则", each if [终值]=null  then true else "<="&Text.From([终值])),
自定义1 = Table.AddColumn(计算规则, "构造表达式", each "{(x)=>x"&Text.From([计算规则])&", """&Text.From([每单提成])&"""}"),
替换的值 = Table.ReplaceValue(自定义1,"xtrue","true",Replacer.ReplaceText,{"构造表达式"}),
自定义2 = Text.Combine(替换的值[构造表达式], ",")
in
自定义2

前面说了(x)=>x可以用“(单数)=>单数”代替,结果是一样的。最后结果就是把表格变成了一个文本串,这个文本串可以直接放到Expression.Evaluate()的参数中,进行运算,得到结果,供下一步处理。

反思

目前采用PowerQuery解决,用DAX是不是更简单些呢,我估计如果梯度是写死的,用DAX估计会简单些。但考虑到梯度是动态变化的,需要变成数据源表,估计DAX处理起来就不如PowerQuery了。但具体结果如何,还有待试验了才知道。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,114评论 0 13
  • 芦花趁着最后的秋色还在风中摇曳。芦苇上密生的灰褐色柔毛,源源不绝地形成花絮,撒向轻雾盘旋的天空,撒向水气氤...
    冰夫阅读 168评论 0 0
  • "生长是一个神奇的过程,几天、几周、几个月,孩子们就能完全脱离之前的模样,身体逐渐伸展开展。而衣服却不会因为身体的...
    收了纳个Queen阅读 678评论 0 5
  • 1、从文章中学到的 尊重是为人处世中很重要的一点,看似很简单却很难做到,而人与人交往的前提就是尊重,只有做到...
    小辫子_阅读 197评论 1 0
  • 中午时分,老公正在厨房做饭菜,我在旁边打下手,宝贝女儿还未放学回来。 12:26门铃准时响起,老公擦干手,小跑去开...
    雪绒花飞阅读 252评论 1 2