具有类似sumif标准功能的Excel VBA自定义功能

时间:2009-11-04 02:11:12

标签: excel vba excel-vba

在Excel中,我在VBA中编写一个自定义函数,需要采用标准字符串和条件范围,如内置SUMIF函数。 Excel是否公开了在其API中的任何位置测试条件字符串的功能,或者我是否必须自己编写它?

如果它是相关的,我正在编写一个“CountUniquesIf”公式,如果它们符合标准,它会计算范围内的唯一值。这是我到目前为止所做的。

Function CountUniquesIf(CondRange As Range, Criteria As String, _
    Range As Range) As Long

    Static dict As New Scripting.Dictionary
    Dim index As Long

    index = 1
    For Each Cell In Range.Cells
        If CondRange(index).Value = Criteria And Cell.Value <> "" Then
            dict(Cell.Value) = Empty
        End If
        index = index + 1
    Next Cell

    CountUniquesIf = dict.Count
    dict.RemoveAll
End Function

4 个答案:

答案 0 :(得分:2)

如果你愿意的话,你可以用常规公式完成整个事情。

请参阅:

http://www.officearticles.com/excel/count_unique_values_in_microsoft_excel.htm

http://office.microsoft.com/en-us/excel/HP030561181033.aspx

但是,您需要稍微修改公式,以涵盖您的方案中的“if”部分:

=SUM(IF(FREQUENCY(IF((LEN(A1:A15)>0)*(B1:B15=D4),MATCH(A1:A15,A1:A15,0),""), IF((LEN(A1:A15)>0)*(B1:B15=D4),MATCH(A1:A15,A1:A15,0),""))>0,1))

Where A1:A15 is your Range, B1:B15 is your CondRange, and D4 is your Criterion.

请记住将其作为数组公式输入(粘贴公式并按Ctrl-Shift-Enter而不是Enter)。

那就是说,我认为你的VBA公式也是一个很好的解决方案(每次需要这种类型的计数时,可能比创建怪物数组公式更加用户友好。)

<强>更新

鉴于你的澄清,我真的不认为有一个内置的“标准分析器”,但我认为增强你的公式以涵盖不同的可能标准并不太难。这样,您的CountUniquesIf公式将真正做到人们认为的做法。具体来说,你可以做一些检查,检查所有可能的运算符(除了“=”,“&gt;”,“&gt; =”,“&lt;”,“&lt; =”?)之外还有什么可能是在值之前加前缀。

答案 1 :(得分:1)

根据澄清评论,我认为最简单的方法是传递一个布尔值数组,这些值是通过在工作表中使用数组公式得到的,然后只测试它们。

也就是说,不是传入范围和标准,如b2:b15和“&gt; 0”,而是传递b2:b15> 0的结果,这将是一个数组或布尔值。那么你在函数中的测试就可以

If CondRange(index).Value And Cell.Value <> "" Then

一切都应该按照你想要的方式运作。记得以数组公式的形式输入对UDF的调用。

可以将Application.Evaluate与字符串一起使用,但这样做有很多限制,似乎使用数组公式来进行标准测试在这种情况下更简单

答案 2 :(得分:1)

非VBA方式:

{=SUM(1/COUNTIF($A$2:$A$1001,$A$2:$A$1001)*(LEFT(A2:A1001)="C"))}

这将计算A2:A1001中以“C”开头的唯一身份

对于VBA,请考虑使用Application Object的Evaluate方法

If Asc(Left(Criteria, 1)) >= 60 And Asc(Left(Criteria, 1)) <= 62 Then
    bPass = Application.Evaluate(CondRange(Index).Value & Criteria)
Else
    bPass = CondRange(Index).Value = Criteria
End If

答案 3 :(得分:0)

自从我切换到vista之后,我即将上交并擅长崩溃。但我明天会在办公室看这个。你可能会在工作表函数上找到一个'包装器'.SumIf如果那不适合你在这里发布它。但是有一些问题/建议:即使它会起作用,使用像'Range'或'Cell'这样的变量名称也会让人感到困惑。在处理重复项时,如何在dict中保留唯一值并不是很明显。你会反对把它分解成2个函数吗?一个返回符合条件的值数组,另一个来计算该数组的唯一成员?你测试过脚本的旧版本了吗? 'CondRange(index)'语法对我来说很奇怪。也许它很好,我从来没有使用它(除了数组之类的,不是范围)。如果您已经有标准,为什么还需要测试空单元格或零长度字符串?标准是否可以表达为正则表达式? ['现在你有2个问题'哈哈哈..]你能给出标准和一些虚拟数据的例子吗?您是否尝试录制Data \ Filter \ Advanced Filter菜单序列?它具有列表范围,条件范围和唯一值选项。只要它符合您的标准,就必须有一种方法在您的函数中“包装”它。如果您的标准不是太复杂,请查看“Like”运算符的帮助。希望其中一些对您有所帮助。我看到你习惯了一种更具表现力的语言。