2009-11-02 178 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個字符)。區域數量在兩種情況下都是相同的。