如何在VBA中使for循环更有效?

时间:2019-06-18 00:29:41

标签: excel vba

我是VBA的新手,我正在寻找类似于python pandas的东西,即避免多次遍历每行。我正在尝试完成一个非常简单的任务,并且花费的时间太长。循环的最佳替代方法是什么?

环顾四周,似乎“自动筛选”和“查找”可能起作用,但是我不确定哪种情况下最好的选择。

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 :(得分:0)

访问和更新工作簿对象很慢。根据现在的情况,一种简单的方法是将工作表转换为数组并从数组中读取数据。同样,将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%。并不是很大的改进,但是只需花费一分钟即可更新。