由浅入深解释在 Power Pivot 中如何查找对应的值求得费用

(一) 简单匹配

有2个表,需要通过右边的报价表求出重量清单对应的单价。
数据源1
在Excel中我们可以直接使用Vlookup或者Index和Match组合匹配到,然后下拉即可

VlookUp(A2,E1:F4,2,0)*RoundUp(B2,0)
Index(F:F,Match(A2,E:E,0))*RoundUp(B2,0)

如果我们把表转换成超级表的话,则可以直接这样写,不需要下拉直接全部一次生成。
数据源2

VlookUp([@目的地],价格表,2,0)*RoundUp([@[重量(kg)]],0)
Index(价格表[单位价格(kg)],Match([@目的地],价格表[目的地],0))*RoundUp([@[重量(kg)]],0)

如果我们放到PP里面的话在添加列里面直接需要使用类似的LookUpValue函数

LookUpValue('价格表'[单位价格(kg)],'价格表'[目的地],'重量表'[目的地])*RoundUp('重量表'[重量(kg)],0)

如果把2个表建立1对多的关系后,书写的更精简化
表关系

Related('价格表'[单位价格(kg)])*RoundUp('重量表'[重量(kg)],0)

(二) 多条件匹配

如果我们在原来的基础上加一个条件,例如客户。

如果我们也是使用类似LookUpValue函数来操作的话,则需要进行增加一列辅助列,把目的地和客户组合起来进行匹配。这里我们可以用另外种方式来进行,相对于增加辅助列的话更灵活些。
数据源3

Calculate(FirstNonBlank('价格表'[单位价格(kg)],""),
          Filter('价格表',
                 '价格表'[客户]='重量表'[客户] && '价格表'[目的地]='重量表'[目的地]
                 )
          ) * RoundUp('重量表'[重量(kg)],0)

同理如果再加上一个报价时间的话也一样,再多加一个条件。但是这个条件会显得不一样,因为报价时间和发货时间是不等的,因为一般报价都是在发货前,所以在筛选的时候条件是报价时间<=发货时间,这时在筛选的时候会出现多个内容的表。
时间条件
我们以最后1条2019/2/5的时候A客户发深圳的报价来看。前2个条件一样,再多加1个时间条件,但是这样的写法出来的结果是不正确的。

Calculate(LastnonBlank('价格表'[单位价格(kg)],""),
          Filter('价格表',
                   '价格表'[客户]='重量表'[客户] && 
                   '价格表'[目的地]='重量表'[目的地] &&
                   '价格表'[报价时间]<='重量表'[发货时间]
                )
         ) * RoundUp('重量表'[重量(kg)],0)

因为LastnonBlank此时返回的是[单位价格kg]中最大的一个值,而不是最后的一个值。
错误计算
我们要取的价格应该是A客户发深圳在发货日2019/2/5之前最后的一次报价,应该是7,而不是8。
需要的结果
那如何才能返回最后一条信息呢?通过3个条件的筛选我们可以得出这个表。
3个筛选条件
把上面的筛选过程命名为时间的筛选条件sjsx变量那我们要取最后一个时间就可以直接用函数Calculate+FirstNonBlank返回最后一天为2019/2/1。
提取最后时间
有了这个最后的时间,按我们就可以按照之前的思路继续进行了,在添加列里面的公示如下。

var sj=   //代表返回最后的时间
     var sjtj=Filter('价格表',   //sjtj代表时间条件
                     '价格表'[客户]='重量表'[客户] &&
                     '价格表'[目的地]='重量表'[目的地] &&
                     '价格表'[报价时间]<='重量表'[发货时间]
                     )
     return
         Calculate(LastnonBlank('价格表'[报价时间],""),sjtj)  
return
Calculate(LastnonBlank('价格表'[单位价格(kg)],""),
          Filter('价格表',
                   '价格表'[客户]='重量表'[客户] && 
                   '价格表'[目的地]='重量表'[目的地] &&
                   '价格表'[报价时间]=sj
                )
         ) * RoundUp('重量表'[重量(kg)],0)

我们可以针对这个代码再进行简化,除了LastnonBlank字面意义是返回最后一条信息,还有一个函数TopN也是可以返回最后一行的信息,根据时间降序排序后获取第一行数据,然后通过Values进行取值。

var tj=Filter('价格表',   //tj代表根据筛选条件后返回的表
        '价格表'[客户]='重量表'[客户] &&
        '价格表'[目的地]='重量表'[目的地] &&
        '价格表'[报价时间]<='重量表'[发货时间]
              )
return
    Calculate(Values('价格表'[单位价格(kg)]),
              TopN(1,tj,'价格表'[报价时间])
              )* RoundUp('重量表'[重量(kg)],0)

(三) 增加首续重匹配

数据源4
这里我们需要查找的是2个值,一个是首重,一个是续重(单位价格),然后再去求运费。我们通过var变量来写,相对能够更清楚些。最终我们可以在添加列里面写上如下公式。

 var tj=Filter('价格表',   //tj代表根据筛选条件后返回的表
              '价格表'[客户]='重量表'[客户] &&
              '价格表'[目的地]='重量表'[目的地] &&
              '价格表'[报价时间]<='重量表'[发货时间]
              )
 var xz=Calculate(Values('价格表'[单位价格(kg)]), //xz代表续重
                  TopN(1,tj,'价格表'[报价时间])
                  )
 var sz=Calculate(Values('价格表'[首重]), //sz代表首重
                  TopN(1,tj,'价格表'[报价时间])
                  )
 var xzdw=RoundUp('重量表'[重量(kg)],0)-1  //xzdw代表续重计费单位
 return
 sz+xz*xzdw

解释:
取值的方式都是一样,只不过首重,续重针对不同的列表取值即可。因为这里涉及到一个首续重的问题,所以在最后求续重计费单位的时候要去掉一个首重。