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

PowerBI中FIFO出库分配实现方法

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

问题描述

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

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

具体问题如下图所示:

本案例的初始数据如下:

入库:

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

出库:

出库日期出库批次出库产品出库数量
2022年9月10日1ID01500
2022年9月11日2ID01110
2022年9月30日3ID01200
2022年10月1日4ID01100
2022年10月10日5ID01200
2022年10月20日6ID01100
2022年10月21日7ID01300
2022年10月23日8ID01100

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

解题要点

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

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

解决方案

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

然后,创建如下度量值:

入库批次 = 
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

### 创建动态物品出入库统计报表的方法 在 Power BI 中创建动态的物品出入库统计报表,首先需要建立一个合理的数据模型,并结合 DAX 表达式实现动态筛选和计算功能。数据模型应包含物品出入库记录表、日期表以及可能涉及的物品主数据表。出入库记录表中应包含物品编号、出入库日期、数量等字段,日期表则用于支持按时间维度进行筛选和分析。 为了实现动态报表,可以使用切片器(Slicer)控制时间范围、物品类别或具体物品,从而动态更新报表中的数据展示。例如,使用日期切片器选择特定的起止日期,报表会自动显示该时间段内的出入库情况。日期表应与出入库记录表建立多对一关系,并使用 `USERELATIONSHIP` 函数激活特定的日期关系,确保数据筛选逻辑正确[^1]。 ### 使用 DAX 实现动态计算 在创建动态报表时,DAX 表达式是实现动态计算的核心工具。例如,统计某个时间段内的总入库数量可以使用如下表达式: ```dax 指定时间段入库数量 = CALCULATE( SUM('出入库表'[入库数量]), DATESBETWEEN('日期表'[日期], [开始日期], [结束日期]) ) ``` 其中,`[开始日期]` 和 `[结束日期]` 是基于切片器选择的日期参数,确保报表能根据用户的筛选动态更新计算结果。类似地,统计出库数量也可以使用 `CALCULATE` 和 `DATESBETWEEN` 函数实现[^2]。 ### 结合 ALL 函数清除筛选上下文 在某些情况下,需要计算整体的出入库趋势或平均值,这时可以使用 `ALL` 函数清除筛选上下文的影响。例如,计算日均出入库数量可以使用如下表达式: ```dax 日均出入库数量 = CALCULATE( DIVIDE([总出入库数量], [总计天数], 0), ALL('出入库表') ) ``` 此表达式确保统计范围覆盖所有日期,而不受当前筛选条件的影响,从而支持全局趋势分析[^3]。 ### 数据模型设计与优化 为了支持动态报表的高效运行,数据模型设计应遵循以下原则: - **日期表作为单一事实表**:确保日期表是“单一事实表”,并与出入库记录表建立多对一关系。如果出入库记录表中包含多个日期字段(如入库日期、出库日期),则需要为每个日期字段建立独立的关系,并在计算时使用 `USERELATIONSHIP` 激活特定关系。 - **物品主数据关联**:物品主数据表应包含物品编号、物品名称、分类等字段,并与出入库记录表建立关联,支持按物品分类或具体物品进行筛选。 - **支持库存计算**:如果报表需要展示当前库存情况,可以结合历史出入库记录,使用 `SUM` 和 `FILTER` 函数计算当前库存量。例如: ```dax 当前库存 = CALCULATE( SUM('出入库表'[入库数量]) - SUM('出入库表'[出库数量]), FILTER(ALL('日期表'), '日期表'[日期] <= MAX('日期表'[日期])) ) ``` 此表达式基于历史数据计算截至当前日期的库存数量,支持动态更新[^4]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PowerBI | 夕枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值