唯一计数(Excel VBA 与公式)更快的方法

Posted

技术标签:

【中文标题】唯一计数(Excel VBA 与公式)更快的方法【英文标题】:Unique Count (Excel VBA vs Formulas) Faster Approach 【发布时间】:2015-11-04 12:01:48 【问题描述】:

64 位 Win7 上的 32 位 Excel 365 工作表 300600 行 x 105 列 目标:计算每列的唯一条目数

尝试的解决方案 1:公式

=SUM(1/COUNTIF(A8:A300600,A8:A300600))

问题:长时间运行,冻结 Excel,必须停止计算

尝试的解决方案 2:VBA UDF

Function UniqueCount(Selection As Range) As Integer
Dim UniqueArray()
ReDim UniqueArray(0 To Selection.Count)
Dim Rng As Range
Dim CUniqueCount As Integer
CUniqueCount = 0
For Each Rng In Selection
    For i = 0 To Selection.Count
        If UniqueArray(i) = Rng.Value Then Exit For
        If UniqueArray(i) = "" Then
            UniqueArray(i) = Rng.Value
            CUniqueCount = CUniqueCount + 1
            Exit For
        End If
    Next i
Next
UniqueCount = CUniqueCount
End Function

注意:这要快得多,但我仍在寻找更快的方法

【问题讨论】:

我没有,我这样做的原因是将数据集分解为较小的表以上传到我的访问数据库中——数据集太大而无法在内部破坏访问的内存限制。我想我也可以通过数据透视表来达到这些限制。它们与我在所有 105 列中应用公式化方法时遇到的限制相同。 【参考方案1】:

我会使用数组和字典:

Public Function CountUnique(rngInput As Range) As Double
    Dim rngCell               As Range
    Dim dData                 As Object
    Dim vData
    Dim x                     As Long
    Dim y                     As Long

    Set dData = CreateObject("Scripting.Dictionary")

    vData = rngInput.Value2
    For x = LBound(vData, 1) To UBound(vData, 1)
        For y = LBound(vData, 2) To UBound(vData, 2)
            If LenB(vData(x, y)) <> 0 Then dData(CStr(vData(x, y))) = Empty
        Next y
    Next x
    CountUnique = dData.Count
End Function

【讨论】:

【参考方案2】:

试试这个

'Set a reference to MS Scripting runtime ('Microsoft Scripting Runtime')
Function UniqueCount(SelRange As Range)
    Dim Rng As Range
    Dim dict As New Scripting.Dictionary
    Set dict = CreateObject("Scripting.Dictionary")
    For Each Rng In SelRange
        If Not dict.Exists(Rng.Value) Then
            dict.Add Rng.Value, 0
        End If
    Next Rng
    UniqueCount = dict.Count
    Set dict = Nothing
End Function

【讨论】:

有趣的是,事后看来,计算的持续时间更多地取决于找到的唯一匹配项的数量,因为嵌套迭代复合了选择迭代,因此当数量较少时,我们的 UDF 执行非常相似唯一值,但是当有大量唯一值时,您的表现要好得多 -- 谢谢!

以上是关于唯一计数(Excel VBA 与公式)更快的方法的主要内容,如果未能解决你的问题,请参考以下文章

访问 VBA - 在大范围内更改 Excel 单元格值的更快方法?

如何在EXCEL中提取唯一值

VBA 学习笔记 使用Excel工作表函数

VBA 学习笔记 使用Excel工作表函数

使用 VBA for Excel 从大量单元格中删除“额外”空格(超过 1 个)的更快方法

从 Excel 与 VBA 调用时,VBA UDF 给出不同的答案