如果我在Excel中设置了自动过滤器,并且我希望使用VBA代码遍历一列中的所有可见数据,那么最简单的方法是什么?
不应包含已过滤掉的所有隐藏行,因此从上到下的普通范围无济于事。
有什么好主意吗?谢谢。
答案 0 :(得分:51)
假设A2:A11
中的自动过滤器在单元格A1
中有数字1到10。我现在过滤到仅显示大于5的数字(即6,7,8,9,10)。
此代码仅打印可见单元格:
Sub SpecialLoop()
Dim cl As Range, rng As Range
Set rng = Range("A2:A11")
For Each cl In rng
If cl.EntireRow.Hidden = False Then //Use Hidden property to check if filtered or not
Debug.Print cl
End If
Next
End Sub
也许SpecialCells
有更好的方法,但上述内容在Excel 2003中适用于我。
修改强>
刚刚找到了SpecialCells
的更好方法:
Sub SpecialLoop()
Dim cl As Range, rng As Range
Set rng = Range("A2:A11")
For Each cl In rng.SpecialCells(xlCellTypeVisible)
Debug.Print cl
Next cl
End Sub
答案 1 :(得分:13)
我建议使用Offset
,假设标题位于第1行。请参阅此示例
Option Explicit
Sub Sample()
Dim rRange As Range, filRange As Range, Rng as Range
'Remove any filters
ActiveSheet.AutoFilterMode = False
'~~> Set your range
Set rRange = Sheets("Sheet1").Range("A1:E10")
With rRange
'~~> Set your criteria and filter
.AutoFilter Field:=1, Criteria1:="=1"
'~~> Filter, offset(to exclude headers)
Set filRange = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
Debug.Print filRange.Address
For Each Rng In filRange
'~~> Your Code
Next
End With
'Remove any filters
ActiveSheet.AutoFilterMode = False
End Sub
答案 2 :(得分:8)
假设A1中的过滤数据向下的一种方式;
dim Rng as Range
set Rng = Range("A2", Range("A2").End(xlDown)).Cells.SpecialCells(xlCellTypeVisible)
...
for each cell in Rng
...
答案 3 :(得分:1)
我使用了范围的 RowHeight
属性(也意味着单元格)。如果它为零,则它是隐藏的。
因此,只需像往常一样遍历所有行,但在 if
条件中检查该属性,如 If myRange.RowHeight > 0 then DoStuff
中,其中 DoStuff
是您想要对可见单元格执行的操作。
答案 4 :(得分:0)
SpecialCells实际上不起作用,因为它需要连续。我已经通过添加排序功能来解决此问题,以便根据我需要的列对数据进行排序。
很抱歉,由于我不打算共享该代码,因此未对代码发表评论:
Sub testtt()
arr = FilterAndGetData(Worksheets("Data").range("A:K"), Array(1, 9), Array("george", "WeeklyCash"), Array(1, 2, 3, 10, 11), 1)
Debug.Print sms(arr)
End Sub
Function FilterAndGetData(ByVal rng As Variant, ByVal fields As Variant, ByVal criterias As Variant, ByVal colstoreturn As Variant, ByVal headers As Boolean) As Variant
Dim SUset, EAset, CMset
If Application.ScreenUpdating Then Application.ScreenUpdating = False: SUset = False Else SUset = True
If Application.EnableEvents Then Application.EnableEvents = False: EAset = False Else EAset = True
If Application.Calculation = xlCalculationAutomatic Then Application.Calculation = xlCalculationManual: CMset = False Else CMset = True
For Each col In rng.Columns: col.Hidden = False: Next col
Dim oldsheet, scol, ecol, srow, hyesno As String
Dim i, counter As Integer
oldsheet = ActiveSheet.Name
Worksheets(rng.Worksheet.Name).Activate
Worksheets(rng.Worksheet.Name).AutoFilterMode = False
scol = Chr(rng.Column + 64)
ecol = Chr(rng.Columns.Count + rng.Column + 64 - 1)
srow = rng.row
If UBound(fields) - LBound(fields) <> UBound(criterias) - LBound(criterias) Then FilterAndGetData = "Fields&Crit. counts dont match": GoTo done
dd = sortrange(rng, colstoreturn, headers)
For i = LBound(fields) To UBound(fields)
rng.AutoFilter Field:=CStr(fields(i)), Criteria1:=CStr(criterias(i))
Next i
Dim rngg As Variant
rngg = rng.SpecialCells(xlCellTypeVisible)
Debug.Print ActiveSheet.AutoFilter.range.address
FilterAndGetData = ActiveSheet.AutoFilter.range.SpecialCells(xlCellTypeVisible).Value
For Each row In rng.Rows
If row.EntireRow.Hidden Then Debug.Print yes
Next row
done:
'Worksheets("Data").AutoFilterMode = False
Worksheets(oldsheet).Activate
If SUset Then Application.ScreenUpdating = True
If EAset Then Application.EnableEvents = True
If CMset Then Application.Calculation = xlCalculationAutomatic
End Function
Function sortrange(ByVal rng As Variant, ByVal colnumbers As Variant, ByVal headers As Boolean)
Dim SUset, EAset, CMset
If Application.ScreenUpdating Then Application.ScreenUpdating = False: SUset = False Else SUset = True
If Application.EnableEvents Then Application.EnableEvents = False: EAset = False Else EAset = True
If Application.Calculation = xlCalculationAutomatic Then Application.Calculation = xlCalculationManual: CMset = False Else CMset = True
For Each col In rng.Columns: col.Hidden = False: Next col
Dim oldsheet, scol, srow, sortcol, hyesno As String
Dim i, counter As Integer
oldsheet = ActiveSheet.Name
Worksheets(rng.Worksheet.Name).Activate
Worksheets(rng.Worksheet.Name).AutoFilterMode = False
scol = rng.Column
srow = rng.row
If headers Then hyesno = xlYes Else hyesno = xlNo
For i = LBound(colnumbers) To UBound(colnumbers)
rng.Sort key1:=range(Chr(scol + colnumbers(i) + 63) + CStr(srow)), order1:=xlAscending, Header:=hyesno
Next i
sortrange = "123"
done:
Worksheets(oldsheet).Activate
If SUset Then Application.ScreenUpdating = True
If EAset Then Application.EnableEvents = True
If CMset Then Application.Calculation = xlCalculationAutomatic
End Function
答案 5 :(得分:0)
a = 2
x = 0
Do Until Cells(a, 1).Value = ""
If Rows(a).Hidden = False Then
x = Cells(a, 1).Value + x
End If
a = a + 1
Loop
End Sub
答案 6 :(得分:0)
Thisworkbook.sheets("Mysheet").Range("A1).Currentregion.copy
Thisworkbook.sheets("Othersheet").Range("A1)
答案 7 :(得分:-1)
Call MyMacro()
ActiveCell.Offset(1, 0).Activate
Do Until Selection.EntireRow.Hidden = False
If Selection.EntireRow.Hidden = True Then
ActiveCell.Offset(1, 0).Activate
End If
Loop