Example data我试图想出一个宏,它将填充“Pass On”选项卡,其中“H”表中没有“QC-Completed”的每个项目的“数据”选项卡中的相应数据或U列中的容器。
我还没有接近。
请尝试以下方法。
A)定义过滤范围
我通过查找基于第1行和第A列的最后使用的行和列来定义要使用的范围,并将其存储在filterRange
变量中。
B)清除任何现有的过滤器
我确保没有现有的过滤器:
wsSource.AutoFilterMode = False
请注意,我已将源表和目标表放入工作表变量中以便于参考?
C)应用过滤条件
然后我使用该范围来应用这两个标准:
With filterRange
.AutoFilter
.AutoFilter Field:=filterField1, Criteria1:="<>" criterion1, Operator:=xlFilterValues
.AutoFilter Field:=filterField2, Criteria1:=criterion2
请注意,我已经使用常量来保存感兴趣的列,并使用过滤条件来处理例如: filterField1
和criterion1
。这意味着,如果您决定更改应用过滤器的方式,则可以在代码顶部轻松调整这些内容。显然仍然限于两列但很容易看到你如何扩展它。
D)提取感兴趣的列并对其进行排序
现在,因为我们不希望所有过滤后的数据需要做三件事:
1)获取所有过滤的数据
因此,以下内容使用.AutoFilter.Range
对象来获取过滤范围,然后使用Resize排除标题行。我们已经在另一张表中有一个标题。这被转储到一个数组中,因为它从工作表中读入的是Option Base 1,而不是0. 0是数组的正常下限。
With wsSource.AutoFilter.Range
dataArray = .Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count) 'exclude header
End With
2)将其减少到感兴趣的列
3)按指定的顺序排列那些列S,AD,B,C,E,H,L
通过使用指定要按所需顺序保留的列的数组来实现2和3。
Dim columnsToKeep() As Variant
columnsToKeep = Array(19, 30, 2, 3, 5, 8, 12)
然后创建一个数组来保存要写入工作表的结果,resultArray
,你知道它将具有与你已经拥有的数组相同的行数dataArray
,并且将具有与中的项目相同的列数columnsToKeep
阵列即UBound(columnsToKeep) + 1
。注意+ 1,因为该数组使用默认的base 0选项。
我们循环dataArray
的行,然后,在这个循环中,我们循环columnsToKeep
指定的列。这意味着我们可以使用columnsToKeep(currentColumn)
以dataArray
中显示的顺序从源数组columnsToKeep
返回指定列中的值。为了确保将其加载到resultArray
中,列编号从1开始,另外一个columnCounter
变量用于指定输出列。
For currentRow = LBound(dataArray, 1) To UBound(dataArray, 1)
columnCounter = 0
For currentColumn = LBound(columnsToKeep) To UBound(columnsToKeep)
columnCounter = columnCounter + 1
resultArray(currentRow, columnCounter) = dataArray(currentRow, columnsToKeep(currentColumn))
Next currentColumn
Next currentRow
E)将结果写入第二张表
最后,我们将所有内容写入标题下方的另一个表格:
wsTarget.Range("A2").Resize(UBound(resultArray, 1), UBound(resultArray, 2)) = resultArray
码:
Option Explicit
Public Sub CopyData()
'Range("H1").Select
Dim wb As Workbook
Dim wsSource As Worksheet
Dim wsTarget As Worksheet
Const filterField1 As Long = 8 'Column H
Const filterField2 As Long = 21 'Column U
Const criterion1 As String = "QC-Completed"
Const criterion2 As String = vbNullString
Set wb = ThisWorkbook
Set wsSource = wb.Worksheets("Data")
Set wsTarget = wb.Worksheets("Pass On")
Dim lastRowSource As Long
lastRowSource = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row
Dim lastColumnSource As Long
lastColumnSource = wsSource.Range("A1").SpecialCells(xlCellTypeLastCell).Column
Dim filterRange As Range
Set filterRange = wsSource.Range(wsSource.Cells(1, 1), wsSource.Cells(lastRowSource, lastColumnSource))
wsSource.AutoFilterMode = False
Dim dataArray As Variant
With filterRange
.AutoFilter
.AutoFilter Field:=filterField1, criteria1:="<>" & criteria1, Operator:=xlFilterValues
.AutoFilter Field:=filterField2, criteria1:=criteria2
With wsSource.AutoFilter.Range
dataArray = .Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count) 'exclude header
End With
End With
Application.CutCopyMode = False 'Clear clipboard
Dim columnsToKeep() As Variant
columnsToKeep = Array(19, 30, 2, 3, 5, 8, 12) 'determine output columns to keep and their orser
Dim currentRow As Long
Dim currentColumn As Long
Dim resultArray() As Variant
ReDim resultArray(1 To UBound(dataArray, 1), 1 To UBound(columnsToKeep) + 1)
Dim columnCounter As Long
For currentRow = LBound(dataArray, 1) To UBound(dataArray, 1)
columnCounter = 0
For currentColumn = LBound(columnsToKeep) To UBound(columnsToKeep)
columnCounter = columnCounter + 1
resultArray(currentRow, columnCounter) = dataArray(currentRow, columnsToKeep(currentColumn))
Next currentColumn
Next currentRow
wsTarget.Range("A2").Resize(UBound(resultArray, 1), UBound(resultArray, 2)) = resultArray
End Sub
参考文献: