【问题标题】:Workaround for filtering for multiple wildcard criteria过滤多个通配符条件的解决方法
【发布时间】:2019-02-21 01:23:19
【问题描述】:

我看到了一些不同的解决方案来绕过 excel 中过滤器的 2 个通配符限制(特别是发布的答案 here,但我很难理解他们在做什么。我正在尝试实施的工作是仅使用基本 countif 公式计算单元格中每个条件的实例数,如果为 0,则宏将隐藏该行。

With ws1

    ColumnOne = .Cells(1, .Columns.Count).End(xlToLeft).Column
    LastRow = .Cells(.Rows.Count, lastColumn).End(xlUp).Row

    ColumnTwo = ColumnOne - 1



    If ws2.Application.WorksheetFunction.CountA("D47:D61") <> 0 Then

        For i = 1 To LastRow
            If .Cells(i, ColumnTwo).Value = 0 Then
                .Rows(i).EntireRow.Hidden = True
            End If

        Next i

    ElseIf ws2.Application.WorksheetFunction.CountA("E47:E61") <> 0 Then

        For i = 1 To LastRow
            If .Cells(i, ColumnOne).Value = 0 Then
                .Rows(i).EntireRow.Hidden = True
            End If

        Next i
    Else
        Exit Sub
    End If
End With

上面的代码是我用来处理这个问题的。作为参考,单独的工作表 (ws2) 上有两列标准可以更改/完全为空。然后,上面的代码通过查看哪个不为空来检查它应该与哪些列一起使用(ws2 上的 D 使用 ws1 上的 ColumnTwo,ws2 上的 E 使用 ws1 上的 ColumnOne),然后开始检查 ws1 行上的列行以查看是否存在任何条件。如果不存在任何条件(单元格值 = 0),则它应该隐藏该行。

使用 D 或 E 的检查似乎不起作用。即使 ws2 上的 D47:D61 中的所有单元格都是空的,它仍然在该 if 语句中运行,而不是移动到 E47:E61。关于我应该在这里尝试和改变什么的任何想法?

【问题讨论】:

  • 您能否更具体地说明什么不起作用?代码看起来没问题,你遇到了什么问题?
  • 抱歉,我应该更具体一点 - 目前没有隐藏任何行,即使它们应该隐藏。我已经设置了一个示例,其中检查 0 的列有很多存在,但由于某种原因,这些行没有被隐藏。
  • 我还遇到了一个问题,即在检查 ColumnTwo 时所有内容都被隐藏了,即使有很多单元格的值大于 0。
  • 我很确定问题出在支票本身,因为即使 D47:D61 为空,它仍在第一个 if 语句中工作。也许它没有像我最初想要的那样引用工作表? D47:D61 在 ws2 上,但对 1 和 0(以及隐藏自身的行)的检查发生在 ws1 上。
  • lastColumn 在哪里被赋值(向下第 3 行)?在第 4 行添加断点 (wiseowl.co.uk/blog/s196/breakpoints.htm) - 将鼠标悬停在 lastRow 上时的值是多少?此外,如果 IF 语句的第二部分应该检查表 2,则不能使用 .Cells,则需要添加表,例如ws2.Cells

标签: excel vba


【解决方案1】:

我修改了您的代码以确保声明所有变量。

Sub HideRows()
'Ensure you declare all your variables
Dim ws1 As Worksheet, ws2 As Worksheet, lRow As Long
Dim ColumnOne As Integer, ColumnTwo As Integer
Dim dRng As Range, eRng As Range
Dim dRngCnt As Long, eRngCnt As Long

'Assign worksheets and variables
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Sheet2")

'Identifying the specific range as variable
Set dRng = ws2.Range("D2:D9")
Set eRng = ws2.Range("E2:E9")

'Assigning a variable to the countA will simplify your IF and ELSEIF statements
dRngCnt = Application.WorksheetFunction.CountA(dRng)
eRngCnt = Application.WorksheetFunction.CountA(eRng)

    With ws1
        ColumnOne = .Cells(1, .Columns.Count).End(xlToLeft).Column
        'I replaced "lastColumn" with "ColumnOne", because they are the same value, so you only need to use one
        lRow = .Cells(.Rows.Count, ColumnOne).End(xlUp).Row
        ColumnTwo = ColumnOne - 1

        If dRngCnt <> 0 Then 'I use the countA variable for column D Range
            For i = 1 To lRow
                If .Cells(i, ColumnTwo).Value = 0 Then 'Any 0s in the second to last columns will hide the row
                    .Rows(i).EntireRow.Hidden = True
                End If
            Next i

        ElseIf eRngCnt <> 0 Then 'I use the countA variable for column E Range
            For i = 1 To lRow
                If .Cells(i, ColumnOne).Value = 0 Then
                    .Rows(i).EntireRow.Hidden = True
                End If

            Next i
        Else
            Exit Sub

        End If
    End With

End Sub

【讨论】:

  • 是的,单独声明范围似乎是问题所在,我在今天早上早些时候发布的答案中有原始代码的修改版本。只是一个注释,虽然我确实声明了所有变量,但我只是在这里发布了一段代码,因为它是一个更大函数的一部分。如果有必要,我一定会在以后的帖子中包含它,以免引起混淆。
【解决方案2】:

下面的代码现在似乎可以工作了:

With ws1

    ColumnTwo = .Cells(1, .Columns.Count).End(xlToLeft).Column
    LastRow = .Cells(.Rows.Count, lastColumn).End(xlUp).Row

    ColumnOne = ColumnTwo - 1


    With ws2
    Set aDataRange = ws2.Range("D47:D61")
    Set pDataRange = ws2.Range("E47:E61")
        If Application.WorksheetFunction.CountA(aDataRange) <> 0 Then
            MsgBox ("ColumnOne")
            With ws1
                For i = 1 To LastRow
                    If .Cells(i, ColumnOne).Value = 0 Then
                        .Rows(i).EntireRow.Hidden = True
                    End If

                Next i
            End With

        ElseIf Application.WorksheetFunction.CountA(pDataRange) <> 0 Then
            MsgBox ("ColumnTwo")
            With ws1
                For i = 1 To LastRow
                    If .Cells(i, ColumnTwo).Value = 0 Then
                        .Rows(i).EntireRow.Hidden = True
                    End If

                Next i
            End With
        Else
            Exit Sub
        End If
    End With
End With

为什么需要在ws2上单独定义D47:D61/E47:E61的范围区域?为什么“ws2.Application.WorksheetFunction.CountA("Range")”不适用于 ws2 上的范围,即使它包含在“With ws2”中?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 2021-11-22
    • 2019-10-04
    • 2016-06-10
    • 1970-01-01
    相关资源
    最近更新 更多