人生没有彩排
每一天都是现场直播

在PowerBI中以先进先出规则计算单批满足机制下的出库分配

先进先出(FIFO)是库存管理中广泛采用的核心原则,尤其在财务核算和成本计算中至关重要。本篇文章将介绍如何在PowerBI中实现基于先进先出规则的单批满足机制下的出库分配。

问题描述

计算每次出库时要使用的入库批次,在满足以下要求的情况下优先使用最早的入库批次:某产品对应的入库批次的入库数量在减去前面已分配给该产品的其它出库批次的出库数量后,要大于等于本次出库数量。

例如:1号入库10,2号入库20,3号入库30。然后5号要出库15,那么应该用2号的库存;然后6号要出库15,那么应该用3号的库存,而不是使用1号与2号剩余的库存之和。

具体问题如下图所示:


本案例的初始数据如下:

入库:

入库日期 入库批次 入库产品 入库数量
2022年9月1日 1 ID01 1000
2022年9月11日 2 ID01 200
2022年10月10日 3 ID01 200
2022年10月11日 4 ID01 1000

出库:

出库日期 出库批次 出库产品 出库数量
2022年9月10日 1 ID01 500
2022年9月11日 2 ID01 110
2022年9月30日 3 ID01 200
2022年10月1日 4 ID01 100
2022年10月10日 5 ID01 200
2022年10月20日 6 ID01 100
2022年10月21日 7 ID01 300
2022年10月23日 8 ID01 100

若需其它辅助表等,可自行创建并建模。

解题要点

在本案例中需要注意的是,查找某个产品出库时所用的入库批次时,必须要考虑到在前面出库的产品对库存的影响,否则计算结果将不正确,而这也是本案例的难点。

由于思路较复杂且难以描述,因此请直接从下文查看给出的示例答案来理解。


解决方案

首先,数据模型如下图所示:

然后,创建如下度量值:

入库批次 = 
MAXX(
    '出库',
    VAR CurOutDate = '出库'[出库日期]
    VAR CurOutPrd = '出库'[出库产品]
    VAR CurOutCode = '出库'[出库批次]
    VAR vTb1 = 
        FILTER(
            ADDCOLUMNS(
                GENERATE(
                    FILTER(ALL('出库'),'出库'[出库产品]=CurOutPrd && '出库'[出库批次]<=CurOutCode),
                    FILTER(ALL('入库'),'入库'[入库产品]=CurOutPrd && '入库'[入库日期]<=CurOutDate)
                ),
                "IsMeet",
                    IF('入库'[入库数量]>='出库'[出库数量] && '入库'[入库日期]<='出库'[出库日期],1,0)
            ),
            [IsMeet]>0
        )
    VAR vTb2 = 
        ADDCOLUMNS(
            vTb1,
            "CumOut",
                VAR CurInCode = '入库'[入库批次]
                VAR CurOutDate = '出库'[出库日期]
                RETURN
                SUMX(
                    FILTER(vTb1,'入库'[入库批次]=CurInCode && '出库'[出库日期]<=CurOutDate),
                    '出库'[出库数量]
                )
        )
    VAR vTb3 = 
        ADDCOLUMNS(
            vTb2,
            "IsExtraOut",
                VAR CurInCodeDate = '入库'[入库日期]
                VAR CurOutCode = '出库'[出库批次]
                VAR ActUseIncodeDate = 
                    MAXX(
                        TOPN(1,FILTER(vTb2,'出库'[出库批次]=CurOutCode && '入库'[入库数量]>=[CumOut]),'入库'[入库日期],ASC),
                        '入库'[入库日期]
                    )
                RETURN
                IF(CurInCodeDate>ActUseInCodeDate && ActUseInCodeDate<>BLANK(),1,0)
        )
    VAR vTb4 = 
        ADDCOLUMNS(
            vTb3,
            "CumOut_PartCorrect",
                VAR CurInCode = '入库'[入库批次]
                VAR CurOutCodeDate = '出库'[出库日期]
                VAR ExtraNum = 
                    SUMX(
                        FILTER(vTb3,'入库'[入库批次]=CurInCode && '出库'[出库日期]<CurOutCodeDate && [IsExtraOut]=1),
                        '出库'[出库数量]
                    )
                RETURN
                [CumOut]-ExtraNum

        )

    VAR vTb5 = 
        ADDCOLUMNS(
            vTb4,
            "IsExtraOut_Correct",
                VAR CurOutCode = '出库'[出库批次]
                VAR CurInCode = '入库'[入库批次]
                VAR CurOutCodeDate = '出库'[出库日期]
                VAR CurInCodeDate = '入库'[入库日期]
                VAR TempTable = FILTER(vTb4,'出库'[出库批次]=CurOutCode)
                RETURN
                IF(
                    MAXX(TempTable,[IsExtraOut])>0,
                    [IsExtraOut],
                    VAR ActUseIncodeDate =
                        MAXX(
                            TOPN(1,FILTER(TempTable,'入库'[入库数量]>=[CumOut_PartCorrect]),'入库'[入库日期],ASC),
                            '入库'[入库日期]
                        )
                    RETURN
                    IF(CurInCodeDate>ActUseInCodeDate && ActUseInCodeDate<>BLANK(),1,0)
                )
        )
    VAR vTb6 = 
        ADDCOLUMNS(
            vTb5,
            "CumOut_Correct",
                VAR CurInCode = '入库'[入库批次]
                VAR CurOutCodeDate = '出库'[出库日期]
                VAR ExtraNum = 
                    SUMX(
                        FILTER(vTb5,'入库'[入库批次]=CurInCode && '出库'[出库日期]<CurOutCodeDate && [IsExtraOut_Correct]=1),
                        '出库'[出库数量]
                    )
                RETURN
                [CumOut]-ExtraNum
        )
    RETURN
    MAXX(
        TOPN(1,FILTER(vTb6,'出库'[出库批次]=CurOutCode && '入库'[入库数量]>=[CumOut_Correct]),'入库'[入库日期],ASC),
        '入库'[入库批次]
    )
)

然后创建一个矩阵,并将出库表中的所有字段作为行标签,再将上面的度量值放入矩阵的值字段即可,如下图所示:

总结

以上方法仅供参考,若有更优雅的解决方案,欢迎留言讨论,或者加入我们的技术交流群,一起享受这种思维碰撞的快乐吧!

PBI/DAX技术交流群(QQ):344353627

赞(0) 打赏
版权声明:本文为夕枫的原创文章,著作权归作者所有,未经允许不得转载
文章名称:《在PowerBI中以先进先出规则计算单批满足机制下的出库分配》
文章链接:https://www.ximaple.com/posts/1171.html
订阅评论
提醒
guest
0 评论
最新
最久 最赞
内联反馈
查看所有评论

觉得文章有用的话就支持一下吧~

感谢您的打赏支持,我将持续输出有价值的内容!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册

Operation don't support