后台有人问先进先出式出货的问题……
先说一下,我们这里说的先进先出,不是数据结构上的队列……就只是一种就事论事—— 百度是这么说的,先进先出是根据先入库先发出的原则,对于发出的存货以先入库存货的单价计算发出存货成本的方法…… 这事看起来很复杂,代码实现起来……简单。 举个例子。 下图是一份库存表。 
B列是产品名称,D列是单价,C列是进货数量,E列是已出库的数量,F列是实际存货的数量…… 下图是一张出货单。本着没事就偷懒的原则,这张出货单星光模拟的极其简陋,没有出货日期,也没有出货单号…… 
假设咱们现在出货的产品名称是:星光牌印钞机,出货数据量是150…… 那咱们就要去库存表里找星光牌印钞机了…… 在第3行找到了一条记录,可惜存货量为0,没用,继续向下找…… 在第4行又找到了一条记录,只有23个,先拿过来,此时我们还需要150-23=127个星光牌印钞机…… 在第9行又找到了一条记录,有144个,用不了这么多,拿过来127就够了,剩下的录入结余数…… 所以计算完成后的出货单是下面这样子。 
库存表就变成了酱紫: 
把以上找星光牌印钞机的过程用VBA代码描述下来就好了。 动图如下: 
代码如下: Sub FirstInFirstOut() Dim arr As Variant Dim Pname As String Dim Pnum As Long, i As Long, j As Long Dim Jnum As Long, k As Long, Tnum As Long With Sheets('出库单') .Select Pname = Range('b2').Value '出货产品的名称 Pnum = Range('e2').Value '出货产品的数量 End With If Pname = '' Or Pnum = 0 Then MsgBox '老板,您的信息填写不完整。': Exit Sub arr = Sheets('库存表').Range('a1').CurrentRegion '库存表的数据装入数组arr ReDim brr(1 To UBound(arr), 1 To 6) '结果数组,出库单只有6列,故设置为6列。最大行数不可能超过数据源arr,故设置为arr的行数 ReDim crr(1 To UBound(arr), 1 To 1) '用于保存每个库存表商品出库的数量 For i = 1 To UBound(arr) If arr(i, 2) = Pname Then '如果库存表的产品名称等于出库单产品名称 Jnum = arr(i, 6) '结存数量 If Jnum > 0 Then '如果有结存数量 k = k + 1 If Jnum >= Pnum Then '如果结存数大于目标数 brr(k, 4) = Pnum '数量 Else brr(k, 4) = Jnum End If brr(k, 1) = k '序号 brr(k, 2) = arr(i, 2) '商品名称 brr(k, 3) = arr(i, 1) '进货日期 brr(k, 5) = arr(i, 4) '单价 brr(k, 6) = brr(k, 4) * brr(k, 5) '金额 crr(i, 1) = brr(k, 4) '将出库的商品数量记录起来 Tnum = Tnum + Jnum '累加总出库数量 Pnum = Pnum - Jnum If Pnum <= 0 Then Exit For End If End If Next If Pnum > 0 Then MsgBox '老板,冷静,你家的货不够出了啊。' & vbCrLf & _ '库存数量:' & Tnum & vbCrLf & _ '出货数量:' & Range('e2').Value Else Sheets('出库单').UsedRange.Offset(3).ClearContents Range('a4').Resize(k, UBound(brr, 2)) = brr '数据写入出库单 For i = 1 To UBound(crr) If crr(i, 1) > 0 Then '将出库的数量写入库存表 With Sheets('库存表').Cells(i, 5) .Value = crr(i, 1) + .Value End With End If Next MsgBox 'ok' End If End Sub 小贴士: 1,代码里有注释。 2,很多时候代码做的事,只是把人工做的过程直白的描述出来,特别是VBA这种简单的小程序,数据量不大,也用不到什么算法,就是换个语言叙事而已。 3,不要把问题想的复杂,循环最重要,不行就循环,把自己要的数据先挑出来再说。一个循环不够,你就再弄一个,就Excel那点数据,效率也不会差到哪里去……能解决问题就好。 比如,倘若是多品项先进先出法出货,如果想思路简单,那就再套一个循环一个个计算每个品项……当然啦,你如果了解字典,也可以用字典。但从解决问题的角度,那不是必须的。 4,示例文件下载: https://pan.baidu.com/s/1u4VY87g0M4ZQ5XGVF1bvKQ 提取码:ekq3
|