Excel VBA – 使用命名范围的自定义filter

我在工作表上有一列数据,包含在我正在编写的一个非常大的工作簿中,名为Vendor ,我想在VBA中编写一个macros,允许我通过特定供应商过滤供应Vendor A

到目前为止,我有这样的:

 Sub filterVendor() ' ' filterVendor Macro ' ' ActiveSheet.Range("$A:$BB").AutoFilter Field:=21, Criteria1:= _ "Vendor A" End Sub 

我所Vendor的问题是Vendor列的位置可能会发生改变 – 因为其他列在之前被添加和/或删除,导致它相应地移位 – 我想知道是否可以引用这个特定的列/块的数据保存macros变得无用。

理想情况下,我会引用范围( vendor就是我想调用的命名范围),以便无论工作表结构如何,filter在运行macros时都能正常工作。

如何才能做到这一点?

更多信息:

我怀疑Field:标准是造成这个问题,因为这似乎绝对定义了要过滤的列; 即使我已经指定Vendor列被命名为vendor的范围,并且即使命名的范围引用与所述Vendor列一起移动,被过滤的列始终位于Field:指定的位置。 如何才能解决这个问题呢?

我努力了:

 ...Field:=Range("vendor") 

 ...Field:=(Range("vendor")) 

但这两者都会导致错误。

有趣的挑战! 我解决了这个问题:

  • 使用一个命名的Range ,“供应商”,如你所描述的(我认为)
  • 编写一个小助手函数DoesVendorExist ,确保命名Range “供应商”存在
  • 编写另一个小帮手函数VendorColNum ,返回“Vendor”的列号
  • 根据.Autofilter返回的编号应用VendorColNum

下面是我testing过的工作簿(确实很小)的屏幕截图:

开始

这里是辅助函数和稍微修改的filterVendor2子例程:

 Option Explicit Sub filterVendor2() Dim DataSheet As Worksheet Dim VendorCol As Long 'set references up-front Set DataSheet = ThisWorkbook.Worksheets("data") '... 'doing other stuff '... 'here we make sure a named range called Vendor exists If Not DoesVendorExist(ThisWorkbook) Then MsgBox ("Dangit! There is not a named range Vendor in this workbook! Exiting...") Exit Sub End If 'define the vendor column VendorCol = VendorColNum(DataSheet) 'here we make sure the Vendor named range is not empty If VendorCol = 0 Then MsgBox ("Bummer! The named range Vendor was Nothing on DataSheet, exiting...") Exit Sub End If 'otherwise, let's do some filtering! DataSheet.Range("$A:$BB").AutoFilter Field:=VendorCol, Criteria1:="SnookerFan" '... 'doing other cool stuff and finishing up '... End Sub 'INPUT : pass this function the worksheet on which the Vendor range is defined 'OUTPUT : the column number that the Vendor range exists in 'SPECIAL: if the Vendor Range is nothing, return 0 Public Function VendorColNum(Sheet As Worksheet) As Long 'if the Vendor range is missing, return 0 and exit If Sheet.Range("Vendor") Is Nothing Then VendorColNum = 0 Exit Function End If 'otherwise, we return a real column number VendorColNum = Sheet.Range("Vendor").Column End Function 'INPUT : pass this function the workbook we'd like to check for Vendor 'OUTPUT : true/false... does Vendor exist? 'SPECIAL: none Public Function DoesVendorExist(Book As Workbook) As Boolean Dim Nm As Name 'assume false, test each name and flip the flag if Vendor is found 'assume false, test each name and flip the flag if Vendor is found DoesVendorExist = False For Each Nm In Book.Names If UCase(Nm.Name) = UCase("vendor") Then '<~ error was here, did not paste over .Name DoesVendorExist = True Exit Function End If Next Nm End Function 

最后,这是最终的过滤Range 。 您应该发现,在数据表中添加或删除列不会破坏代码。

结束

编辑:我的道歉,因为检查命名的范围的错误是一个马虎复制/粘贴,我自己通过这个问题的工作。 我已经更新了上面的代码,并突出显示错误(正在检查Nm ,看看它是否匹配“供应商”,应该已经检查Nm.Name ,看看它是否匹配UCASE("vendor")

自动筛选器喜欢基于一维的单维数组,所以我们构build和应用这种types的数组:

 Sub FilterMyData() Dim ary(), N As Long, i As Long N = Range("Vendors").Count ReDim ary(1 To N) For i = 1 To N ary(i) = Range("Vendors")(i).Value Next i With ActiveSheet.Range("A:BB") .AutoFilter Field:=23, Criteria1:=ary, Operator:=xlFilterValues End With End Sub 

你使用MS Excel版本2010? 如果是这样,您可以使用内置的filter选项,可以使用临时的。

首先,你需要形成一个表格,然后点击filter箭头。