[英]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.