设计库存管理系统时,很多企业都会要求:禁止出现负库存。
常规做法很简单——在出库单上设置一条校验公式,判断出库数量是否大于当前库存,如果超出就不允许出库。
这套逻辑在表间更新公式库存模式下完全没问题,在内源实时库存模式下日常录单也正常运行。但在一种特殊场景下,它会报错——你明明修改了一张历史单据,库存是足够的,系统却提示“负库存”,禁止保存。
举个例子:
有一批元钢:
入库10kg
第一次出库3kg
第二次出库7kg(库存刚好清零)
后来发现第一次出库录错了,不是3kg,应该是2kg。
当你打开第一张出库单准备修改时,系统却直接报错“不允许负库存”。明明库存是够的,为什么改单会报错?
根源在于Myexcel的运行机制
Myexcel的前端是Excel,后端是SQL数据库。它的设计原理和纯编程语言开发的软件不太一样。
在Myexcel中,有一个“本报表”的概念。我们打开一张表单录入数据但还未保存时,这份数据只存在于内存中,还没有写入数据库,这就是“本报表”。当我们打开一张已经保存过的历史单据进行修改时,系统并不会先把这张单据的原始数量从数据库中扣掉,而是从数据库中复制一份相同的数据作为“本报表”。
问题就出在这里:当你以修改方式打开一张旧单据时,数据库中的库存量仍然包含当前这张单据(本报表)的数量。这时候如果校验公式读取数据库中的当前库存量,得到的是一个“包含本报表数量”的结果,而不是真实的库存量。系统就会判断:本报表中的数量大于库存量,保存后会出现负库存——于是禁止保存,给你报错。
解决方案一:单据状态法
如果你需要修改历史出库单,可以用一个简单的办法:在单据上增加一个“单据状态”字段,选项为“已确认”和“录入中”。未确认或未录完的单据设为“录入中”,不参与库存计算;确认后改为“已确认”,才纳入库存统计。
修改历史单据时:
打开要修改的出库单
先把单据状态改为“录入中”,保存一次——这时该单据的数量会从库存中扣除
再修改为正确的数量,保存后把状态改回“已确认”
这样就可以绕过负库存校验,正常修改单据。
但这个方法也有局限:只能解决修改出库单的问题,修改入库单时仍可能导致负库存。如果你只是偶尔改单,这个方法够用了;如果需要经常修改各类单据,建议用下面的方案。
解决方案二:辅助表差值计算法(通用、彻底解决)
在出库单和入库单模板上都建立一个辅助表(建议单独放一个工作表,不要和明细表混在一起),包含五个字段:
编号
保存前库存量
修改前单据量
修改后单据量
保存后库存量

然后设置三条表间取数公式,执行时机设置为”保存前“:
第一条,从内源中取出当前商品在数据库中的库存量
第二条,从出库单中取出修改前的单据数量
第三条,把本报表中修改后的数量写入辅助表
最后用Excel公式计算“保存后库存量”:
出库单:保存后库存量 = 保存前库存量 + 修改前单据量 - 修改后单据量
入库单:保存后库存量 = 保存前库存量 - 修改前单据量 + 修改后单据量
校验时,用修改后的数量与辅助表中的“保存后库存量”对比,超出则禁止保存。
这样无论是修改入库单还是出库单,都能精准判断。辅助表可以设置为“不保存数据”,不产生数据冗余。
总结
常规校验公式:能防止新增时出现负库存,但管不住修改历史单据
单据状态法:简单易行,能解决修改出库单的问题,但不够全面
辅助表差值法:一劳永逸,入库、出库改单全部覆盖,推荐用于正式项目
如果你觉得这篇对你有用,欢迎收藏或分享给需要的朋友。也欢迎在留言区说说你在库存管理中遇到过哪些类似的坑,我可以在后续的案例中有针对性地讲。
夜雨聆风