2009-11-02 148 views
4

有一些什么限制,我可以在通过VBA的范围内选择?基本上我发现的是,如果我是隐藏整个行,而在一个循环时,会如果有大量的行隐藏的相当长一段时间。范围限制的难题

前) - 隐藏不具有在列值的任何行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设置。

我现在遇到的问题是,如果该范围的字符串引用太长,它只是失败。

下面的代码声明它接受行号的一个标准数组(如果该数组手之前进行),以及参数的参数(如果你不想手之前声明数组的功能,并且行的列表很小)。然后它创建一个在范围参考中使用的字符串。

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秒

回答

6

我觉得神奇功能,你是在寻找这里是联盟()。它的建成到Excel VBA,所以看帮助它。它不只是你所期望。

通过您的范围循环,但不建立一个字符串,建立一个多区域范围。然后,您可以一次选择或设置整个属性。

我不知道什么(如果有的话)在一个范围内可以建立的区域数量的限制是,但是它大于600.我不知道有什么限制(如果有的话)在选择或设置多区域范围的属性时,但它可能值得一试。

+0

完美!谢谢一堆。 – JakeTheSnake 2009-11-02 21:03:55

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细胞内的工作,我想。

+0

也非常有帮助;尽管我对空单元格的搜索是偶然的。 – JakeTheSnake 2009-11-03 13:57:39

+0

糟糕。无论如何,在进一步调查中,通过SpecialCells属性添加到一个范围内的非连续单元格的数量似乎有一个限制(8,192),请参阅MS知识库文章编号832293.因此,即使这是您的问题,您的解决方案可能会遇到困难。 – dendarii 2009-11-03 16:38:14

2

可以,如果你rowHeight属性设置为0。 在我的系统中获得A小调加速它去两次快速 (6000上反复1.17秒,而2.09秒)

你没有提到什么“相当长的一段”是的,你使用的是什么版本的XL的......

你的问题可能是部分的行检测检查要隐藏行代码(?)。

下面是2003 XL我的测试代码(注释掉一个版本,然后其他):

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 
+0

非常好!使用Union和RowHeight的组合,现在宏运行速度非常快。代码修改在OP中更新。 – JakeTheSnake 2009-11-06 21:47:35

1

有字符串长度的限制。我刚刚遇到类似问题,发现如果 范围(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 

抛出而代码

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”,而不错误的错误(在串256个字符)。区域数量在两种情况下都是相同的。