Arrays 比较两个数据集-慢

Arrays 比较两个数据集-慢,arrays,vba,dictionary,collections,Arrays,Vba,Dictionary,Collections,我有以下格式的一组数据,尽管非常简化: DealName、AccountCode、Value 经销商1,A-1,5 经销商2,A-1,10 经销商1,A-2,20 经销商2,A-2,15 经销商3,A-3,5 我正在尝试实现一个最终结果,该结果将提供AccountCode汇总的数据,因此,对于上述数据,请执行以下操作: 会计代码、价值 A-1,15 A-2,35 A-3,5 为此,我创建了一个名为OutputData的不同账户代码数组,然后将账户代码与selectedDelerData中

我有以下格式的一组数据,尽管非常简化:

  • DealName、AccountCode、Value
  • 经销商1,A-1,5
  • 经销商2,A-1,10
  • 经销商1,A-2,20
  • 经销商2,A-2,15
  • 经销商3,A-3,5
我正在尝试实现一个最终结果,该结果将提供AccountCode汇总的数据,因此,对于上述数据,请执行以下操作:

  • 会计代码、价值
  • A-1,15
  • A-2,35
  • A-3,5
为此,我创建了一个名为
OutputData
的不同账户代码数组,然后将账户代码与
selectedDelerData
中的相同字段进行比较,并将其添加到现有值中:

For i = 0 To UBound(SelectedDealerData)
    For j = 0 To UBound(OutputData)
        If SelectedDealerData(i).AccountNumber = OutputData(j).AccountNumber And SelectedDealerData(i).Year = OutputData(j).Year Then
            OutputData(j).Units = OutputData(j).Units + SelectedDealerData(i).Units
            Exit For
        End If
    Next j
Next i
大约有10,00个经销商,每个经销商有600-1000个帐户代码,因此这意味着大量不必要的循环

有人能告诉我一个更有效的解决方案吗?我在想某种字典可以比较,但我不确定如何实现它

为字典添加对Microsoft脚本运行时的引用:

    Dim aggregated As Dictionary
    Set aggregated = New Dictionary

    For i = 0 To UBound(SelectedDealerData)
        With SelectedDealerData(i)
            If aggregated.Exists(.AccountCode) Then
                aggregated(.AccountCode) = aggregated(.AccountCode) + .Value
            Else
                aggregated(.AccountCode) = .Value
            End If
        End With
    Next

    For Each Key In aggregated.Keys
        Debug.? Key, aggregated(Key)
    Next

代码很慢,因为这里正在进行1000万次比较和赋值操作(10000 x 1000)

此外,在集合中循环也不是很有效,但由于设计已经按原样进行了设置和维护,因此对此无能为力

有两种方法可以提高效率(您可以立即对代码计时,并在执行这些步骤后看到节省的百分比)

  • 有两种情况检查。即使第一个为假(无短路),VBA也会对这两个进行评估。因此,设置嵌套的
    if-then
    条件,这样,如果第一个条件失败,就不会继续检查第二个条件。另外,在外部
    if
    语句中保持条件更有可能失败(这样它会快速失败并移动到下一个元素)。在最好的情况下,你会在这里遇到一个小的减速,在最坏的情况下,你的情况也不会更糟

  • 这里有太多的比较。现在改变这一点已经太迟了,但是如果您可以对集合进行排序,或者构建一个保持其排序顺序的索引(如果愿意,可以将该索引数组保存在电子表格上),则可以基于以下伪代码遍历循环。排序应该基于一个名为Account\u Number\u Year的复合字段进行(只需将它们连接起来)

  • 您可以在Alex K建议的字典结构中使用此连接字段。因此,您可以在第二个字典中查找此联合字段,然后根据需要执行操作

  • 尝试在VBA中完全实现它的代码:

    'Assuming both arrays are sorted
    For i = 0 to Ni
        MatchingIndex = _
            BinarySearchForAccNumberYear(SelectedUserData(i).AccountNumberYear)
    Next i
    
    你可以查二进制搜索


    这将使时间复杂度从O(n^2)降低到O(n log n),代码运行速度将提高一个数量级。

    这是Excel/Access中的吗?如果它在Excel中,为什么不使用像
    =SUMIFS