【问题标题】:Excel VBA: If Statement on Filtered RangeExcel VBA:过滤范围的If语句
【发布时间】:2016-07-14 21:48:00
【问题描述】:

我有一系列数据,我在 C 到 K 列中过滤“是”,一次一列。过滤范围后,我想逐行检查第 2 列的字母“R”或“C”。如果有 R,我将 1 加到 R_counter 和 Cs 中。不幸的是,我的柜台得到了完全古怪的数字。我怀疑当我过滤范围并告诉它检查第 2 行到剩下多少行时,它可能与它有关,它正在检查实际的行号,而不仅仅是向下移动一行,如果这有意义的话。有任何想法吗?

*注意:如果我的描述没有意义:基本上,我对 R 或 C 是​​否有更多的标题 1-9 感兴趣。

这是我得到的和我期望得到的:

For z = 3 To LstSpecCol 
        R_counter = 0
        C_counter = 0
        If (WS_Sel.AutoFilterMode And WS_Sel.FilterMode) Or WS_Sel.FilterMode Then
        WS_.ShowAllData
        End If

        WS_Sel.Range(WS_Sel.Cells(1, 1), WS_Sel.Cells(counter + 1, LstCol1)).AutoFilter _
        Field:=z, Criteria1:="Yes"

        With WS_Sel
        Set rngFilter_Yes = Intersect(.UsedRange, .UsedRange.Offset(1), _
        .Columns(z)).SpecialCells(xlCellTypeVisible)
        LstRow_Yes = rngFilter_Yes.Cells.Count
        End With

        For t = 2 To LstRow_Yes
           If WS_Sel.Cells(t, 2) = "R" Then
            R_counter = R_counter + 1
           Else
            C_counter = C_counter + 1
           End If
        Next t
    Next z

【问题讨论】:

  • 您的预期输出是什么?可以发一下吗

标签: vba excel


【解决方案1】:

我稍微重构了代码并对其进行了测试以产生所需的结果。

值得注意的是:

  • 我循环遍历FilteredRange 中的每个Cell(问题中的写法是将每个Row 从2 循环到filteredrange 的末尾,这是在过滤器之外拾取行。李>
  • 我使用Select Case 来测试RC(主要是因为我认为它更干净)。
  • 我使用过滤范围内的第 2 列直接测试R/C ? 列。
  • 我将整个内容放在 With 中,以帮助它更快地处理。

代码:

With WS_Sel

    For Z = 3 To LstSpecCol

        R_Counter = 0
        C_Counter = 0

        If (.AutoFilterMode And .FilterMode) Or .FilterMode Then
            .ShowAllData
        End If

        .Range(.Cells(1, 1), .Cells(counter, LstCol1)).AutoFilter Field:=Z, Criteria1:="Yes"

        Set rngFilter_Yes = Intersect(.UsedRange, .UsedRange.Offset(1), .Columns(2)).SpecialCells(xlCellTypeVisible)

        For Each cel In rngFilter_Yes
            Select Case cel
                Case Is = "R": R_Counter = R_Counter + 1
                Case Is = "C": C_Counter = C_Counter + 1
            End Select
        Next cel

    Next Z

End With

【讨论】:

  • 效果很好。非常感谢!
【解决方案2】:

这必须在 VBA 中完成吗?使用 COUNTIFS 函数,问题在工作表上变得异常简单。

例如对于“header1”列,您可以编写=COUNTIFS(B2:B6,"R",C2:C6,"Yes") 来计算所有 R/C 为“R”且 header1 为“Yes”的实例。相同的想法可以推广到“C”和其他标题。

如果必须在 VBA 中完成,您可以使用 Application.Evaluate 通过代码获得相同的结果。

【讨论】:

    【解决方案3】:

    一个问题是 LstRow 不会返回行数,只返回过滤后剩余的结果数(行仍然保留但隐藏在两者之间)

    如果您将 LstRow_Yes 编辑为实际上是表的最后一行(未过滤),那么您可以像这样编辑内部 for 循环:

    For t = 2 To LstRow_Yes
        If Not Range("B" & t).EntireRow.Hidden Then
            If WS_Sel.Cells(t, 2) = "R" Then
                R_counter = R_counter + 1
            Else
                C_counter = C_counter + 1
            End If
        End If
    Next t
    

    这将确保您只计算过滤后的可见行。

    另一种方法是使用 =COUNTIFS($B$2:$B$5;"R";C$2:C$5;"Yes") 在不使用 VBA 的情况下获得相同的结果

    【讨论】:

    • 您是否在想要结果的单元格中尝试COUNTIFS?请注意,如果结果在另一张纸上,您必须写 =COUNTIFS(NAMEOFSHEET!$B$2:$B$5;"R";NAMEOFSHEET!C$2:C$5;"Yes),在其中将 NAMEOFSHEET 替换为该纸的实际名称。 (并保留!)
    猜你喜欢
    • 2013-08-15
    • 1970-01-01
    • 2014-01-07
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    相关资源
    最近更新 更多