简体   繁体   English

Excel VBA 高级过滤器不复制所有列

[英]Excel VBA Advanced Filter to not copy all columns

I'm using AdvancedFilter for the first time in VBA.我第一次在 VBA 中使用 AdvancedFilter。 I'm trying to copy only specific columns from the source data table to an external workbook table.我正在尝试仅将特定列从源数据表复制到外部工作簿表。 I've seen how it should be specified when doing it not in VBA, but it's not working in my code.我已经看到在 VBA 中不这样做时应该如何指定它,但它在我的代码中不起作用。

Currently, the filtering works and it's copying to the external workbook table, BUT it's copying all the headings and filtered data, and pasting everything into the external table, not just the columns that are in my external table.目前,过滤有效,它正在复制到外部工作簿表,但它正在复制所有标题和过滤数据,并将所有内容粘贴到外部表中,而不仅仅是我的外部表中的列。

The code runs without any error messages.代码运行时没有任何错误消息。

So the outcome I want is所以我想要的结果是

  • for it not to copy the source data ( SDCRange ) headings因为它不复制源数据( SDCRange )标题
  • Only copy the columns that are in the external table ( copyToRng )仅复制外部表 ( copyToRng ) 中的列

Current code:当前代码:

Sub StockManagement(wb As Workbook, ws As Worksheet)
Dim TemplPath As String
Dim SMTemp As String
Dim SMTempF As String  

'Create Filter Criteria ranges
With MainWB.Worksheets.Add
    .Name = "FltrCrit"
    Dim FltrCrit As Worksheet
    Set FltrCrit = MainWB.Worksheets("FltrCrit")
End With

With FltrCrit
    Dim DerangedCrit As Range
    Dim myLastColumn As Long

    'Create Deranged Filter Criteria Range
    .Cells(1, "A") = "Deranged"
    .Cells(2, "A") = "MS"
    .Cells(3, "A") = "<>4"
    .Cells(2, "B") = "SOH"
    .Cells(3, "B") = "=0"

    'get last column, set range name
    With .Cells

        'find last column of data cell range
        myLastColumn = .Find(What:="*", After:=.Cells(2), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext).Column

        'specify cell range
        Set DerangedCrit = .Range(.Cells(2, "A:A"), .Cells(3, myLastColumn))

    End With


'Copy Filtered data to specified tables
Dim tblSDC As ListObject, tblFiltered As ListObject
Dim shSDC As Worksheet, shFiltered As Worksheet
Dim critRange As Range, copyToRng As Range, SDCRange As Range

'Assign values to sheet variables
Set shSDC = MainWB.Worksheets(2)
Set shFiltered = wb.Worksheets("Deranged with SOH")

'Turn off autofilter on filtered tab
shFiltered.AutoFilterMode = False

'Store Filtered table in variable
Set tblFiltered = shFiltered.ListObjects("Table_Deranged_with_SOH")
Set tblSDC = shSDC.ListObjects("Table_SDCdata")

'Remove Filtered table Filters
tblFiltered.AutoFilter.ShowAllData

'Set Criteria range to variable
Set critRange = DerangedCrit

'Set Copy to range on Filtered sheet table
Set copyToRng = tblFiltered.DataBodyRange(1, 1)
Set SDCRange = tblSDC.Range

'Use Advanced Filter
SDCRange.CurrentRegion.AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=critRange, CopyToRange:=copyToRng, Unique:=False

Any help will be appreciated.任何帮助将不胜感激。

EDIT:编辑:

If I set the external/output range to如果我将外部/输出范围设置为

Set copyToRng = tblFiltered.HeaderRowRange

It makes sense to me that it'll behave in the same way as if you used the Advanced Filter without VBA.对我来说,它的行为方式与您使用没有 VBA 的高级过滤器的行为方式相同。 So you set the output table range to the output table range headers, and that should then just copy all the columns that match.因此,您将 output 表范围设置为 output 表范围标题,然后应该只复制所有匹配的列。 BUT when I do that, nothing is copied, the output/external table is empty.但是当我这样做时,没有复制任何内容,输出/外部表是空的。

So any suggestions will be helpful thanks.所以任何建议都会有所帮助,谢谢。

Untested but should get you on the right track:未经测试,但应该让你走上正确的轨道:

Sub StockManagement(wb As Workbook, ws As Worksheet)

    Dim FltrCrit As Worksheet
    Dim DerangedCrit As Range
    Dim tblSDC As ListObject, tblFiltered As ListObject
    Dim m As Variant, c As Range


    Set FltrCrit = MainWB.Worksheets.Add()
    With FltrCrit
        .Name = "FltrCrit"
        .Cells(1, "A") = "Deranged"
        .Cells(2, "A") = "MS"
        .Cells(3, "A") = "<>4"
        .Cells(2, "B") = "SOH"
        .Cells(3, "B") = "=0"
        Set DerangedCrit = .Range(.Cells(2, "A"), _
                                  .Cells(2, .Columns.Count).End(xlToLeft)).Resize(2)
    End With

    Set tblFiltered = wb.Worksheets("Deranged with SOH").ListObjects("Table_Deranged_with_SOH")
    tblFiltered.AutoFilter.ShowAllData

    Set tblSDC = MainWB.Worksheets(2).ListObjects("Table_SDCdata")
    tblSDC.Range.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=DerangedCrit

    'loop over the headers in the destination table
    For Each c In tblFiltered.HeaderRowRange.Cells
        m = Application.Match(c.Value, tblSDC.HeaderRowRange, 0) 'matched source header?
        If Not IsError(m) Then
            'got a match - copy visible cells for this column
            tblSDC.ListColumns(c.Value).DataBodyRange.SpecialCells(xlCellTypeVisible).Copy _
                    c.Offset(1, 0)
        End If
    Next c

End Sub

Mystery solved, It was a silly error.谜底解决了,这是一个愚蠢的错误。 The code works absolutely fine, the problem that the external/output table was empty was because one of my headers in the external/output table had an extra space in, so it couldn't match to the source data headers.代码工作得很好,外部/输出表为空的问题是因为我在外部/输出表中的一个标题有一个额外的空间,所以它不能与源数据标题匹配。

I did adjust the code slightly to remove some of the variables (as suggested by @Tim Williams) above.我确实稍微调整了代码以删除上面的一些变量(如@Tim Williams 所建议的)。

Code now looks as like this:代码现在看起来像这样:

Sub StockManagement(wb As Workbook, ws As Worksheet)
Dim TemplPath As String
Dim SMTemp As String
Dim SMTempF As String  

'Create Filter Criteria ranges
With MainWB.Worksheets.Add
    .Name = "FltrCrit"
    Dim FltrCrit As Worksheet
    Set FltrCrit = MainWB.Worksheets("FltrCrit")
End With

With FltrCrit
    Dim DerangedCrit As Range
    Dim myLastColumn As Long

    'Create Deranged Filter Criteria Range
    .Cells(1, "A") = "Deranged"
    .Cells(2, "A") = "MS"
    .Cells(3, "A") = "<>4"
    .Cells(2, "B") = "SOH"
    .Cells(3, "B") = "=0"

    'get last column, set range name
    With .Cells

        'find last column of data cell range
        myLastColumn = .Find(What:="*", After:=.Cells(2), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext).Column

        'specify cell range
        Set DerangedCrit = .Range(.Cells(2, "A:A"), .Cells(3, myLastColumn))

    End With

'Copy Filtered data to specified tables
Dim tblFiltered As ListObject
Dim copyToRng As Range, SDCRange As Range

'Store Filtered table in variable
Set tblFiltered = wb.Worksheets("Deranged with SOH").ListObjects("Table_Deranged_with_SOH")

'Remove Filtered table Filters
tblFiltered.AutoFilter.ShowAllData

'Set Copy to range on Filtered sheet table
Set copyToRng = tblFiltered.HeaderRowRange
Set SDCRange = MainWB.Worksheets(2).ListObjects("Table_SDCdata").Range

'Use Advanced Filter
SDCRange.AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=DerangedCrit, CopyToRange:=copyToRng, Unique:=False

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM