3

我在 VBA 中使用过滤范围时遇到问题。如果我使用宏来过滤范围,然后使用另一个来调用小计工作表函数以在第一列中找到最小值,我会得到过滤范围的预期最小值;这就是我要的。这显示在这里:

Sub TestFilterTrans()
    Call FilterTrans("111Wall")
End Sub

Sub TestMinDate()
    MsgBox MinTransDate()
End Sub

Sub FilterTrans(Inv As String)
    Range("TransLabels").Select
    Selection.AutoFilter
    ActiveSheet.Range("Trans").AutoFilter Field:=2, Criteria1:=Inv
End Sub

Function MinTransDate()
    MinTransDate = Application.WorksheetFunction.Subtotal(5,     Worksheets("Transactions").Range("TransDates"))
End Function

但是,如果从工作表中,我调用一个函数来首先调用过滤器过程,然后调用一个函数来查找最小值,它会选择整个范围内的最小值,就像未过滤一样,如下所示:

Function IncepDate(Inv As String)
    Dim d As String
    Call FilterTrans(Inv)
    d = MinTransDate()
    Call FilterOff
    IncepDate = d
End Function

谁能告诉我为什么过滤器在第二种情况下似乎不起作用?

4

1 回答 1

1

函数不应操作工作表对象。这里有几个关于该主题的问题,但一致认为从工作表函数中调用子例程来操作工作表对象是一个坏主意。

我逐步执行了一些类似的代码来尝试复制它。

代码执行没有错误,但如果您单步执行,您会发现自动过滤器从未实际应用。

我有理由确定这是设计使然,尽管错误/警告消息会很好。

我之前对类似问题的评论:

单元格引用在 Excel VBA 2010 函数中不起作用

无法从从工作表调用的 UDF 中操作工作表单元格。

更多信息在这里:

https://stackoverflow.com/a/15647054/1467082

和这里:

http://www.excel-it.com/UDF.htm

通常,子程序可以操作工作表,而函数不能。

例外是从子例程中调用的函数(有时)可以,但是将函数用于除向子例程返回值之外的任何事情可能是一个坏习惯。

并且,来自 Microsoft 的大量关于此的文档:

http://support.microsoft.com/kb/170787

由工作表单元格中的公式调用的用户定义函数无法更改 Microsoft Excel 的环境。这意味着这样的函数不能执行以下任何操作:

  • 在电子表格上插入、删除或格式化单元格。
  • 更改另一个单元格的值。
  • 向工作簿移动、重命名、删除或添加工作表。
  • 更改任何环境选项,例如计算模式或屏幕视图。
  • 将名称添加到工作簿。
  • 设置属性或执行大多数方法。

用户定义函数的目的是允许用户创建不包含在 Microsoft Excel 附带的函数中的自定义函数。Microsoft Excel 中包含的功能也不能改变环境。函数可以执行计算,将值或文本返回到输入它们的单元格。任何环境更改都应通过使用 Visual Basic 子例程进行。

在计算过程中,Excel 会检查包含用户定义函数的单元格的先例。如果在计算过程中到目前为止还没有计算出所有先例,Excel 最终会调用用户定义的函数并将 Null 或 Empty 单元格传递给该函数。Excel 然后确保为所有要计算的先例发生足够的计算通过。在最后的计算过程中,用户定义的函数被传递了单元格的当前值。这可能会导致调用用户定义的函数比预期的更频繁,并且使用意外的参数。因此,用户定义的函数可能会返回意外的值。

为了正确计算,计算中使用的所有范围都应作为参数传递给函数。如果您不将计算范围作为参数传递,而不是引用函数的 VBA 代码中的范围,Excel 将无法在计算引擎中考虑它们。因此,Excel 可能无法充分计算工作簿以确保在计算用户定义函数之前计算所有先例。

于 2013-08-28T02:59:00.753 回答