【问题标题】:VBA, Excel - iterating through cells selected in filtered columnVBA,Excel - 遍历过滤列中选择的单元格
【发布时间】:2015-12-03 10:24:16
【问题描述】:

在包含数据的工作表中,有一列应用了过滤器来限制显示的数据。用户在一列中选择 1 个或多个单元格(不一定是连续的)并执行 VBA 代码。 在 VBA 代码中,我想遍历选定的单元格并对它们进行一些操作,但是当只选择 1 个单元格时(在 Excel 术语中是活动的),Excel 的行为会有所不同。有效的代码:

Sub Macro1()
    If Selection.count = 1 Then
        counter = 1
        Debug.Print Selection.Text
    Else
        counter = Selection.SpecialCells(xlCellTypeVisible).count
        For Each c In Selection.SpecialCells(xlCellTypeVisible)
             Debug.Print c.Text
        Next c
    End If
    Debug.Print counter
End Sub

问题: 有没有办法,更优雅,更干净的解决方案来做到这一点?摆脱 If-Then?

Selection.SpecialCells(xlCellTypeVisible).count

如果只激活一个单元格会产生溢出错误(我认为 Excel 会将选择扩展到整个工作表)

ActiveCell.Select
Selection.SpecialCells(xlCellTypeVisible).count

如果只选择了一个单元格,则返回 2(返回选择的记录两次)

编辑 请注意:过滤器由用户手动应用,而不是由 VBA 代码应用。用户还可以从过滤视图中手动选择单元格,然后在 VBA 代码中使用选定的单元格。

【问题讨论】:

  • 所以....您正在从可见标题中移出一行并调整范围以使用.Rows.Count-1...进行处理?然后查看单个列...?尽量避免将Selection 作为确定要处理的范围的手段。无论如何,应该是Selection.SpecialCells(xlCellTypeVisible).Count 而不是Selection.Count
  • 否,用户在过滤表中选择了 1 到多个单元格。该选择是宏必须使用的。标题在这里并不重要。正如我写的,Selection.SpecialCells(xlCellTypeVisible).Count 如果用户只选择了一条记录就不起作用。

标签: vba excel


【解决方案1】:

以下内容基于此示例数据。

     Column A   Column A   Column C
      a           b           c
1    AA-01       BB-01        1
2    AAA-02      BBB-02       2
3    AAAA-03     BBBB-03      2

这些是我用于AutoFilter Method 的方法。我在处理一个或多个可见行时没有任何问题,并且不需要区分过滤器集。

Sub filter_test()
    With Worksheets("Sheet16")  '<~~set this properly
        If .AutoFilterMode Then .AutoFilterMode = False
        With .Cells(1, 1).CurrentRegion
            .AutoFilter field:=3, Criteria1:=1
            'report on column A
            With .Resize(.Rows.Count - 1, 1).Offset(1, 0)
                If CBool(Application.Subtotal(103, .Cells)) Then
                    reportVisibleCells visRng:=.Cells
                Else
                    Debug.Print "no visible cells with 1"
                End If
            End With
            .AutoFilter field:=3
            .AutoFilter field:=3, Criteria1:=2
            'report on column B
            With .Resize(.Rows.Count - 1, 1).Offset(1, 1)
                If CBool(Application.Subtotal(103, .Cells)) Then
                    reportVisibleCells visRng:=.Cells
                Else
                    Debug.Print "no visible cells with 2"
                End If
            End With
            .AutoFilter field:=3
            .AutoFilter field:=3, Criteria1:=3
            'report on column C
            With .Resize(.Rows.Count - 1, 1).Offset(1, 2)
                If CBool(Application.Subtotal(103, .Cells)) Then
                    reportVisibleCells visRng:=.Cells
                Else
                    Debug.Print "no visible cells with 3"
                End If
            End With
            .AutoFilter field:=3
        End With
        If .AutoFilterMode Then .AutoFilterMode = False
    End With
End Sub

Sub reportVisibleCells(visRng As Range)
    Dim vr As Range

    With visRng.SpecialCells(xlCellTypeVisible)
        For Each vr In .Cells
            Debug.Print vr.Text
        Next vr
        Debug.Print .Count
    End With
End Sub

设置您的桌面,以便您可以同时看到工作表和 VBE 窗口。打开 VBE 的即时窗口 (Ctrl+G),您可以看到 Debug.Print 报告。将光标放在filter_test 子上,然后开始按 F8 浏览。

来自 VBE 的即时窗口的预期结果。

AA-01
 1 
BBB-02
BBBB-03
 2 
no visible cells with 3

【讨论】:

  • 感谢您的回答,但您假设过滤器是通过代码应用来计算可见记录数的。事实并非如此。用户手动进行单元格的过滤和选择。然后执行 VBA 代码。所以用户选择是VBA代码的输入。我想以统一的方式遍历选定的单元格。
  • 你是说不能把Selection作为参数扔到reportVisibleCells sub中?
  • 我可以,但是当只选择 1 个单元格(实际上只激活)时,Excel 选择整个工作表作为范围,并且 reportVisibleCells 需要永恒结束。此处描述了类似的问题 [link]excelforum.com/excel-programming-vba-macros/…
【解决方案2】:

循环选定单元格并用当前日期填充它们的简单方法。
询问已包含内容的单元格是否正常。

子日期() 调暗作为范围 d = Date$ ' 乱码 d = Right(d, 4) + "-" + Mid(d, 4, 2) + "-" + Left(d, 2) ' 使 ISO'ish 设置 r = Application.Selection 对于 i = 1 到 r.Cells.Count 答案 = 1 如果 r.Cells(i).Value "" 那么 ans = MsgBox("删除 " + r.Cells(i).Text + ", 设置为 " + d, vbOKCancel) 万一 如果 ans = 1 那么 r.Cells(i).Value = d 万一 接下来我 结束子

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    相关资源
    最近更新 更多