我可以通过VBA在一个范围内选择一些限制吗?基本上我发现如果我在循环中隐藏整行,如果要隐藏很多行,则需要很长时间。
ex) - 隐藏A列中没有值的任何行
For i = 1 to 600
With Range("A" & i)
If .value = vbEmpty then .EntireRow.Hidden = True
End With
Next
更快速的方法是创建一个引用每个行的单个范围,然后执行单个“.entirerow.hidden = true”语句。是的,我已经有了application.screenupdating = false set。
我遇到的问题是,如果范围的字符串引用太长,它就会失败。
下面的代码声明了一个函数,它接受一个标准的行号数组(如果数组是在手工制作的情况下),以及参数参数(如果你不想在手工之前声明一个数组,并且行列表很小)。然后它创建一个在范围引用中使用的字符串。
Function GetRows(argsArray() As Long, ParamArray args() As Variant) As Range
Dim rngs As String
Dim r
For Each r In argsArray
rngs = rngs & "," & r & ":" & r
Next
For Each r In args
rngs = rngs & "," & r & ":" & r
Next
rngs = Right(rngs, Len(rngs) - 1)
Set GetRows = Range(rngs)
End Function
Function dfdfd()
Dim selList(50) As Long, j As Long
For i = 1 To 100
If i Mod 2 = 1 Then
selList(j) = i
j = j + 1
End If
Next
selList(50) = 101
GetRows(selList).Select
End Function
第二个函数“dfdfd”仅用于给出失败时的示例。要查看它的工作原理,只需创建一个包含5个项目的新数组,然后尝试。它有效。
最终(?)更新:
Option Explicit
Public Sub test()
Dim i As Integer
Dim t As Long
Dim nRng As Range
t = Timer()
Application.ScreenUpdating = False
Set nRng = [A1]
For i = 1 To 6000
Set nRng = Union(nRng, Range("A" & i))
Next
nRng.RowHeight = 0
'nRng.EntireRow.Hidden = true
Application.ScreenUpdating = True
Debug.Print "Union (RowHeight): " & Timer() - t & " seconds"
'Debug.Print "Union (EntireRow.Hidden): " & Timer() - t & " seconds"
End Sub
结果:
联盟(行高:0.109375秒
联盟(隐藏行):0.625秒
答案 0 :(得分:6)
我认为你在这里寻找的神奇功能是Union()。它内置于Excel VBA中,请查看它的帮助。它完全符合您的期望。
遍历您的范围,但不是构建字符串,而是构建一个多区域范围。然后,您可以一次选择或设置整个事物的属性。
我不知道在一个范围内你可以建立的区域数量是多少(如果有的话),但它大于600.我不知道有什么(如果有的话)限制选择或设置多区域范围的属性,但它可能值得一试。
答案 1 :(得分:2)
更快的选择可能是使用SpecialCells属性查找空白然后隐藏行:
Sub HideRows()
Dim rng As Range
Set rng = ActiveSheet.Range("A1:A600")
Set rng = rng.SpecialCells(xlCellTypeBlanks)
rng.EntireRow.Hidden = True
End Sub
我认为这只适用于UsedRange中的单元格。
答案 2 :(得分:2)
如果将RowHeight属性设置为0,则可以获得次要加速。 在我的系统上它的速度提高了一倍 (6000次迭代约1.17秒对2.09秒)
你没有提到“很长一段时间”是什么,以及你正在使用的XL版本......
您的问题可能部分是行检测代码,用于检查您要隐藏的行(?)。
这是我在XL 2003中的测试代码(注释掉一个版本然后另一个版本):
Option Explicit
Public Sub test()
Dim i As Integer
Dim t As Long
t = Timer()
Application.ScreenUpdating = False
For i = 1 To 6000
With Range("A" & i)
'If .Value = vbEmpty Then .EntireRow.Hidden = True
If .Value = vbEmpty Then .RowHeight = 0
End With
Next
Application.ScreenUpdating = True
Debug.Print Timer() - t & " seconds"
End Sub
答案 3 :(得分:1)
字符串长度有限制。我刚刚遇到类似的问题,发现如果是String Txt的话 范围(TXT) 大于255个字符,我的VBA抛出一个Error.eg。代码:
Debug.Print sheet1.Range("R2300,T2300,V2300,R2261,T2261,V2261,R1958,T1958,V1958,R1751,T1751,V1751,R1544,T1544,V1544,R1285,T1285,V1285,R1225,T1225,V1225,R1193,T1193,V1193,R1089,T1089,V1089,R802,T802,V802,R535,T535,V535,R264,T264,V264,R205,T205,V205,R168,T168,V168,R135,T135,V135,R101").Areas.count
抛出错误(字符串中有256个字符),而代码
Debug.Print sheet1.Range("R230,T2300,V2300,R2261,T2261,V2261,R1958,T1958,V1958,R1751,T1751,V1751,R1544,T1544,V1544,R1285,T1285,V1285,R1225,T1225,V1225,R1193,T1193,V1193,R1089,T1089,V1089,R802,T802,V802,R535,T535,V535,R264,T264,V264,R205,T205,V205,R168,T168,V168,R135,T135,V135,R101").Areas.count
有255个字符并打印出来" 46"没有错误。在两种情况下,区域数量都相同。