Ок, ответ в значительной степени основан на этом недавнем ответе, который я дал. В этой теме есть еще один умный ответ от @DisplayName, который вы, возможно, захотите использовать, но здесь я рассмотрю понятный способ использования модуля класса и словаря.
Давайте предположим следующеевведите данные, начиная с A1
:
| 1 | 2 | 1 | 5 |
| 2 | 3 | 2 | 5 |
| 2 | 6 | 2 | 5 |
| 1 | 2 | 3 | 4 |
| 5 | 4 | 1 | 2 |
Сначала создайте модуль class
и назовите его, например: clssList
со следующим кодом:
Public Col1 As Variant
Public Col2 As Variant
Public Col3 As Variant
Public Col4 As Variant
Второй создайте модуль и вставьте в него следующий код:
Sub BuildList()
Dim x As Long, arr As Variant, lst As clssList
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
'Fill array variable from sheet
With Sheet1
x = .Cells(.Rows.Count, 1).End(xlUp).Row
arr = .Range("A1:D" & x).Value
End With
'Load array into dictionary with use of class
For x = LBound(arr) To UBound(arr)
If Not dict.Exists(arr(x, 1) & "|" & arr(x, 2)) Then
Set lst = New clssList
lst.Col1 = arr(x, 1)
lst.Col2 = arr(x, 2)
lst.Col3 = arr(x, 3)
lst.Col4 = arr(x, 4)
dict.Add arr(x, 1) & "|" & arr(x, 2), lst
Else 'In case column 2 is the same then add the values to the lst object
dict(arr(x, 1) & "|" & arr(x, 2)).Col3 = dict(arr(x, 1) & "|" & arr(x, 2)).Col3 + arr(x, 3)
dict(arr(x, 1) & "|" & arr(x, 2)).Col4 = dict(arr(x, 1) & "|" & arr(x, 2)).Col4 + arr(x, 4)
End If
Next x
'Transpose dictionary into sheet3
With Sheet1
x = 1
For Each Key In dict.Keys
.Cells(x, 6).Value = dict(Key).Col1
.Cells(x, 7).Value = dict(Key).Col2
.Cells(x, 8).Value = dict(Key).Col3
.Cells(x, 9).Value = dict(Key).Col4
x = x + 1
Next Key
End With
End Sub
Это немного обширно, но я написал так, что будет легкопонять, что происходит. Это должно быть очень быстро для 20000 записей.
Приведенные выше результаты приводят к матрице, начиная с диапазона F1
, которая выглядит следующим образом:
Выполнение теста скорости на 100 000 строк вернуло общее истекшее время около 3,4 секунды. 20.000 записей сократились до 1,8 секунд.
Другой, более короткий (записанный код, а не скорость) способ состоит в том, чтобы не использовать модуль класса и объединять элементы массива (с небольшим риском того, что используемый вами разделитель существует в значении). Пример показан в ссылке сверху. И я просто вижу, что @RonRosenFeld приводит пример того, как использовать именно это.