Excel - 计算与ID匹配的唯一值,针对100,000多个案例进行了优化

时间:2017-07-06 21:53:42

标签: excel count excel-formula match unique

参考下面的excel屏幕截图,我正在寻找一个公式解决方案,它计算A列中每个ID号的B列(颜色)中唯一值的数量。

我已将所需结果归入C列。因此,例如,ID 1(A2)只有一种唯一颜色Gray(B2),它会在C2中返回1。 ID 2只有一种唯一的颜色,黄色(B3,B4),并在C3和C4中返回1。 ID 3,有两种独特的颜色,蓝色和紫色,因此在C5到C8中返回2。等

因为这将运行近100,000行,所以我遇到的许多基于索引和/或匹配的解决方案都需要很长时间才能计算出来。我发现ID值都是按升序排列的,可以通过启动= IF的公式(A2 = A1,或类似的东西)来加快速度。提前感谢任何有关如何获得一些想法的人用精益公式解决这个问题。

注意:我正在处理也有近100列的文件。一个不需要辅助列的解决方案将是理想的。

编辑/添加:在我的主数据文件中,B列中有空白单元格的实例。在计算C列结果时是否有办法忽略空白单元格?

enter image description here

2 个答案:

答案 0 :(得分:3)

好的,我使用这个数组公式解决了你的问题:

=SUM(IF(FREQUENCY(IF($A$2:$A$21=A2,MATCH($B$2:$B$21,$B$2:$B$21,0),""),MATCH($B$2:$B$21,$B$2:$B$21,0))>0,1))

将此公式放入单元格C2并按 CTRL + SHIFT + ENTER ,然后拉下公式。如有任何问题,请在下面发表评论

答案 1 :(得分:3)

这是一个VBA例程,应该可以快速运行该数量的条目。我们创建一个类模块(用户定义对象),它由与每个ID关联的颜色集合(Dictionary)和该颜色的计数组成。 (不要真的需要计算,但是如果你想要它用于其他目的,那么添加它是微不足道的;并且还作为一些可以做的事情的演示)。

然后我们在屏幕截图中显示的相邻列中输出结果。结果可以在其他地方输出,即使在不同的工作表上,也可以进行少量的代码更改。

请务必阅读模块开头的注释,以获取重要信息和正确设置。

班级单元

Option Explicit
'RENAME this module:  cID

Private pID As String
Private pColor As String
Private pColors As Dictionary

Public Property Get ID() As String
    ID = pID
End Property
Public Property Let ID(Value As String)
    pID = Value
End Property

Public Property Get Color() As String
    Color = pColor
End Property
Public Property Let Color(Value As String)
    pColor = Value
End Property

Public Property Get Colors() As Dictionary
    Set Colors = pColors
End Property
Public Function ADDColor(Value As String)
    'Might as well also count # of times this color assigned
    If Not pColors.Exists(Value) Then
        pColors.Add Key:=Value, Item:=1
    Else
        pColors(Value) = pColors(Value) + 1
    End If
End Function

Private Sub Class_Initialize()
    Set pColors = New Dictionary
End Sub

常规模块

编辑已编辑以消除空白行的计数

Option Explicit
'Set reference to Microsoft Scripting Runtime (Tools/References)

Sub IDColorCount()
    Dim cID As cID, dID As Dictionary
    Dim wsData As Worksheet, rData As Range
    Dim vData As Variant, vRes As Variant
    Dim I As Long

'Set the data worksheet and range
'Read the data into an array for faster calculations
Set wsData = Worksheets("sheet1")
With wsData
    Set rData = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)).Resize(columnsize:=2)
    vData = rData
End With

'Go through the data and collect the information
Set dID = New Dictionary
For I = 2 To UBound(vData, 1)
  If Not vData(I, 1) = "" Then
    Set cID = New cID
    With cID
        .ID = vData(I, 1)
        .Color = vData(I, 2)
        .ADDColor .Color

        If Not dID.Exists(.ID) Then
            dID.Add Key:=.ID, Item:=cID
        Else
            dID(.ID).ADDColor .Color
        End If
    End With
  End If
Next I

'Size the results array
ReDim vRes(1 To UBound(vData), 1 To 1)
vRes(1, 1) = "Count"
For I = 2 To UBound(vData, 1)
    If Not vData(I, 1) = "" Then _
        vRes(I, 1) = dID(CStr(vData(I, 1))).Colors.Count
Next I

'The results can  be written anyplace
With rData.Offset(0, 2).Resize(columnsize:=1)
    .EntireColumn.Clear
    .Value = vRes
End With

End Sub