【问题标题】:Detect Autofilter changes检测自动过滤器更改
【发布时间】:2016-12-20 19:10:22
【问题描述】:

我希望检测特定表上自动过滤器中的任何更改,以强制 UDF 对当前可见的表条目执行一些简单的算术运算以更新其结果。到目前为止,使 UDF 易失性没有任何影响,但它也不直接针对表。

这个解决方案 (https://stackoverflow.com/a/15906275/4604845) 对我不起作用,可能是因为我只有手动计算。

我有点太脏的解决方法是Workbook_SelectionChange,虽然 UDF 不会以这种方式杀死资源消耗,但我宁愿避免它,以防数据变得更大。此外,我有一些用户在使用计算机方面完全是新手,我无法确信我能让他们所有人都明白,他们需要在更新自动过滤器后单击其他内容才能使结果正确。

有什么想法吗?我尝试过Workbook_ChangeWorkbook_Calculate,但它们都没有被自动过滤器更改触发(或者我不知道如何触发它们)。

【问题讨论】:

  • 语法应该是=SUBTOTAL( 3, TableName[Field] )而不是=SUBTOTAL( 3, tableName),并且它应该在用户每次点击[F9]时重新计算
  • 是的,我知道语法。对不起,如果我之前不清楚。我设计的公式在显示所需信息方面工作得很好,我只是在努力使其在我的工作簿的限制内自动更新。
  • 按下[F9]时他们“更新”了吗?
  • 是的,如果我选择退出 EnableCalculation = False。我知道这会更新工作表,但它不像我希望的那样自动......而且开销很大,看看我在该特定工作表上的一些 10k + 功能区域中的情况。但即使有开销,它也是可行的,因此它仍然是几种可能的备份解决方案之一。
  • 我已经有了答案,但在发布之前我还有一个问题:如果计算设置为Manual,除了尝试检测AutoFilter 的更改之外,用户如何确保在任何其他情况下更新计算(即对数据执行更改但对AutoFilter 没有更改您在所有其他情况下使用Worksheet_Events 吗?

标签: excel vba


【解决方案1】:

即使您在工作表上没有其他公式,如果您在引用表格的工作表的某处包含 Subtotal() 公式,Subtotal() 也会重新计算每次更改自动过滤器时。

您可以使用它来触发 Calculate() 事件宏。

编辑#1:

假设我们在名为 data 的工作表的 A 列上设置了自动筛选。工作表 data 还包含许多其他公式。如果我们在 data 工作表中使用 Calculate() 事件,我们将在任何时候 any 这些公式重新计算时触发。 p>

我们创建一个名为 trigger 的新工作表。这个新工作表完全为空,除了一个包含以下内容的单元格:

=SUBTOTAL(3,data!A1:A20)

我们在 trigger 工作表中放置了 Calculate() 事件宏。

现在如果我们使用 data 工作表,我们可以进行任意更改并执行各种重新计算并且不会触发任何事件,但是如果我们更改 AutoFilter,trigger上的事件宏> 会看到变化并开火!

【讨论】:

  • 你的意思是=SUBTOTAL(3, tableName)?我也试过这个,但小计不会重新计算。再加上 text-to-column 似乎不适用于语言本地化函数这一事实,这就是我最初编写 UDF 的动机。
  • 如果你将计算设置为手动,公式自然不会重新计算...
  • 这也是我的理解,这就是我试图找到解决方法的原因。
  • 这是检测表(ListObjects)何时被过滤的好方法,无论是在表上还是通过切片器...
  • @aSystemOverload 我同意,但是如果你的工作表中有很多公式,你的代码必须能够区分假命中和真命中......
【解决方案2】:

如何在手动计算中触发自动筛选更改后的工作表计算

据我们所知,无法自动检测到AutoFilter 选择的更改,因为这些更改不会触发任何Workbook EventWorksheet Event。因此,唯一可用的选项是让用户通过操作触发工作表计算,即单元格选择更改、右键单击、双击等;或者只需按[F9];这是更可取的操作,因为不涉及任何其他内容,而且这是它的设计工作方式。

尽管如此,根据用户的要求,我提供了这个 VBA 代码,虽然需要通过用户的操作来启动,但可以在选择 AutoFilter 更改后立即执行此操作,只需双击即可。

DoubleClick 可以不受限制(双击工作表中的任何单元格) 使用以下代码:

Private Sub Worksheet_BeforeDoubleClick(ByVal rTrg As Range, blCancel As Boolean)
    rTrg.Worksheet.Calculate
End Sub

或设置最多三种类型的限制:

  1. 表格的任何单元格

  2. 表头

  3. 表格主体

使用此代码限制DoubleClick 区域: 当前代码设置为限制类型1,使用变量bRType 将其更改为首选类型。此代码假定表的名称是Table1 (根据需要更改)

Private Sub Worksheet_BeforeDoubleClick(ByVal rTrg As Range, blCancel As Boolean)
Dim ObjLst As ListObject, rTbl As Range, bRType As Byte

    Rem Set Restriction Type
    Rem 1: DoubleCliking any cell of the Table - Default
    Rem 2: DoubleCliking any cell of the Table Header
    Rem 3: DoubleCliking any cell of the Table Body
    bRType = 1

    With rTrg
        Set ObjLst = .Worksheet.ListObjects("Table1")

        Select Case bRType
        Case 2:     Set rTbl = ObjLst.HeaderRowRange
        Case 3:     Set rTbl = ObjLst.DataBodyRange
        Case Else:  Set rTbl = ObjLst.Range
        End Select

        If Not (Intersect(.Cells, rTbl) Is Nothing) Then
            .Worksheet.Calculate
            blCancel = True
        End If
    End With
End Sub

这两个过程都是工作表事件,因此请确保您决定实施的过程进入包含表格的工作表模块。 (不要更改程序的名称)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    相关资源
    最近更新 更多