Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel ActiveCell.Offset()和Range()之间的速度差?_Excel_Vba - Fatal编程技术网

Excel ActiveCell.Offset()和Range()之间的速度差?

Excel ActiveCell.Offset()和Range()之间的速度差?,excel,vba,Excel,Vba,总结:我循环了许多行的数据,每次循环都将来自不同列的数据存储在大约6个不同的变量中 问题:与ActiveCell.Offset(一些数字)相比,我是否会使用Range(“a”和某些迭代器)节省大量CPU周期?一个比另一个快多少 提前谢谢 出于纯粹的无聊和一点好奇,我为各种方法组装了一个粗略的计时器,以循环100000个Excel单元格 理想情况下,你应该每次跑几次,取平均值,但这会让你大致了解速度 在我的机器上,这就是我得到的 Option Explicit #If Win64 Then

总结:我循环了许多行的数据,每次循环都将来自不同列的数据存储在大约6个不同的变量中

问题:
ActiveCell.Offset(一些数字)
相比,我是否会使用
Range(“a”和某些迭代器)
节省大量CPU周期?一个比另一个快多少


提前谢谢

出于纯粹的无聊和一点好奇,我为各种方法组装了一个粗略的计时器,以循环100000个Excel单元格

理想情况下,你应该每次跑几次,取平均值,但这会让你大致了解速度

在我的机器上,这就是我得到的

Option Explicit

#If Win64 Then
    Public Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
    Public Declare Function GetTickCount Lib "kernel32" () As Long
#End If

Sub TestSpeedofReadingCells()
Dim tcStart As Long
Dim tcEnd As Long
Dim temp As Variant

Dim i As Long
Dim rngobject As Range
Dim rngItem As Range
Dim rngArray() As Variant
Const rowsToRead As Long = 100000


    '***Read individual cells using .Range
    With Sheet1
        tcStart = GetTickCount
        For i = 1 To rowsToRead
            temp = .Range("A" & i).Value
        Next i
        tcEnd = GetTickCount
        Debug.Print "Time1: " & tcEnd - tcStart
    End With

    '***Read individual cells using .Range & screenupdating off
    With Sheet1
        Application.ScreenUpdating = False
        tcStart = GetTickCount
        For i = 1 To rowsToRead
            temp = .Range("A" & i).Value
        Next i
        tcEnd = GetTickCount
        Application.ScreenUpdating = True
        Debug.Print "Time1a: " & tcEnd - tcStart
    End With

    '***Read individual cells using .Range & screenupdating off & using value2
    With Sheet1
        Application.ScreenUpdating = False
        tcStart = GetTickCount
        For i = 1 To rowsToRead
            temp = .Range("A" & i).Value2
        Next i
        tcEnd = GetTickCount
        Application.ScreenUpdating = True
        Debug.Print "Time1b: " & tcEnd - tcStart
    End With

    '***Read individual cells using range object
    With Sheet1
        Set rngobject = .Range("A1:A" & rowsToRead)
        tcStart = GetTickCount
        For Each rngItem In rngobject
            temp = rngItem
        Next rngItem
        tcEnd = GetTickCount
        Debug.Print "Time2: " & tcEnd - tcStart
    End With

    '***Read individual cells using activecell
    With Sheet1
        tcStart = GetTickCount
        .Range("A1").Select
        For i = 1 To rowsToRead
            temp = ActiveCell.Offset(i - 1, 0).Value
        Next i
        tcEnd = GetTickCount
        Debug.Print "Time3: " & tcEnd - tcStart
    End With

    '***Read individual cells using activecell & screenupdating off
    With Sheet1
        Application.ScreenUpdating = False
        tcStart = GetTickCount
        .Range("A1").Select
        For i = 1 To rowsToRead
            temp = ActiveCell.Offset(i - 1, 0).Value
        Next i
        tcEnd = GetTickCount
        Application.ScreenUpdating = True
        Debug.Print "Time3a: " & tcEnd - tcStart
    End With

    '***Read individual cells using array
    With Sheet1
        tcStart = GetTickCount
        rngArray = .Range("A1:A" & rowsToRead).Value
        For i = 1 To rowsToRead 'should really use Lbound to Ubound but only example
            temp = rngArray(i, 1)
        Next i
        tcEnd = GetTickCount
        Debug.Print "Time4: " & tcEnd - tcStart
    End With

End Sub


出于纯粹的无聊和一点好奇,我为各种方法组装了一个粗略的计时器,以循环100000个Excel单元格

理想情况下,你应该每次跑几次,取平均值,但这会让你大致了解速度

在我的机器上,这就是我得到的

Option Explicit

#If Win64 Then
    Public Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
    Public Declare Function GetTickCount Lib "kernel32" () As Long
#End If

Sub TestSpeedofReadingCells()
Dim tcStart As Long
Dim tcEnd As Long
Dim temp As Variant

Dim i As Long
Dim rngobject As Range
Dim rngItem As Range
Dim rngArray() As Variant
Const rowsToRead As Long = 100000


    '***Read individual cells using .Range
    With Sheet1
        tcStart = GetTickCount
        For i = 1 To rowsToRead
            temp = .Range("A" & i).Value
        Next i
        tcEnd = GetTickCount
        Debug.Print "Time1: " & tcEnd - tcStart
    End With

    '***Read individual cells using .Range & screenupdating off
    With Sheet1
        Application.ScreenUpdating = False
        tcStart = GetTickCount
        For i = 1 To rowsToRead
            temp = .Range("A" & i).Value
        Next i
        tcEnd = GetTickCount
        Application.ScreenUpdating = True
        Debug.Print "Time1a: " & tcEnd - tcStart
    End With

    '***Read individual cells using .Range & screenupdating off & using value2
    With Sheet1
        Application.ScreenUpdating = False
        tcStart = GetTickCount
        For i = 1 To rowsToRead
            temp = .Range("A" & i).Value2
        Next i
        tcEnd = GetTickCount
        Application.ScreenUpdating = True
        Debug.Print "Time1b: " & tcEnd - tcStart
    End With

    '***Read individual cells using range object
    With Sheet1
        Set rngobject = .Range("A1:A" & rowsToRead)
        tcStart = GetTickCount
        For Each rngItem In rngobject
            temp = rngItem
        Next rngItem
        tcEnd = GetTickCount
        Debug.Print "Time2: " & tcEnd - tcStart
    End With

    '***Read individual cells using activecell
    With Sheet1
        tcStart = GetTickCount
        .Range("A1").Select
        For i = 1 To rowsToRead
            temp = ActiveCell.Offset(i - 1, 0).Value
        Next i
        tcEnd = GetTickCount
        Debug.Print "Time3: " & tcEnd - tcStart
    End With

    '***Read individual cells using activecell & screenupdating off
    With Sheet1
        Application.ScreenUpdating = False
        tcStart = GetTickCount
        .Range("A1").Select
        For i = 1 To rowsToRead
            temp = ActiveCell.Offset(i - 1, 0).Value
        Next i
        tcEnd = GetTickCount
        Application.ScreenUpdating = True
        Debug.Print "Time3a: " & tcEnd - tcStart
    End With

    '***Read individual cells using array
    With Sheet1
        tcStart = GetTickCount
        rngArray = .Range("A1:A" & rowsToRead).Value
        For i = 1 To rowsToRead 'should really use Lbound to Ubound but only example
            temp = rngArray(i, 1)
        Next i
        tcEnd = GetTickCount
        Debug.Print "Time4: " & tcEnd - tcStart
    End With

End Sub


看起来这很容易测试,但我猜这不会有任何明显的区别(只要你不是真的选择每个单元格)。编辑:确定-第二个版本在覆盖100k单元格的范围内速度快2-3倍。在许多情况下,将范围加载到阵列并循环阵列会更快。读取/写入工作表通常是最慢的操作,因此请尽可能尝试每种操作中的一种。@TimWilliams你所说的第二种版本是什么意思?@Mike-你给出了两个引用单元格的示例(版本)-我指的是第二种。我使用100k行测试了每种方法的一个简单循环:只检查单元格中的值,没有执行任何其他操作。您的实际代码是什么?通常,使用
Find
AutoFilter
SpecialCells
可以避免慢循环,或者根据ooo的评论,Arrays似乎很容易测试,但我猜这不会产生任何明显的差异(只要您没有实际选择每个单元格)。编辑:确定-第二个版本在覆盖100k单元格的范围内速度快2-3倍。在许多情况下,将范围加载到阵列并循环阵列会更快。读取/写入工作表通常是最慢的操作,因此请尽可能尝试每种操作中的一种。@TimWilliams你所说的第二种版本是什么意思?@Mike-你给出了两个引用单元格的示例(版本)-我指的是第二种。我使用100k行测试了每种方法的一个简单循环:只检查单元格中的值,没有执行任何其他操作。您的实际代码是什么?通常,可以使用
Find
AutoFilter
SpecialCells
或根据ooo的评论,使用数组+1来避免慢循环。很好的回答,我不知道这些差异有多快。在未来的所有应用程序中肯定会使用后者,而不是扫描。看起来案例2和案例4甚至不会在循环中得到值。这似乎有助于解释为什么会有如此大的差异。很好的回答,我不知道这些差异有多快。在未来的所有应用程序中肯定会使用后者,而不是扫描。看起来案例2和案例4甚至不会在循环中得到值。这似乎有助于解释为什么会有如此大的差异。