相关文章推荐
怕考试的鼠标  ·  在JTable中使表头列横跨两列以显示一个表 ...·  1 年前    · 
买醉的拖把  ·  关于wrf格式的课件的视频转换问题 - ...·  1 年前    · 
任性的抽屉  ·  如何确定神经网络的层数和隐藏层神经元数量 - 知乎·  1 年前    · 
傻傻的铁链  ·  Caching - Improve ...·  1 年前    · 
正直的茶叶  ·  android ...·  1 年前    · 
Code  ›  PowerBI DAX 库存余量模型与计算开发者社区
date powerbi
https://cloud.tencent.com/developer/article/1708476
知识渊博的打火机
2 年前
作者头像
BI佐罗
0 篇文章

PowerBI DAX 库存余量模型与计算

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > PowerBI战友联盟 > 正文

PowerBI DAX 库存余量模型与计算

发布 于 2020-09-29 16:00:26
1.7K 0
举报

在真实的企业环境中,管理往往是按刚需分配,意思是:如果不出问题,那么就不会真正得到重视,因为说明还没有问题。

在库存管理中,常常面对的难题是:

要可以在无有效批次管理的前提下,知道各种批次余量。

这看着是个矛盾的需求,而却有着很重要的现实意义。

问题重述

在企业中,库存管理中,已经有两个表:

1、采购入库表,它记录了日期,SKU以及入库量。

2、库存盘点表,它记录了日期,SKU以及盘点余量。

问题来了:

如何在不增加额外管理复杂度的前提下,知道现有库存中的某SKU来自哪个批次以及库龄。

先来看看效果:

问题分析

把某SKU的商品或零配件放入仓库是很基本的管理。而必然会涉及到两个表:

1、采购入库表

2、库存盘点表

接下来的问题来了,例如,某日期,我们想知道当时在此前某日期那一批的存货还有多少,怎么办呢?

这就会额外涉及到一个批次管理的概念。

只有将物品的出入对应到相关的批次才能正确计算。

但这就会引入新的管理复杂度。

在实际的企业运行中,很多时候,批次管理是一个复杂的话题,那么,为了简化管理,常常采用:先入先出的方式,将最早入库的内容,当需要取出时,也最先拿出,这确保最新鲜的内容最不容易过期,而存放时间相对较长的也最早得到消耗。

如何实现 - 抽取维度

这里涉及到两个事实表,同属于多事实表问题。

来看看初始的数据模型结构,如下:

在设计和进行 DAX 计算时的大忌就是:直接计算。

本案例可以充分体现这点,要计算每一日对应SKU的余量,会同时涉及:

1、同时涉及两个事实表中的日期;

2、同时涉及两个事实表中的SKU。

那么,到底选择哪个表作为出发点呢?

结果是残忍的都不是。

我们必须从事实表抽取维度,而抽取通用日期维度的方式,大家都很熟悉,这里介绍抽取通用维度的方法:

Product =
DISTINCT(
    UNION(
        SUMMARIZE( '库存盘点表' , [SKU] ),
        SUMMARIZE( '采购入库表' , [SKU] )
)

这种方式,可以兼顾两个表,且确保维度的唯一性。

BI 佐罗提醒你注意

在具有主数据管理的情况下,可能会纳入主数据的比对,这超越了本文的范畴,不再说明。

如何实现 - 度量值

在有了有效结构以后,大致可以得到:

而经过仔细分析可以发现,在本例中只有一个日期表是无法正常运作的,我们必须使用第二个日期表来控制计算的参考日期,如下:

形成视图结构如下:

库存数量和入库数量都可以由简单的聚合计算给出,而每次入库所剩余的量以及库龄则比较复杂,效果如下:

其计算给出如下:

KPI.批次余量 =
VAR _date_current = MAX( 'Calendar'[Date] )
VAR _value_current = [KPI.入库数量]
VAR _date_next = CALCULATE( FIRSTNONBLANK( 'Calendar'[Date] , [KPI.入库数量] ) , 'Calendar'[Date] > _date_current )
VAR _date_ref = MAX( CalendarRef[Date] )
VAR _balance  = CALCULATE( LASTNONBLANKVALUE( 'Calendar'[Date] , [KPI.库存数量] ) , 'Calendar'[Date] <= _date_ref )
VAR _inventry = FILTER( ADDCOLUMNS( ALL( 'Calendar'[Date] ) , "@Input" , [KPI.入库数量] ) , [Date] <= _date_ref )
VAR _cummulated_for_current   = SUMX( FILTER( _inventry , [Date] >= _date_current && [Date] <= _date_ref ) , [@Input] )
VAR _cummulated_for_next      = SUMX( FILTER( _inventry , [Date] >= _date_next && [Date] <= _date_ref ) , [@Input] )
RETURN 
    IF( _balance >= _cummulated_for_current , _value_current ,
        IF( _balance >= _cummulated_for_next , _balance - _cummulated_for_next , 0 ) )

可以注意到,如果参考日期是2020-02-18,按照最后一次的盘点应该是 900,再考虑先进先出的原则,那么:

1、2020-02-15 的入库 200,应该未动,还是 200。

2、2020-02-05 的入库 500,应该未动,还是 500。

3、2020-01-18 的入库 400,应该出库 200,还剩 200。

这样,才能确保与最后一次盘点 900 准确对齐。

再来解读该公式的逻辑:

KPI.批次余量 =
VAR _date_current = MAX( 'Calendar'[Date] ) // 视图表格中行日期
VAR _value_current = [KPI.入库数量]              // 视图表格中行值
// 具有入库的下次日期
VAR _date_next = CALCULATE( FIRSTNONBLANK( 'Calendar'[Date] , [KPI.入库数量] ) , 'Calendar'[Date] > _date_current )
// 参考日期
VAR _date_ref = MAX( CalendarRef[Date] )
// 按照参考日期的库存结余
VAR _balance  = CALCULATE( LASTNONBLANKVALUE( 'Calendar'[Date] , [KPI.库存数量] ) , 'Calendar'[Date] <= _date_ref )
// 按照参考日期构建在该日期前的入库表
VAR _inventry = FILTER( ADDCOLUMNS( ALL( 'Calendar'[Date] ) , "@Input" , [KPI.入库数量] ) , [Date] <= _date_ref )
// 按视图表格中行日期计算积累余量
VAR _cummulated_for_current   = SUMX( FILTER( _inventry , [Date] >= _date_current && [Date] <= _date_ref ) , [@Input] )
// 按视图表格中行日期的下次有入库日期,计算积累余量
VAR _cummulated_for_next      = SUMX( FILTER( _inventry , [Date] >= _date_next && [Date] <= _date_ref ) , [@Input] )
RETURN 
    IF( // 如果库存结余比当然行日期后的积累余量还大,说明当前行日期的入库未被动
        _balance >= _cummulated_for_current , _value_current ,
        // 否则,如果库存结余比当然行日期后的积累余量小,但却比下一次有入库后的积累余量大,说明当前行日期的入库被部分使用
 
推荐文章
怕考试的鼠标  ·  在JTable中使表头列横跨两列以显示一个表头- JTable Java Swings
1 年前
买醉的拖把  ·  关于wrf格式的课件的视频转换问题 - 双鹏 - 博客园
1 年前
任性的抽屉  ·  如何确定神经网络的层数和隐藏层神经元数量 - 知乎
1 年前
傻傻的铁链  ·  Caching - Improve ASP.NET Web Application's Performance - CodeProject
1 年前
正直的茶叶  ·  android 截取两个特殊字符之间的数据,获取某特殊字符第n次出现的位置_51CTO博客_java截取两字符中间的字符
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号