Я уже разрешил несколько других, используя Application.Index
с Application.WorksheetFunction.Match
и уменьшил время выполнения с 7-8 секунд до миллисекунд. Но я чувствую, что есть еще возможности для улучшения.
Должен ли я использовать массив с Index
и Match
?
Мне также сказали использовать Scripting.Dictionary
, но я ищу человека, который сможет продемонстрировать, как сделать это правильно в этом сценарии. Потому что в моей голове я должен заполнить словарь циклом, прежде чем я смогу его использовать, поэтому не будет ли он похожим по скорости?
'Production Quantity for Dashboard
For i = 2 To Total_rows_Prod
For j = 2 To Total_rows_Dash
If ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 5) = ThisWorkbook.Worksheets("Dashboard").Cells(j, 1) Then
ThisWorkbook.Worksheets("Dashboard").Cells(j, 4) = ThisWorkbook.Worksheets("Dashboard").Cells(j, 4) + ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 31) / ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 4)
End If
Next j
Next i
После выполнения некоторых узких мест использование вложенного цикла for-next
, как известно, является чрезвычайно медленным и плохим занятием, как показано ниже (время выполнения кода показано в строке 10):

Однако при использовании Index
и Match
при использовании только петли 1 for-next
, как показано в приведенном ниже коде:
'Production Quantity for Dashboard
For i = 2 To Total_rows_Prod
m = Application.Match(ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 5), ThisWorkbook.Worksheets("Dashboard").Range("A:A"), 0)
If Not IsError(m) Then
ThisWorkbook.Worksheets("Dashboard").Cells(Application.WorksheetFunction.Match(ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 5), ThisWorkbook.Worksheets("Dashboard").Range("A:A"), 0), 4) = ThisWorkbook.Worksheets("Dashboard").Cells(Application.WorksheetFunction.Match(ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 5), ThisWorkbook.Worksheets("Dashboard").Range("A:A"), 0), 4) + ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 31) / ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 4)
End If
Next i
Время выполнения будет незначительным, как показано ниже (все еще в строке 10):

В последний раз (по состоянию на 21.01.19) я смог запустить все с заменами Index
и Match
: 2 секунды:

На более медленном нетбуке с процессором Pentium Atom выполнение того же кода занимает 26 секунд (в 13 раз больше). Поэтому мне интересно, есть ли способ сбить эти 26 секунд.
Любые улучшения, которые позволили бы минимизировать время выполнения, были бы великолепны. Надеюсь, сделаем это максимально быстрым.
Обновление от 23.02.19 (пересмотр кода):
Dim rangeProdQtySum As Range, rangeProdQtyPass As Range
Set rangeProdQtySum = ThisWorkbook.Worksheets("Prod. Qty.").Range("AE1:AE" & Total_rows_Prod)
Set rangeProdQtyPass = ThisWorkbook.Worksheets("Prod. Qty.").Range("D1:D" & Total_rows_Prod)
ReDim arrProdQtySum(1 To Total_rows_Prod) As Variant
ReDim arrProdQtyPass(1 To Total_rows_Prod) As Variant
arrProdQtySum = rangeProdQtySum
arrProdQtyPass = rangeProdQtyPass
ReDim arrProdQtyDash(1 To Total_rows_Dash) As Variant
'Production Quantity for Dashboard
For i = 2 To Total_rows_Prod
m = Application.Match(arrProdQtyJTJN(i, 1), Application.Index(Application.WorksheetFunction.Transpose(arrDashInfo), 0, 1), 0)
If Not IsError(m) Then
arrProdQtyDash(Application.Match(arrProdQtyJTJN(i, 1), Application.Index(Application.WorksheetFunction.Transpose(arrDashInfo), 0, 1), 0)) = arrProdQtyDash(Application.Match(arrProdQtyJTJN(i, 1), Application.Index(Application.WorksheetFunction.Transpose(arrDashInfo), 0, 1), 0)) + arrProdQtySum(i, 1) / arrProdQtyPass(i, 1)
End If
Next i
arrProdQtyDash(1) = "Production Quantity"
ThisWorkbook.Worksheets("Dashboard").Range("D1:D" & Total_rows_Dash) = Application.WorksheetFunction.Transpose(arrProdQtyDash)
Для массивов, минимизирующих использование циклов for-next
, используйте index
и match
с комбинациями для arrays
и запоминание переменных (присвоение ссылок на переменную), таймер выглядит следующим образом:

Тот же набор кодов, который я пробовал на более медленном компьютере с атомом Pentium, занимает 10 секунд, чтобы выполнить тот же код, как показано ниже:

Это примерно в 2,6 раза быстрее, чем просто использование индексов и кодов совпадений. Мне интересно, есть ли какие-либо улучшения, которые можно предложить для фрагмента кода, отображаемого здесь, потому что это узкое место (для выполнения атома pentium требуется 5 секунд или около 50% времени обработки).