2014-07-09 147 views
0

我有一組以下列格式的數據,雖然非常簡化:比較兩個數據集 - 慢速

  • DealerName,AccountCode,價值
  • Dealer1,A-1,5
  • Dealer2,A -1,10
  • Dealer1,A-2,20
  • Dealer2,A-2,15
  • Dealer3,A-3,5

我想實現一個最終的結果,讓我通過AccountCode總結的數據,因此,在上述數據的情況下執行以下操作:

  • AccountCode,價值
  • A-1,15
  • A-2,35
  • A-3,5

我已經通過創建的命名OutputData不同帳戶代碼的陣列,然後通過比較所述數據去完成這個帳戶代碼相同的場中SelectedDealerData並將其添加到現有的值:

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帳戶代碼,所以這意味着很多不必要的循環的。

有人能指出我的方向更有效的解決方案嗎?我在想某種字典比較,但我不確定如何實現它。

+0

這是在Excel/Access中嗎?如果它在Excel中,爲什麼不使用像'= SUMIFS'這樣的工作表函數 – Gareth

回答

1

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 
0

的代碼是緩慢的,因爲有1000萬間的比較和賦值操作在這裏(10,000×1000)正在進行。

此外,通過集合循環並不是非常有效,但由於設計已經按照原樣設置和維護,因此無法做到這一點。

有兩種方法可以提高效率(您可以立即計算代碼並在執行這些步驟後查看節省的成本)。

  1. 有兩個條件檢查進行And。即使第一個虛假(不短路),VBA也會進行評估。因此,嵌套if then條件,以便如果第一個條件失敗,您不會繼續檢查第二個條件。此外,保持條件更可能在外部if語句失敗(所以它快速失敗並移動到下一個元素)。最好的情況是,你在這裏會遇到一個小的速度顛簸,最糟糕的是,你並沒有更糟。

  2. 這裏發生了太多的比較。如果您可以對您的集合進行排序或創建一個索引來維護它們的排序順序(如果您喜歡,可以在電子表格中保存該索引數組),但是您可以根據以下僞代碼查看循環。排序應該基於名爲Account_Number_Year的複合字段完成(只是連接它們)

  3. 您可以在Alex K.建議的字典結構中使用此連接字段。因此,您可以在第二個字典中查找此聯合字段,然後如果需要做操作。

代碼,以嘗試在VBA充分實現它:

'Assuming both arrays are sorted 
For i = 0 to Ni 
    MatchingIndex = _ 
     BinarySearchForAccNumberYear(SelectedUserData(i).AccountNumberYear) 
Next i 

你可以看一下二進制搜索here

這會將您的時間複雜度從O(n^2)降低到O(n log n),並且您的代碼將以更快的速度運行一個數量級。