Как сделать цикл более эффективным в VBA? - PullRequest
0 голосов
/ 18 июня 2019

Я новичок в VBA и ищу что-то похожее на Python-панд, то есть избегаю циклически проходить по каждой строке много раз. Я пытаюсь выполнить довольно простую задачу, и это занимает слишком много времени. Какова лучшая альтернатива петлям?

Оглядываясь вокруг, кажется, что AutoFilter и Find могли бы подойти, однако я не уверен, какой вариант лучше в моем случае.

Sub UpdateManualUpdates()
    Dim lookUpSheet As Worksheet, updateSheet As Worksheet
    Dim valueToSearch As String
    Dim i As Long, t As Long

    Set lookUpSheet = Worksheets("Manual price changes")
    Set updateSheet = Worksheets("Price Build-up")

    lastRowLookup = lookUpSheet.Cells(Rows.Count, "F").End(xlUp).Row
    lastRowUpdate = updateSheet.Cells(Rows.Count, "B").End(xlUp).Row
    'get the number of the last row with data in sheet1 and in sheet2

    For i = 6 To lastRowLookup 'i = 2 to last to omit the first row as that row is for headers

        valueType = lookUpSheet.Cells(i, 5) 'Type of update - Both, Planning group or GC
        valueGroup = lookUpSheet.Cells(i, 3) 'Family group
        valueGC = lookUpSheet.Cells(i, 4) 'GC
        ValueChange = lookUpSheet.Cells(i, 6) 'What is the % change
        'above get the values from the four column into variables
        With Worksheets("Price build-up")
            For t = 6 To lastRowUpdate
                'AW is column 49 target column to update
                'M is target column for group, 13
                'C is target column for GC, 3
                If valueType = "Both" Then
                    If .Cells(t, 13) = valueGroup And .Cells(t, 3) = valueGC Then
                    .Cells(t, 49) = ValueChange
                    End If
                End If
                If valueType = "Planning group" Then
                    If .Cells(t, 13) = valueGroup Then
                    .Cells(t, 49) = ValueChange
                    End If
                End If
                If valueType = "GC" Then
                    If .Cells(t, 3) = valueGC Then
                    .Cells(t, 49) = ValueChange
                    End If
                End If
            Next t
        End With
    Next i
End Sub

1 Ответ

0 голосов
/ 18 июня 2019

Медленный доступ и обновление объекта Workbook.Исходя из того, что у вас есть, простой способ - преобразовать лист в массив и прочитать данные из массива.Кроме того, установите Application.ScreenUpdating = False, чтобы сделать это немного быстрее.

Sub UpdateManualUpdates()
    Application.ScreenUpdating = False
    Dim lookUpSheet As Worksheet, updateSheet As Worksheet
    Dim valueToSearch As String
    Dim i As Long, t As Long

    Set lookUpSheet = Worksheets("Manual price changes")
    Set updateSheet = Worksheets("Price Build-up")

    Dim lookUpSheetArray As Variant
    Dim updateSheetArray As Variant

    lastRowLookup = lookUpSheet.Cells(Rows.Count, "F").End(xlUp).Row
    lastRowUpdate = updateSheet.Cells(Rows.Count, "B").End(xlUp).Row

    lookUpSheetArray = lookUpSheet.Range("A1:F" & lastRowLookup).Value
    updateSheetArray = updateSheet.Range("A1:AW" & lastRowUpdate).Value

    For i = 6 To lastRowLookup 'i = 2 to last to omit the first row as that row is for headers

        valueType = lookUpSheetArray(i, 5) 'lookUpSheet.Cells(i, 5) 'Type of update - Both, Planning group or GC
        valueGroup = lookUpSheetArray(i, 3) 'Family group
        valueGC = lookUpSheetArray(i, 4) 'GC
        ValueChange = lookUpSheetArray(i, 6) 'What is the % change
        'above get the values from the four column into variables

        For t = 6 To lastRowUpdate
            'AW is column 49 target column to update
            'M is target column for group, 13
            'C is target column for GC, 3
            If valueType = "Both" Then
                If updateSheetArray(t, 13) = valueGroup And updateSheetArray(t, 3) = valueGC Then
                    updateSheet.Cells(t, 49) = ValueChange
                End If
            End If
            If valueType = "Planning group" Then
                If updateSheetArray(t, 13) = valueGroup Then
                    updateSheet.Cells(t, 49) = ValueChange
                End If
            End If
            If valueType = "GC" Then
                If updateSheetArray(t, 3) = valueGC Then
                    updateSheet.Cells(t, 49) = ValueChange
                End If
            End If
        Next t
    Next i
    Application.ScreenUpdating = True
End Sub

Из моего эксперимента это примерно на 35% быстрее.Не большое улучшение, но обновление займет всего минуту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...