我希望能夠在過濾的表格中找到連續行的最大可見區域。我知道一種可能的方式是使用「xlCellTypeVisible」屬性循環可見單元格並計算每個可見區域中的單元格。然而,這些數據由數十個甚至數十萬個行組成,所以我想知道是否有更快,更有效的方法來做到這一點。在已過濾的範圍內查找可見單元格的最大範圍
0
A
回答
1
幾個月前,我有一個模糊的相似要求,對我發現的最佳解決方案感到不滿。盯着你的問題,我突然想到了兩種新技術。下面的宏展示了兩者。雖然我無法想象技術2不是更快的情況,但兩者都給出了可接受的結果。
我的宏啓動:
Option Explicit
Sub LargestVisibleRange()
Dim Count As Long
Dim NumRowsInLargestRange As Long
Dim RngCrnt As Range
Dim RngTgt As Range
Dim RowCrnt As Long
Dim RowCrntRangeStart As Long
Dim RowLargestRangeEnd As Long
Dim RowLargestRangeStart As Long
Dim RowMax As Long
Dim RowPrev As Long
Dim StartTime As Single
With Worksheets("TrainData")
RowMax = .Cells(Rows.Count, "A").End(xlUp).Row
Debug.Print "1 RowMax " & RowMax
.Cells.AutoFilter
.Range(.Cells(2, 1), .Cells(RowMax, "Z")).AutoFilter Field:=2, Criteria1:=ChrW$(&H2116) & " 9/10"
我有一些數據時,我與過濾實驗我使用。如果你想使用這個宏作爲你自己的實驗的基礎,你將不得不取代上面的陳述。
宏繼續:
Set RngTgt = .Range(.Rows(2), .Rows(RowMax)).SpecialCells(xlCellTypeVisible)
Debug.Print "2 RngTgt " & RngTgt.Address
Count = 1
Debug.Print "3 ";
For Each RngCrnt In RngTgt
Debug.Print RngCrnt.Address & " ";
Count = Count + 1
If Count = 30 Then Exit For
Next
Debug.Print
Set RngTgt = RngTgt.EntireRow
Debug.Print "4 RngTgt " & RngTgt.Address
Count = 1
Debug.Print "5 ";
For Each RngCrnt In RngTgt
Debug.Print RngCrnt.Address & " ";
Count = Count + 1
If Count = 30 Then Exit For
Next
Debug.Print
從上面的語句中的輸出是:
1 RowMax 5691
2 RngTgt $2:$4,$20:$22,$38:$40,$56:$58,$74:$76,$92:$94,$110:$112,$128:$130,$146:$148,$164:$166,$182:$184,$200:$202,$218:$220,$236:$238,$254:$256,$272:$274,$290:$292,$308:$310,$326:$328,$344:$346,$362:$364,$380:$382,$398:$400,$416:$418,$434:$436,$452:$454,$470:$472
3 $A$2 $B$2 $C$2 $D$2 $E$2 $F$2 $G$2 $H$2 $I$2 $J$2 $K$2 $L$2 $M$2 $N$2 $O$2 $P$2 $Q$2 $R$2 $S$2 $T$2 $U$2 $V$2 $W$2 $X$2 $Y$2 $Z$2 $AA$2 $AB$2 $AC$2
4 RngTgt $2:$4,$20:$22,$38:$40,$56:$58,$74:$76,$92:$94,$110:$112,$128:$130,$146:$148,$164:$166,$182:$184,$200:$202,$218:$220,$236:$238,$254:$256,$272:$274,$290:$292,$308:$310,$326:$328,$344:$346,$362:$364,$380:$382,$398:$400,$416:$418,$434:$436,$452:$454,$470:$472
5 $2:$2 $3:$3 $4:$4 $20:$20 $21:$21 $22:$22 $38:$38 $39:$39 $40:$40 $56:$56 $57:$57 $58:$58 $74:$74 $75:$75 $76:$76 $92:$92 $93:$93 $94:$94 $110:$110 $111:$111 $112:$112 $128:$128 $129:$129 $130:$130 $146:$146 $147:$147 $148:$148 $164:$164 $165:$165
線1示出了,我有5690個的數據行。這比你少得多,但這足以提供足夠的性能指標。
線2的結果是:
Set RngTgt = .Range(.Rows(2), .Rows(RowMax)).SpecialCells(xlCellTypeVisible)
Debug.Print "2 RngTgt " & RngTgt.Address
注意,地址範圍爲$ 2:$ 4,$ 20:$ 22和等。還請注意該行被截斷。 Address屬性給出儘可能多的整個範圍,使得字符串的總長度小於255個字符。
3行的結果是:
Debug.Print "3 ";
For Each RngCrnt In RngTgt
Debug.Print RngCrnt.Address & " ";
Count = Count + 1
If Count = 30 Then Exit For
Next
Debug.Print
注意,雖然範圍內的地址分別爲整個行,For Each
返回單個細胞。還要注意,儘管我有26列數據,但返回的單元格包括AA2,AB2等。
4號線的結果是:這樣看來
Set RngTgt = RngTgt.EntireRow
Debug.Print "4 RngTgt " & RngTgt.Address
,新Set RngTgt
一直沒有效果。
但是,第5行與第3行相同,包含行而不是單元格。如果使用Excel 2003,處理修改後的RngTgt
將比處理未修改的RngTgt
快256倍。如果您使用更高版本的Excel,則速度會更快16,384。
宏的其餘部分通過兩種不同技術中的每一種識別最大範圍。第一種技術檢查每行的隱藏屬性。第二種技術使用修改後的RngTgt
。輸出是:
Duration 1: 0.073
Largest range 579 to 582
Duration 2: 0.003
Largest range 579 to 582
我相信持續時間1表明技術1會給出可接受的結果,但技術2顯然明顯快得多。
的宏的其餘部分是:
StartTime = Timer
RowCrntRangeStart = 0 ' No current visible range
RowLargestRangeStart = 0 ' No range found so far
RowCrnt = 2
Do While True
' Search for visible row
Do While True
If Not .Rows(RowCrnt).Hidden Then
RowCrntRangeStart = RowCrnt
Exit Do
End If
RowCrnt = RowCrnt + 1
If RowCrnt > RowMax Then
Exit Do
End If
Loop
If RowCrntRangeStart = 0 Then
' No unprocessed visible row found
Exit Do
End If
' Search for invisble row
Do While True
If .Rows(RowCrnt).Hidden Then
' Visible range is RowCrntRangeStart to RowCrnt-1
If RowLargestRangeStart = 0 Then
' This is the first visible range
RowLargestRangeStart = RowCrntRangeStart
RowLargestRangeEnd = RowCrnt - 1
NumRowsInLargestRange = RowLargestRangeEnd - RowLargestRangeStart + 1
Else
' Check for new range being larger thsn previous
If RowCrnt - RowCrntRangeStart > NumRowsInLargestRange Then
' This visible range is larger than previous largest
RowLargestRangeStart = RowCrntRangeStart
RowLargestRangeEnd = RowCrnt - 1
NumRowsInLargestRange = RowLargestRangeEnd - RowLargestRangeStart + 1
End If
End If
RowCrntRangeStart = 0 ' Not within visible range
RowCrnt = RowCrnt + 1 ' Step over first row of invisible range
Exit Do
End If
RowCrnt = RowCrnt + 1
If RowCrnt > RowMax Then
Exit Do
End If
Loop
If RowCrnt > RowMax Then
Exit Do
End If
Loop
Debug.Print "Duration 1: " & Format(Timer - StartTime, "##0.####")
Debug.Print "Largest range " & RowLargestRangeStart & " to " & RowLargestRangeEnd
End With
StartTime = Timer
RowCrntRangeStart = 0 ' No current visible range
RowLargestRangeStart = 0 ' No range found so far
For Each RngCrnt In RngTgt
If RowCrntRangeStart = 0 Then
' Start of visible range
RowPrev = RngCrnt.Row
RowCrntRangeStart = RowPrev
Else
' Already within visible range
If RowPrev + 1 = RngCrnt.Row Then
' Within same visible range
RowPrev = RngCrnt.Row
Else
' Have start of new visible range
' Last visible range was RowCrntRangeStart to Rowprev
If RowLargestRangeStart = 0 Then
' This is the first visible range
RowLargestRangeStart = RowCrntRangeStart
RowLargestRangeEnd = RowPrev
NumRowsInLargestRange = RowLargestRangeEnd - RowLargestRangeStart + 1
Else
' Check for new range being larger thsn previous
If RowPrev - RowCrntRangeStart + 1 > NumRowsInLargestRange Then
' This visible range is larger than previous largest
RowLargestRangeStart = RowCrntRangeStart
RowLargestRangeEnd = RowPrev
NumRowsInLargestRange = RowLargestRangeEnd - RowLargestRangeStart + 1
End If
End If
RowCrntRangeStart = RngCrnt.Row ' Start of new visible range
RowPrev = RngCrnt.Row
End If
End If
Next
Debug.Print "Duration 2: " & Format(Timer - StartTime, "##0.####")
Debug.Print "Largest range " & RowLargestRangeStart & " to " & RowLargestRangeEnd
End Sub
我希望技術2是對你有幫助。這一定對我有幫助。
相關問題
- 1. 如何在可見範圍內找到單元格的值
- 2. 檢查所選範圍內的單元格是否可見
- 3. Excel VBA根據相對範圍的最小值到最大值查找範圍內的單元格地址
- 4. 查找範圍內的最大和第二大元素
- 5. 查找activecell空單元格範圍
- 6. 查找範圍內的最小值
- 7. 查找範圍內的值
- 8. 價格範圍過濾器
- 9. 檢查#N/A單元格範圍內的空單元格
- 10. 最大範圍
- 11. 單元格範圍內的宏搜索
- 12. 迭代範圍內的單元格
- 13. Google Apps腳本 - 在單元格範圍內循環查找值
- 14. 在單元格範圍內查找值,然後返回索引
- 15. 當達到最大值時總結範圍內的範圍和阻塞範圍
- 16. VBA使用xlFillSeries自動填充可見單元格(過濾範圍)
- 17. 通過合併值過濾的求和單元格範圍?
- 18. 僅包含可見數據的單元格的複製範圍
- 19. AngularJS過濾範圍
- 20. 查找範圍
- 21. 從範圍VBA中查找最後一個單元格
- 22. php - 檢查多個日期範圍以查找更大範圍內的差距
- 23. 使用範圍(單元格,單元格)的VBA中的範圍錯誤設置範圍
- 24. 參考單元格範圍
- 25. Excel互操作範圍查找全部單元格內容
- 26. 查找大範圍的所有子範圍
- 27. 最後在一個範圍內使用的單元格 - excel 2013
- 28. 過濾器的最佳範圍
- 29. 通過查找範圍
- 30. 可以在單元格內找到的範圍內的返回值
感謝您分享解決方案。我發現了另一種使用split爲結果數組完成此操作的方法 – EranG