VBA 2010:关于编码实践的建议,以加快循环

时间:2015-01-30 21:05:05

标签: arrays excel vba loops for-loop

我在脚本的一部分中有一个循环,它运行得非常慢。我希望得到一些改进的建议。

我有8对数据集。每对由一个数组(一维,通常为400个字符串元素)和一个通常约为2000个字符串元素的列组成。在每对数据集中,我想根据列的每个元素检查数组的每个元素以进行匹配。这是我的方法的简化版本:

For i = 1 to 8
    For j = 0 to 400
        For k = 0 to 2000
           If Cells(k,i) = myArray[1, then 2, then 3, etc.](j) then [action]
        next K
    next j
next i

通过以上操作,我循环通过A列的第一个2000个单元400次,然后是B列的第一个2000个单元400次,依此类推。这看起来非常多余,并且检查了大约640万个单元,这需要永远。我希望有更好的方法可以做到这一点,并希望有人能够启发我。

如果有必要,我可以向您展示实际的代码并解释它所做的所有事情,但它有点冗长。

编辑:这是实际代码。它正在寻找具有合格布尔值的dupes。当满足这些条件时,它会获取相关的整数值和行号。它将所有整数值相加,并用它们的总和替换这些整数。它为每个唯一的名称执行此操作,然后(未显示)对剩余的7个数据集重复此操作。

    For i = 0 To j - 1 'starts with the first unique element and searches for dupes...
        v = 0 'initial qty value 
        r = 0 'initial number of rows with dupes
        For k = 2 To WULastRow 'go though each cell in the first column
            If Cells(k, colPair + 2) = True And Cells(k, colPair).Text = uniqueNames(i) Then '...if one is found and the row's boolean is true...
                v = v + Cells(k, colPair + 1).Value '...sum it's qty with previous dupes qty's...
                r = r + 1 'increment number of dupes found
                ReDim Preserve rngMatch(r - 1) 'increase the size of the array that will hold the row numbers of the dupes.
                rngMatch(r - 1) = k '...and input dupe's row number to said array.
            End If
        Next k

        k = 0

        'if 1 or more duplicate is found for the given unique item name is found...
        If r > 1 Then
            k = 0
            For k = 0 To r - 1
                Cells(rngMatch(k), colPair + 1).Value = v '...input the summed quantity in their qty cells...
            Next k
        End If
    Next i 'then regardless, move on to the name unique name and repeat this process.

2 个答案:

答案 0 :(得分:2)

每次访问Cell(i,j)时都会有很大的开销

您需要通过使用单个语句将数据转换为变量arry,然后循环数组,然后根据需要将其放回来避免这种情况:这是一些演示代码

Option Base 1
dim vArr as variant
varr=Range("A1").resize(Lastrow,LastCol).Value2
for j=1 to LastRow
for k=1 to LastCol
if vArr(j,k) .... then Varr(j,k)= ...
next k
next j
Range("A1").resize(Lastrow,LastCol)=Varr

答案 1 :(得分:1)

您需要做的是实现某种变量排序启发式,以便在矩阵中排序元素(从最低到最高等)。这是一个让你入门的例子:

如果我有一个数组a = [1,8,16](最少排序)和另一个数组b = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16](再次排序),我可以引入一个规则,即每次搜索迭代都发生在最后一次搜索的结束位置。这是我的意思:

index = 0
for i in a:
   for j in range(index, len(b)):
      if a == b:
          do something
          index = j

这有效地做了什么,允许您在每次匹配值时搜索迭代越来越小的空间。希望这是有道理的 - 将变量排序排序应用到b矩阵可能会很困难。