【发布时间】:2018-10-11 07:40:05
【问题描述】:
我有多个 MaterialNo,我现在只举一个 Material No 的例子。类型栏告诉我们是否在特定日期购买或出售了材料。我已经根据材料编号和日期对数据进行了分类。现在我想实现 FIFO 逻辑 来计算已售材料的总价和单价。到目前为止,我已经在 Excel 中手动计算了。
MaterialNo Type Date Qty Price Balance-Quantity **TotalPrice** **UnitPrice**
XXXXXX Buy 03-2017 1250 79.99998042 1250 99999.97552 79.99998042
XXXXXX Sell 03-2017 20 1230 -1599.999608 -79.99998042
XXXXXX Buy 04-2017 2200 79.99999667 3430 175999.9927 79.99999667
XXXXXX Sell 04-2017 2375 1055 -189999.9721 -79.99998825
XXXXXX Buy 05-2017 997 79.9999625 2052 79759.96261 79.9999625
XXXXXX Sell 05-2017 2055 -3 -164399.9229 -79.9999625
XXXXXX Buy 06-2017 4749 79.99996153 4746 379919.8173 79.99996153
XXXXXX Sell 06-2017 3550 1196 -283999.8669 -79.9999625
XXXXXX Buy 07-2017 894 80.00001111 2090 71520.00993 80.00001111
XXXXXX Sell 07-2017 2100 -10 -167999.9213 -79.9999625
XXXXXX Buy 08-2017 2495 137.210024 2485 342339.0098 137.210024
XXXXXX Sell 08-2017 1900 585 -260699.0455 -137.210024
XXXXXX Buy 09-2017 2000 156.28 2585 312560 156.28
XXXXXX Sell 09-2017 2652 -67 -414454.56 -156.28
XXXXXX Buy 10-2017 596 156.2805875 529 93143.23015 156.2805875
XXXXXX Sell 10-2017 476 53 -74389.55965 -156.2805875
XXXXXX Buy 11-2017 5600 156.2800066 5653 875168.0371 156.2800066
XXXXXX Sell 11-2017 1111 4542 -173627.0874 -156.2800066
XXXXXX Buy 12-2017 1118 156.2800863 5660 174721.1365 156.2800863
XXXXXX Sell 12-2017 1222 4438 -190974.2654 -156.2800863
XXXXXX Buy 01-2018 2162 156.28 6600 337877.36 156.28
XXXXXX Sell 01-2018 4188 2412 -654500.64 -156.28
XXXXXX Buy 02-2018 792 156.2796819 3204 123773.5081 156.2796819
XXXXXX Sell 02-2018 2602 602 -406639.7323 -156.2796819
XXXXXX Buy 03-2018 400 156.28 1002 62512 156.28
XXXXXX Sell 03-2018 560 442 -87516.8 -156.28
另一个没有负余额数量的场景
MaterialNo Type Date Qty Price Balance Quantity TotalPrice Unit Price
SSSSSSSS Buy 06-2017 30 140.8 30 4224 140.8
SSSSSSSS Sell 06-2017 30 0 -4224 -140.8
SSSSSSSS Buy 07-2017 150 140.8 150 21120 140.8
SSSSSSSS Sell 07-2017 16 134 -2252.8 -140.8
SSSSSSSS Sell 08-2017 22 112 -3097.6 -140.8
SSSSSSSS Buy 09-2017 150 207.4399333 262 31115.99 207.4399333
SSSSSSSS Sell 09-2017 112 150 -15769.6 -140.8
SSSSSSSS Buy 10-2017 250 207.4399 400 51859.975 207.4399
SSSSSSSS Sell 10-2017 63 337 -13068.7158 -207.4399333
SSSSSSSS Buy 11-2017 3260 207.4399991 3597 676254.3969 207.4399991
SSSSSSSS Sell 11-2017 2655 942 -550753.167 -207.4399876
SSSSSSSS Buy 12-2017 300 207.44 1242 62232 207.44
SSSSSSSS Sell 12-2017 556 686 -115336.6395 -207.4399991
SSSSSSSS Buy 01-2018 428 207.44002 1114 88784.32856 207.44002
SSSSSSSS Sell 01-2018 448 666 -92933.11964 -207.4399992
SSSSSSSS Buy 02-2018 -9 207.44 657 -1866.96 207.44
SSSSSSSS Sell 02-2018 332 325 -68870.08188 -207.4400057
SSSSSSSS Buy 03-2018 699 207.43997 1024 145000.539 207.43997
SSSSSSSS Sell 03-2018 341 683 -70737.0462 -207.4400182
需要注意的一点 - 当余额数量为负时,它应该根据上次购买的价格计算已售材料的总价格。如有任何问题,请告诉我。
这是我试过的功能。
Dim prc As Double
Function fifoval(q As Range, Optional details As String) As Variant
Application.Volatile (True)
Dim i As Integer
Dim qstr As String
Dim pstr As String
Dim cqty As Integer
Dim qty As Integer
Dim ctr As Integer
Dim dstr As String
Dim amt As Double
'Stop
For i = 2 To q.Row - 1
If Cells(i, 1) = Cells(q.Row, 1) And IsNumeric(Cells(i, 7)) Then
Select Case Cells(i, 2)
Case "Buy"
qstr = qstr & Cells(i, 4) & ","
pstr = pstr & Cells(i, 5) & ","
Case "Sell"
qty = Cells(i, 4)
Do While qty > 0
cqty = Val(qstr)
If (cqty = 0) Then
fifoval = "Not enough balance"
Exit Function
End If
Select Case True
Case cqty = qty
qstr = Replace(qstr, cqty & ",", "", , 1)
pstr = Replace(pstr, Val(pstr) & ",", "", , 1)
qty = qty - cqty
Case cqty > qty
qstr = Replace(qstr, cqty, cqty - qty, , 1)
qty = 0
Case cqty < qty
qstr = Replace(qstr, cqty & ",", "", , 1)
pstr = Replace(pstr, Val(pstr) & ",", "", , 1)
qty = qty - cqty
Case cqty = 0
fifoval = "Not enough balance"
Exit Function
End Select
ctr = ctr + 1
If ctr > 1000 Then End: Stop
Loop
End Select
End If
Next i
qty = Cells(q.Row, 4)
Do While qty > 0
cqty = Val(qstr)
If (cqty = 0) Then
fifoval = "Not enough balance"
Exit Function
End If
prc = Val(pstr)
Select Case True
Case cqty = qty
dstr = dstr & IIf(dstr = "", "", " + ") & qty & " * " & prc
amt = amt + qty * prc
qstr = Replace(qstr, cqty & ",", "", , 1)
pstr = Replace(pstr, Val(pstr) & ",", "", , 1)
qty = qty - cqty
Case cqty > qty
dstr = dstr & IIf(dstr = "", "", " + ") & qty & " * " & prc
amt = amt + qty * prc
qstr = Replace(qstr, cqty, cqty - qty, , 1)
qty = 0
Case cqty < qty
dstr = dstr & IIf(dstr = "", "", " + ") & cqty & " * " & prc
amt = amt + cqty * prc
qstr = Replace(qstr, cqty & ",", "", , 1)
pstr = Replace(pstr, Val(pstr) & ",", "", , 1)
qty = qty - cqty
End Select
ctr = ctr + 1
If ctr > 1000 Then End: Stop
Loop
If details = "" Then
fifoval = amt
Else
fifoval = dstr
End If
End Function
【问题讨论】:
-
你有什么问题?该函数是否引发任何运行时错误。它编译正常。
-
编译正常,但结果错误....如果您将这篇文章中给出的总价和单价与编译结果进行比较,它不匹配
-
看起来你的买入价格是正确的。但是,您的卖出价格始终与之前的买入价格相同。
-
@Luuklag 就是这种情况......另一种情况是您不会有负余额数量。在这种情况下,计算会有所不同。
-
我已经更新了问题中的另一个场景。请检查
标签: excel excel-formula vba