将过滤范围放入数组中

时间:2017-08-26 17:02:05

标签: excel-vba vba excel

我试图将过滤范围变成一个数组,在我的测试数据中,数组fArr具有正确的暗淡,而fLR是过滤范围的正确计数

但是filRange始终只是标题范围而不是过滤范围

如何让filRange成为过滤范围?

或者说如何让fArr成为过滤数据的数组?

由于

Sub arrFilterdRng()
Dim fArr As Variant
Dim rRange As Range, filRange As Range, myCell As Range
Dim fLR As Long, rCtr As Long

'Remove any filters
ActiveSheet.AutoFilterMode = False

'~~> Set your range
Set rRange = Sheets("Z").UsedRange

With rRange
    '~~> Set your criteria and filter
    .AutoFilter Field:=3, Criteria1:="*"

    Set filRange = .SpecialCells(xlCellTypeVisible).EntireRow
    fLR = .Resize(, 1).SpecialCells(xlCellTypeVisible).Count
    Debug.Print fLR

    ReDim fArr(1 To fLR, 1 To .Columns.Count)
    Debug.Print UBound(fArr, 1), UBound(fArr, 2)

    rCtr = 0
    For Each myCell In filRange.Columns(1)
      rCtr = rCtr + 1
       For cCtr = 1 To .Columns.Count
         fArr(rCtr, cCtr) = myCell.Offset(0, cCtr - 1).value
       Next cCtr
   Next myCell
End With

'Remove any filters
ActiveSheet.AutoFilterMode = False

End Sub

我的数据看起来像这样(全文)

enter image description here

2 个答案:

答案 0 :(得分:2)

我的感觉是你的标准中的通配符造成了麻烦。

“*”仅适用于字符串,因此如果您的数据是数字(包括日期),那么它们将被过滤器删除(即它们不可见),因此您确实只有您的范围内的标题

如果你想要数值,那么一种方法就是定义一个值,比如说:

.AutoFilter Field:=3, Criteria1:=">0"

或者,如果你想要限制:

.AutoFilter Field:=3, Criteria1:=">0", Operator:=xlAnd, Criteria2:="<10"

另一方面,如果你只想要空白单元格,那么语法应该是:

.AutoFilter Field:=3, Criteria1:="<>"

您还应该知道,如果过滤范围包含非连续范围,则每个“单独”范围将包含在Areas集合中。这意味着像filRange.Rows.Count这样的东西只会返回第一个区域的行数;当您尝试Offset和/或Resize过滤后的范围时,您会遇到真正的困难。使用.Value属性也无法将非连续范围直接读入数组。

我不确定您的代码是处理任务的最有效方式,但保持相同的结构可能如下所示:

Dim rRange As Range, filRange As Range
Dim myArea As Range, myRow As Range, myCell As Range
Dim fArr() As Variant
Dim r As Long

With ThisWorkbook.Worksheets("Z")
    .AutoFilterMode = False
    Set rRange = .UsedRange
End With

With rRange
    .AutoFilter Field:=3, Criteria1:=">0"
    Set filRange = .SpecialCells(xlCellTypeVisible)
End With

With filRange
    r = -1 'start at -1 to remove heading row
    For Each myArea In filRange.Areas
        r = r + myArea.Rows.Count
    Next
    ReDim fArr(1 To r, 1 To .Columns.Count)
End With

r = 1
For Each myArea In filRange.Areas
    For Each myRow In myArea.Rows
        If myRow.Row <> 1 Then
            For Each myCell In myRow.Cells
                fArr(r, myCell.Column) = myCell.Value
            Next
            r = r + 1
        End If
    Next
Next

答案 1 :(得分:0)

也许您的数据更复杂,但您可以简单地将范围的值分配给数组:

@mixin

因此无需循环数据。

这是一个使用这个简单数据网格的工作示例:

enter image description here

此代码:

var = rng.SpecialCells(xlCellTypeVisible).Value

表单中的结果:

enter image description here

Option Explicit Sub arrFilterdRng() Dim ws As Worksheet '<-- your worksheet Dim rng As Range '<-- your range to filter Dim var As Variant '<-- will hold array of visible data Dim lng1 As Long, lng2 As Long ' get sheet; remove filters Set ws = ThisWorkbook.Worksheets("Sheet2") ws.AutoFilterMode = False ' get range; apply filter Set rng = ws.UsedRange rng.AutoFilter Field:=1, Criteria1:="x" ' assign visible range to array var = rng.SpecialCells(xlCellTypeVisible).Value ' test array For lng1 = LBound(var, 1) To UBound(var, 1) For lng2 = LBound(var, 2) To UBound(var, 2) Debug.Print var(lng1, lng2) Next lng2 Next lng1 End Sub 内容的立即窗口输出为:

var