有人可以帮我优化excel中的VBA循环

时间:2014-08-03 17:09:35

标签: excel vba excel-vba

我的工作表有6000行。这个循环花了我超过20分钟才完成。这对我来说太长了,因为我有很多列来运行这个循环。有人能帮助我吗?

Dim i As Integer
For i = ActiveCell.Row To 5771
If Cells(i, ActiveCell.Column - 1).Value = 0 And Cells(i, ActiveCell.Column).Value = "" Then
Cells(i, ActiveCell.Column).Value = 0
ElseIf Cells(i, ActiveCell.Column - 1).Value = 1 Then
Range(Cells(i, ActiveCell.Column), Cells(i + 9, ActiveCell.Column)).Value = 1
ElseIf Cells(i, ActiveCell.Column - 1).Value = -1 Then
Range(Cells(i, ActiveCell.Column), Cells(i + 9, ActiveCell.Column)).Value = -1
End If
Next i

1 个答案:

答案 0 :(得分:2)

很难确切地说出你正在尝试做什么。您正在使用的循环结构效率非常低:您在一个范围内循环,并对每个单元格执行一些评估/逻辑测试。

如果相邻(左侧)单元格的值为1或-1,那么您将使用该值填充单元格接下来的9个单元格。但是当你点击循环中的Next时,你将对这些单元格进行测试。所以,要么你不应该填充10行的值,要么你应该避免测试那些行,因为可能没有什么需要用它们来做(否则你不应该首先填充它们!)所以你可以看到为什么我有点困惑。

在任何情况下,我都假设您不需要在Cells(i, ActiveCell.Column - 1).Value = 1Cells(i, ActiveCell.Column - 1).Value = -1下测试9行。

我没有测试其中任何一个,所以他们可能会有一些拼写错误等等。

最快的方法是仅对内存中的yoru数据执行操作。您可以将范围值存储在数组中,并对数组执行操作,然后"写"值在单个语句中返回到工作表。在内存中循环比在工作表上循环和写入要快得多。

Dim rng as Range
Dim arr as Variant
Dim val as Variant
Dim r as Long, i As Integer

Set rng = Range(Cells(ActiveCell.Row, ActiveCell.Column -1).Address, Cells(5771, ActiveCell.Column).Address)

'store the range values in a variant array:
' this will be of the structure arr(_row#_, _column#_)
arr = rng.Value

For r = 1 to UBound(arr, 1)  'Loop until last row in range/array
    'arr(r,1) represents the first column of the range -- i.e., the column to left of ActiveCell
    ' so we can use a Case statement to check this value of either 0, 1, or -1.
    Select Case arr(r, 1)
        Case 0
            'if the adjacent left cell = 0 AND this cell's value = ""
            ' then make this cell's value = 0. 
            If arr(r, 2) = "" Then arr(r, 2) = 0
        Case 1, -1
            For i = 0 to 10
            'if the value is 1 or -1, puts the in this cell AND the next 9 cells
                arr(r + i, 2) = arr(r, 1)
            Next
            'increment our iterator variable
            r = r + 9
        Case Else
            'Do nothing...
    End Select
Next

'put the transformed values in to the worksheet
rng.Value = arr

这与此基本相同,它使用循环中的工作表对象/单元格。它更接近你的循环,但它的效率也会低于上述。

'Alternatively, but this will be slower:
Dim rng as Range
Dim cl as Range
Dim i as Integer

Set rng = Range(Cells(ActiveCell.Row, ActiveCell.Column -1).Address, Cells(5771, ActiveCell.Column).Address)

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

For each cl in rng.Cells
    With cl
        Select Case .Offset(0, -1).Value
             Case 0
                 If .Value = "" Then .Value = 0
             Case 1, -1
                 .Resize(10,1).Value = .Offset(0, -1).Value
             Case Else
                 'Do nothing
        End Select
    End With
Next

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic