更快的计算,以获得不同级别的数字倍数

时间:2013-03-20 19:53:24

标签: algorithm excel vba

以下是该方案:

我们有几件商品被运往许多商店。我们希望能够根据需要为商店分配一定数量的每件商品。这些商店中的每一个也与特定仓库相关联。

问题是,在仓库级别,每个项目的总数量必须是数字的倍数(例如6)。

我已经计算出每个商店在商店级别所需的数量,但它们在仓库级别的总和不会达到6的倍数。

我的解决方案是使用Excel:

使用SUMIFS公式跟踪在仓库级别分配的每个项目的总和。然后另一个MOD(6)公式计算剩余直到6的倍数。然后我的实际VBA代码循环并减去1(如果MOD< = 3)或从商店添加(如果MOD> 3)所有行的MOD = 0之前需要级单位。

现在这对我有用,但即使我只有约5000行也非常慢。

我正在寻找更快的解决方案,因为每当我减去/添加所需的单位时,需要再次计算SUMIFS和MOD。

编辑:(试图更清楚)

我有一个模板文件,我将数据粘贴到以下设置中:

+------+-------+-----------+----------+--------------+--------+
| Item | Store | Warehouse | StoreQty | WarehouseQty | Mod(6) |
+------+-------+-----------+----------+--------------+--------+
|    1 |     1 |         1 |        2 |            8 |      2 |
|    1 |     2 |         1 |        3 |            8 |      2 |
|    1 |     3 |         1 |        1 |            8 |      2 |
|    1 |     4 |         1 |        2 |            8 |      2 |
|    2 |     1 |         2 |        1 |            4 |      2 |
|    2 |     2 |         2 |        3 |            4 |      2 |
+------+-------+-----------+----------+--------------+--------+

目前,WarehouseQty列是SUMIFS公式,总结了与Warehouse关联的每个Item-Store组合的StoreQty。所以我猜每次Item-Store组合出现时,Warehouse / WarehouseQty列实际上都会重复多次。 WarehouseQty是需要为6的倍数的那个。

3 个答案:

答案 0 :(得分:0)

可以关闭屏幕更新以加快长度计算,如下所示:

Application.ScreenUpdating = FALSE

相反的分配会再次打开屏幕更新。

答案 1 :(得分:0)

猜测您可能会发现停止屏幕刷新可能会有很大帮助,因此不再需要任何建议。

另一种选择是将您的调整减少到可被6整除的数量到if语句的数量,具体取决于mod(6)的值。

您还可以使用数据透视表来解决如何在所有商店中总结特定商品的数量,并从那里读取总和比在宏中使用sumifs快得多的

根据您对问题的修改:

你是正确的,你可以逐行进行大量的复制计算,以及一次调整一个单位的数量,即使你确切知道需要添加/删除多少单位mod(6)公式。

您是否可以使用产品ID和商店的所有可能组合创建新工作表。然后,您可以对这些独特的组合中的每一个使用sumifs(),并在仓库级别向上/向下舍入最后一步?

答案 2 :(得分:0)

首先将数据放入数组,而不是单元格,然后在操作数据后将数据放回去 - 这样会快得多。

使用您的标准的示例:

Option Explicit

Sub test()
Dim q() 'this is what will be used for the range
Dim i As Long

q = Range("C2:C41") 'put the data into the array - *ALWAYS* 2 dimensions, even if a single column
For i = LBound(q) To UBound(q) ' use this, in case it's a dynamic array - 1 to 40 would have worked here
    Select Case q(i, 1) Mod 6 ' calculate remander
        Case 0 To 3
            q(i, 1) = q(i, 1) - (q(i, 1) Mod 6) 'make a multiple of 6
        Case 4 To 5
            q(i, 1) = q(i, 1) - (q(i, 1) Mod 6) + 6 ' and go higher in the later numbers
    End Select
Next i

Range("D2:D41") = q ' drop the data back

End Sub