我有一个sub在循环中大约5000次迭代后变得非常慢。 否则很快。
Windows 8.1 Pro 64位
Excel 2013(15.0.4701.1001)MSO(15.0.4701.1000)64位
Sub UnionSlow()
Dim ColArray() As Variant
Dim NumLastRow, NumRow, Cnt As Long
Dim CurCell As String
Dim rngPRC As Range
'Set an arbitrary row so range is not empty
Set rngPRC = Rows(1)
'Get the total number of rows in the sheet
TotalRows = Rows(Rows.Count).End(xlUp).Row
'Load the first column into an array (v quick)
ColArray = Range(Cells(1, 1), Cells(TotalRows, 1)).Value
'Now loop through the array and add ROWS to the RANGE depending on a condition
For NumRow = 1 To TotalRows
CurCell = ColArray(NumRow, 1)
If CurCell = "PRC" Then Set rngPRC = Union(rngPRC, Rows(NumRow))
Next NumRow
'Display a few things
MsgBox "Areas count " & rngPRC.Areas.Count
MsgBox "Address " & rngPRC.Address
MsgBox "Length array " & UBound(ColArray) & " items"
rngPRC.EntireRow.Font.Color = RGB(0, 0, 128)
End Sub
所以问题是这会非常快速地加载数组并且很快就会改变颜色。 减慢速度的是构建行的范围。 快达2000行(不到1秒) 最多5000行它更慢(约5秒) 在大约20000行,大约需要10分钟
我对VBA很新,所以请告诉我,如果我在这里愚蠢。
谢谢你的期待 安东尼答案 0 :(得分:0)
不是一次建立一行范围:
如果您的范围从上到下是连续的:
如果您的范围不连续:
这至少可以减少你必须做的工会数量。
答案 1 :(得分:0)
我根本不会使用循环 - 而是使用FIND。
如果您从Chip Pearsons网站复制 FindAll 代码:http://www.cpearson.com/excel/findall.aspx
然后,您可以使用此简短程序执行您之后的操作(从Chips网站复制并进行一些更改以使其适用于您:
Sub TestFindAll()
Dim SearchRange As Range
Dim FindWhat As Variant
Dim FoundCells As Range
Set SearchRange = Sheet1.Columns(1)
FindWhat = "PRC"
Set FoundCells = FindAll(SearchRange:=SearchRange, _
FindWhat:=FindWhat, _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByColumns, _
MatchCase:=False, _
BeginsWith:=vbNullString, _
EndsWith:=vbNullString, _
BeginEndCompare:=vbTextCompare)
If FoundCells Is Nothing Then
MsgBox "Value Not Found", vbOKOnly
Else
FoundCells.EntireRow.Font.Color = RGB(0, 0, 128)
End If
End Sub
通过删除与您的需求无关的代码,更新FindAll函数以更快地工作应该相当容易。
答案 2 :(得分:0)
我同意其中一条评论说自动过滤器在这种情况下会很好用。这是一个解决方案草案:
AutoFilterMode = False
TotalRows = Rows(Rows.Count).End(xlUp).Row
Set rngPRC = Range(Cells(1, 1), Cells(TotalRows, 1))
rngPRC.AutoFilter field:=1, Criteria1:="PRC"
If rngPRC.SpecialCells(xlCellTypeVisible).Count > 1 Then 'check if rows exist
Set rngPRC = rngPRC.Resize(rngPRC.Rows.Count - 1, 1).Offset(1, 0) _
.SpecialCells(xlCellTypeVisible).EntireRow
'perform your operations here:
rngPRC.Font.Color = RGB(0, 0, 128)
End If
AutoFilterMode = False