使用我不想要的值

时间:2015-09-12 15:02:08

标签: excel excel-vba vba

ThisWorkbook.Sheets(1).Range("A1:AR1").AutoFilter Field:=27, _
Criteria1:=Array("<>DRCA", "<>DREX", "<>DRFU", "<>DRIN", _
"<>DRIR", "<>DRND", "<>DRPN", "<>DRPR", "<>DRRE", "<>DRUN", _
"<>REXC", "<>EXCD", "<>RFUR", "<>RINV", "<>RIRC", "<>RNDR", _
"<>RPNA", "<>RPRO", "<>RRET", "<>RUND", "<>RUNF", "<>EXC", "<>C"), _
Operator:=xlFilterValues

这不会返回我想要的正确过滤器数据。我想要的是,如果数组没有找到任何<> value,那么跳过它然后检查。

我该如何解决?

2 个答案:

答案 0 :(得分:4)

Excel不允许您在Autofilter中使用您想要的数组。但是有替代方案吗?是的!

逻辑如果我要求您选择010之间的数字,包括010,但您无法选择05810。因此,不要过滤数字并说我不想05810,您可以说I want 1,2,3,4,6,7,9

同样在您的情况下,我们不会过滤我们不想要的值。我们将过滤我们想要的值。

所以如何我们是否找到该列表并将其存储在数组中?

  1. 找到相关列中的最后一行。
  2. 将该列中的所有记录存储在唯一的集合中
  3. 检查该集合中的哪些项目不在“排除”列表中并创建一个数组。
  4. 过滤所需值(数组)的范围!这样我们就不必过滤掉我们不想要的值。
  5. 代码使用50k记录在Excel 2013中测试

    我已对代码进行了评论,但如果您仍有任何疑问,请随时询问:)

    Dim OmitArray As Variant
    Const deLim As String = "|"
    
    Sub Sample()
        Dim Ws As Worksheet
        Dim lRow As Long, i As Long, n As Long, lCol As Long
        Dim Col As New Collection, itm
        Dim includeArray As Variant
        Dim rng As Range
        Dim tmpString As String
    
        '~~> This array has all the values that you want to ignore
        OmitArray = Array("DRCA", "DREX", "DRFU", "DRIN", "DRIR", "DRND", _
                    "DRPN", "DRPR", "DRRE", "DRUN", "REXC", "EXCD", "RFUR", _
                    "RINV", "RIRC", "RNDR", "RPNA", "RPRO", "RRET", "RUND", _
                    "RUNF", "EXC", "C")
    
        '~~> This is the column where you want to filter out
        lCol = 27
    
        '~~> Change this to the relevant worksheet
        Set Ws = ThisWorkbook.Sheets("Sheet1")
    
        With Ws
            '~~> Find lastrow
            lRow = .Range("A" & .Rows.Count).End(xlUp).Row
    
            '~~> This is the range where the filter will be applied
            Set rng = .Range("A1:AR" & lRow)
    
            '~~> All all the values from col 27 to a unique collection
            For i = 2 To lRow
                On Error Resume Next
                Col.Add .Cells(i, lCol).Value, CStr(.Cells(i, 27).Value)
                On Error GoTo 0
            Next i
    
            '~~> Now loop though the collection and store the values in a string
            '~~> delimited with a delimiter which arenot present in the "OmitArray"
            For Each itm In Col
                If Not IsInArray(itm, OmitArray) Then
                    If tmpString = "" Then
                        tmpString = itm
                    Else
                        tmpString = tmpString & deLim & itm
                    End If
                End If
            Next itm
    
            If tmpString <> "" Then
                '~~> Split the values based on the delimiter to create array
                includeArray = Split(tmpString, deLim)
    
                '~~> Remove any filters
                .AutoFilterMode = False
    
                '~~> Filter on the rest of the values
                With rng
                  .AutoFilter Field:=lCol, Criteria1:=includeArray, Operator:=xlFilterValues
                End With
            End If
        End With
    End Sub
    
    '~~> Function to check if there is an item in the array
    Function IsInArray(stringToBeFound As Variant, arr As Variant) As Boolean
        Dim bDimen As Byte, i As Long
    
        On Error Resume Next
        If IsError(UBound(arr, 2)) Then bDimen = 1 Else bDimen = 2
        On Error GoTo 0
    
        Select Case bDimen
        Case 1
            On Error Resume Next
            IsInArray = Application.Match(stringToBeFound, arr, 0)
            On Error GoTo 0
        Case 2
            For i = 1 To UBound(arr, 2)
                On Error Resume Next
                IsInArray = Application.Match(stringToBeFound, Application.Index(arr, , i), 0)
                On Error GoTo 0
                If IsInArray = True Then Exit For
            Next
        End Select
    End Function
    

答案 1 :(得分:2)

您无法使用VBA中的AutoFilter为给定字段明确排除两个以上的值。相反,您需要指定要包含的值。

但您不需要使用AutoFilter来隐藏包含特定值的行。

这是一个适用于您的案例的简短例程。您可以通过编辑第一行来管理要隐藏的行:

Public Sub Demo()
    Const HIDE = ".DRCA.DREX.DRFU.DRIN.DRIR.DRND.DRPN.DRPR.DRRE.DRUN.REXC.EXCD.RFUR.RINV.RIRC.RNDR.RPNA.RPRO.RRET.RUND.RUNF.EXC.C."
    Dim c As Range
    With ThisWorkbook.Sheets(1)
        For Each c In .Range("AR1:AR" & .Range("AR" & .Rows.Count).End(xlUp).Row)
            If InStr(HIDE, "." & c & ".") Then
                c.EntireRow.Hidden = True
            End If
        Next
    End With
End Sub