【发布时间】:2019-05-16 15:36:49
【问题描述】:
我有一个这样的电子表格:
A1: APPLE
A2: BANANA
A3: ORANGE
A4: APPLE
A5: BANANA
A6: ORANGE
(一直重复到 A20)
所以这个公式会计算“APPLE”的所有实例:
=COUNTIF(A1:A20, "APPLE")
而且这个公式的作用相同,只是范围不连续:
=SUM(COUNTIF(INDIRECT({"A1:A6", "A8:A20"}), "APPLE"))
INDIRECT 函数采用array constant,范围定义为字符串。请注意花括号和每个范围周围的引号。 (这是基于here 描述的技术。)
但是,如果我定义一个返回字符串数组并将 that 传递给 INDIRECT 的 VBA 函数,似乎只考虑第一个范围。
这是我的 VBA 函数:
Function TestFn() As Variant
TestFn = Array("A1:A6", "A8:A20")
End Function
这是我的公式:
=SUM(COUNTIF(INDIRECT(TestFn()), "APPLE"))
如果我使用 Excel 的“评估公式”按钮,我可以看到 TestFn() 解析为单个字符串“B1:B6”。但是,如果我使用 VBA 调试器,我会看到两个字符串都在其中。
Expression Value Type
TestFn Variant/Variant(0 to 1)
- TestFn(0) "B1:B6" Variant/String
- TestFn(1) "B8:B20" Variant/String
如何从 Excel VBA 函数返回一个字符串数组,该函数可以以相同的方式传递到 INDIRECT?
我认为这归结为:在没有 VBA 的情况下构造公式时使用花括号创建了哪些内部对象,我可以从 VBA 中创建相同的内部对象吗?
我也尝试过返回字符串数组,而不是包含字符串数组的变体。
Function TestFn() As String()
TestFn = Split("B1:B6,B8:B20", ",")
End Function
这些是调试器中的类型:
Expression Value Type
TestFn String(0 to 1)
- TestFn(0) "B1:B6" String
- TestFn(1) "B8:B20" String
但结果是一样的。我想我需要使用某种容器类型,但我不确定该使用什么或如何弄清楚该使用什么。
如果有更好的方法,我实际上不需要使用SUM...INDIRECT hack,如果合适的话,我很乐意使用数组公式。
如果我可以让我的函数直接返回范围,而不是表示范围的字符串,那将比我目前的方法更好。
如果我可以设置一个类似这样的数组公式(不必完全像这样):
{=COUNTIF(TestFn(), "APPLE")}
然后让我的 UDF 看起来像这样:
Function TestFn() As Range()
TestFn = Array(Range("A1:A6"), Range("A8:A20"))
End Function
或者可能是这样的:
Function TestFn() As Range
TestFn = Union(Range("A1:A6"), Range("A8:A20"))
End Function
这将满足我的需要。
这里的关键是我只希望我的 VBA 只定义哪些单元格被操作,而不是操作是什么,我想处理非连续范围。我希望在 excel 公式中定义实际操作,因为这些操作将被不希望了解如何读写 VBA 代码的人修改。 (哎呀,我也不想再看 VBA 代码了。)在这种情况下,我使用的是 COUNTIF,但我的 VBA 函数也将与其他 excel 公式函数一起使用。
【问题讨论】:
-
如果有人想知道“为什么?”:我的真实数据在过滤表中。 VBA 函数将一个范围作为输入并返回该范围的当前可见的子集(即未过滤掉)。我想使用尽可能少的 VBA 并将大部分逻辑保留在 excel 中。我将使用 SUM...INDIRECT 技巧和几个不同的 excel 函数,而不仅仅是 COUNTIF,所以简单地制作 COUNTIF 的“变体”不是很可持续。
-
您是否使用 Ctrl+Shift+Enter 作为数组公式输入了
=SUM(COUNTIF(INDIRECT(TestFn()), "APPLE"))?因为这适用于我的原始版本TestFn。 -
不同之处在于您需要将其作为数组公式输入到 excel 工作表中(它将获取两个范围)和 vba,如果您要在 vba 中使用不带花括号的
.evaluate这个相同的公式它被自动识别为数组公式。 -
@BigBen 我没有,就像普通公式一样。我不知道存在数组公式。我将阅读数组公式,看看它们是否符合我的目的。但是,我仍然很好奇为什么非 VBA 公式可以像普通公式一样工作,以及我是否可以用 VBA 复制它。
-
@JvdV 我正在努力理解您所描述的内容,但恐怕它已经超出了我的想象。
标签: excel vba excel-formula