简体   繁体   English

将过滤后的范围放入数组 - ....AutoFilter.Range.SpecialCells(xlCellTypeVisible).Offset(1)

[英]Get a filtered range into an array - ….AutoFilter.Range.SpecialCells(xlCellTypeVisible).Offset(1)

After data is filtered and sorted using Sub CreateFilteredandSort , I'm trying to use使用Sub CreateFilteredandSort过滤和排序数据后,我正在尝试使用

.AutoFilter.Range.SpecialCells(xlCellTypeVisible).Offset(1)

to store the data into an array.将数据存储到数组中。

In the array I get only one row.在数组中我只得到一行。

To get all the data into the array I paste somewhere in the active worksheet then要将所有数据放入数组中,我将粘贴到活动工作表中的某个位置,然后

'Alertnative method
   Range("a1").Select
   ActiveSheet.Paste
   ResultArr = Selection  'This Works fine

What do I correct to prevent the alternative method?我该如何纠正以防止替代方法?

My range data location我的范围数据位置
在此处输入图像描述

Here the source code这里是源代码

Sub TestCreateandClearFilter()

    Dim WS As Worksheet
    Dim ResultArr() As Variant

    Set WS = ActiveWorkbook.ActiveSheet

    IfFilterandSortinWorksheetExistClear WS

    CreateFilteredandSort WS, _
                          WS.Range("Rangedata"), _
                          "H", _
                          "F", _
                          "a", _
                          WS.Range("RNGA")
    'store in Array
    'not Working, Only one row is stored
    ResultArr = WS.AutoFilter.Range.SpecialCells(xlCellTypeVisible).Offset(1)
    WS.Range("Rangedata").Offset(1).SpecialCells(xlCellTypeVisible).Select
    ResultArr = Selection
    'not Working, Only one row is stored
   
    WS.Range("Rangedata").Offset(1).Copy
   
    'Alertnative method
    Range("a1").Select
    ActiveSheet.Paste
    ResultArr = Selection                        'This Works fine
                  
End Sub

Sub CreateFilteredandSort(WS As Worksheet, RangeSelected As Range, _
  FilterField11Name As String, FilterField12Name As String, _
  FilterField12Criteria As String, Group1Sort As Range)
    '
    ' Create Custom Filter and sort Macro
    Dim FilterColumn1 As Variant
    Dim arra As Variant

    'GetTheOffsetField
    '3 required because the range start in column 4
    FilterColumn1 = RangeSelected.Rows(1).Find(What:=FilterField11Name, _
      LookAt:=xlWhole, SearchOrder:=xlByRows).Column - 3
    
    FilterColumn2 = RangeSelected.Rows(1).Find(What:=FilterField12Name, _
      LookAt:=xlWhole, SearchOrder:=xlByRows).Column - 3
    
    '   Create the Filter
    RangeSelected.AutoFilter Field:=FilterColumn1, Criteria1:="TRUE"
    RangeSelected.AutoFilter Field:=FilterColumn2, Criteria1:=FilterField12Criteria
    'Sort by group1
    WS.AutoFilter.Sort.SortFields.Add2 Key:= _
      Group1Sort, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
      :=xlSortNormal
    
    With WS.AutoFilter.Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    
End Sub

Sub IfFilterandSortinWorksheetExistClear(WS As Worksheet)

    If WS.AutoFilterMode Then Selection.AutoFilter

End Sub

Please, try the next function, able to transform a discontinuous range in a continuous array:请尝试下一个 function,能够将不连续范围转换为连续数组:

Function arrayFromDiscontRange(rng As Range) As Variant
  Dim aR As Range, R As Range, arrInt, arr, i As Long, k As Long
  Dim rngInt As Range, count As Long, j As Long
  
  k = 1
  'counting range/area rows:________________________________
  Set rngInt = Intersect(rng, rng.cells(1, 1).EntireColumn)
  For Each aR In rngInt.Areas
    If aR.rows.count = 1 Then
        count = count + 1
    Else
        For Each R In aR.cells
            count = count + 1
        Next
    End If
  Next
  '________________________________________________________
  ReDim arr(1 To count, 1 To rng.Columns.count)
  For Each aR In rng.Areas
    If aR.rows.count = 1 Then
        For i = 1 To aR.Columns.count
            arr(k, i) = aR.cells(1, i)
        Next
        k = k + 1
    Else
        For i = 1 To aR.rows.count
            For j = 1 To aR.Columns.count
                arr(k, j) = aR.cells(i, j)
            Next j
            k = k + 1
        Next
    End If
  Next
  arrayFromDiscontRange = arr
End Function

It can be called passing a discontinuous range (obtained after filtering), in the next way:可以称为传递不连续范围(过滤后获得),方式如下:

  'firstly, filter the range
  '
  Dim rngArr As Range
  Set rngArr = WS.Range("Rangedata").SpecialCells(xlCellTypeVisible)
  ResultArr = arrayFromDiscontRange(rngArr)
  Dim arrFirstRow
    arrFirstRow = Application.Index(ResultArr, 1, 0) 'make a slice for the first array row (1D array)
    Debug.Print Join(arrFirstRow, "|") 'see the array first row content in Immediate Window

If you need to skip the first row, the function can be easily transformed to create the array starting from the second (real) range row.如果您需要跳过第一行,可以轻松转换 function 以从第二(实际)范围行开始创建数组。 First row of the first area will be skipped...第一个区域的第一行将被跳过...

Edited :编辑

The next function is able to return an array starting from a mentioned row:下一个 function 能够从提到的行返回一个数组:

Function arrFromDiscontRange(rng As Range, Optional startRow As Long = 1) As Variant
  Dim aR As Range, R As Range, arrInt, arr, i As Long, k As Long
  Dim rngInt As Range, count As Long, j As Long, iStart As Long
  
  k = 1
  'counting range/area rows:________________________________
  Set rngInt = Intersect(rng, rng.cells(1, 1).EntireColumn)
  For Each aR In rngInt.Areas
    If aR.rows.count = 1 Then
        count = count + 1
    Else
        For Each R In aR.cells
            count = count + 1
        Next
    End If
  Next
  '________________________________________________________
  ReDim arr(1 To count - startRow + 1, 1 To rng.Columns.count)
  For Each aR In rng.Areas
    If aR.rows.count = 1 Then
        iStart = iStart + 1
        If iStart >= startRow Then
            For i = 1 To aR.Columns.count
                arr(k, i) = aR.cells(1, i)
            Next
            k = k + 1
        End If
    Else
        For i = 1 To aR.rows.count
            iStart = iStart + 1
            If iStart >= startRow Then
                For j = 1 To aR.Columns.count
                    arr(k, j) = aR.cells(i, j)
                Next j
                k = k + 1
            End If
        Next
    End If
  Next
  arrFromDiscontRange = arr
End Function

It can be called/tested, in your context in the next way:可以在您的上下文中以以下方式调用/测试它:

  'firstly, filter the range
  '
  Dim rngArr As Range
  Set rngArr = WS.Range("Rangedata").SpecialCells(xlCellTypeVisible)
  ResultArr = arrayFromDiscontRange(rngArr, 2)' it will build the array starting from the second row of the (discontinuous) range.
  Dim arrFirstRow
  arrFirstRow = Application.Index(ResultArr, 1, 0) 'make a slice for the first array row (1D array)
  Debug.Print Join(arrFirstRow, "|") 'see the array first row content in Immediate Window

Please, test it and send some feedback.请测试它并发送一些反馈。 I had in mind doing such a function and I did it now, seeing your question...我本来打算做这样一个 function ,我现在就做了,看到你的问题......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法获取xlcelltypevisible的范围类的Specialcells属性 - unable to get the Specialcells property of the range class for xlcelltypevisible xlCellTypeVisible不返回过滤范围,而是整个范围 - xlCellTypeVisible not returning filtered range, instead whole range VBA通过.SpecialCells(xlCellTypeVisible)合并自动过滤的单元格 - VBA merging autofiltered cells via .SpecialCells(xlCellTypeVisible).Range 在下一个工作表循环中,SpecialCells(xlCellTypeVisible) 范围应读取为 NOTHING - SpecialCells(xlCellTypeVisible) range should be read as NOTHING in the next worksheet loop 将经过过滤的范围放入数组 - Get a filtered range into an array SpecialCells(xlCellTypeVisible)还包括隐藏/过滤的单元格 - SpecialCells(xlCellTypeVisible) also includes hidden/filtered cells 找到了'TargetTable.Range.SpecialCells(xlCellTypeVisible).Copy _'目标:= Sheets(“ Sheet8”)。Range(“ A1”) - found 'TargetTable.Range.SpecialCells(xlCellTypeVisible).Copy _ ' Destination:=Sheets(“Sheet8”).Range(“A1”) SpecialCells(xlCellTypeVisible) - SpecialCells(xlCellTypeVisible) SpecialCells(xlCellTypeVisible)-自动过滤器返回零行时出错 - SpecialCells(xlCellTypeVisible) - Error when Autofilter returns zero rows 范围(“CustomTable”)。SpecialCells(xlCellTypeVisible).Delete现在失败。 运行时错误'1004' - Range(“CustomTable”).SpecialCells(xlCellTypeVisible).Delete now fails. Run-time error '1004'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM