简体   繁体   English

在 Excel VBA 中组合两列获取唯一计数

[英]Get unique count combining two columns in Excel VBA

I have an excel with columns我有一个带列的excel

ID|Gender|Age|Center
1    M     20  Center1
1    M     24  Center1
2    M     25  Center2
3    F     30  Center2 
4    F     25  Center1

Total Males -   2   Total Males in Center1 - 1 
Total Females - 2   Total Females in Center2 - 1 

I want to count the unique combination of Id and Gender.我想算一下 Id 和 Gender 的独特组合。 Also, the same info required as center-wise.此外,需要与中心相同的信息。

Below is my code I am using but I am getting the 0 value in the required cell.下面是我正在使用的代码,但我在所需的单元格中获得了 0 值。

 Sub CountPopulation() 
 Dim rCell As Range  
 Dim rRng As Range    
 Dim countM As Integer  
 Dim countF As Integer  
 Dim name As String
Set rRng = Sheet1.Range("D2:D100") 

      For Each rCell In rRng.Cells
        If rCell.Value > name Then
            If rCell.Offset(0, 2).Value = "MALE" Then
                countM = countM + 1
            End If
            If rCell.Offset(0, 2).Value = "FEMALE" Then
                countF = countF + 1
            End If
        End If
        name = rCell.Value

      Next rCell


      Sheet2.Range("D4").Value = countM   Sheet2.Range("D5").Value = countF


    End Sub

Thanks谢谢

If you already have the new dynamic arrays, this is a pretty easy task.如果您已经拥有新的动态数组,这是一项非常简单的任务。 The formula to count unique combinations of ID and Gender would be:计算 ID 和 Gender 的唯一组合的公式是:

=COUNTA(UNIQUE(A2:A6&B2:B6))

This formula first forms a unique list of (concatenated) IDs and genders, which looks such for you:这个公式首先形成一个唯一的(连接的)ID 和性别列表,看起来像这样:

虚数组 UNIQUE 函数

Then the COUNTA function will count the number of rows.然后COUNTA函数将计算行数。

To apply this in VBA, you might use Evaluate() , something like this:要在 VBA 中应用它,您可以使用Evaluate() ,如下所示:

lUniqueCombinationsOfIDandGender = Evaluate("=COUNTA(UNIQUE(A2:A6&B2:B6))")

If you want to have the unique combinations of centers and ID, you can change the formula to:如果您想拥有中心和 ID 的唯一组合,您可以将公式更改为:

=COUNTA(UNIQUE(A2:A6&D2:D6))

I assume that you do not have any blank rows in your data (otherwise, you will count one combination more than you actually have).我假设您的数据中没有任何空白行(否则,您计算的组合数将比实际数多)。

I hope that helps you.我希望这对你有帮助。

If you really want to do it with VBA, this code helps you:如果你真的想用 VBA 来做,这段代码可以帮助你:

Option Explicit

Sub test()
Dim a As Integer, b As Integer, c As Integer
Dim D() As String, e As Integer, f As Integer

Range("A2").Select
a = Selection.End(xlDown).Row

ReDim D(2 To a)

For b = 2 To a
    D(b) = Cells(b, 1).Value & Cells(b, 2).Value
Next b

e = a - 1

For b = 2 To a
    f = D(b)
    For c = (b + 1) To a
        If f = D(c) Then
        e = e - 1
        Exit For
        End If
    Next c
Next b
MsgBox "Unique combinations: " & e

End Sub

The steps are as follows: 1. Count the last row used 2. Redimension the D array accordingly 3. For each row fill each D() with a string of the entrys of both columns 4. Set e = a - 1 (first assuming, all combinations are unique) 5. For all Rows: Compare its content with those of the following rows, until a match happens.步骤如下: 1. 计算使用的最后一行 2. 相应地重新调整 D 数组 3. 对于每一行,用两列条目的字符串填充每个 D() 4. 设置 e = a - 1(首先假设,所有组合都是唯一的) 5. 对于所有行:将其内容与以下行的内容进行比较,直到匹配发生。 Then move on with the next row.然后继续下一行。

Hope, this is helpfull to you.希望,这对你有帮助。

I think this will solve what (I understood) you need:我认为这将解决您需要的(我理解):

  Dim rngVal As Variant, sh As Worksheet, El As Variant, boolM As Boolean, boolF As Boolean, i As Long
  Dim colM1 As New Collection, colM2 As New Collection, colF1 As New Collection, colF2 As New Collection

    Set sh = ActiveSheet 'not recommended but just for testing sake it is OK
    rngVal = sh.Range("A2:D" & sh.Range("A1").SpecialCells(xlCellTypeLastCell).Row).value

    For i = 1 To UBound(rngVal)
        boolM = False: boolF = False
        If rngVal(i, 4) = "Center1" Then
            If rngVal(i, 2) = "M" Then
                For Each El In colM1
                    If El = rngVal(i, 1) & rngVal(i, 1) Then boolM = True: Exit For
                Next
                If Not boolM Then colM1.Add rngVal(i, 1) & rngVal(i, 1): boolM = False
            ElseIf rngVal(i, 2) = "F" Then
                For Each El In colF1
                    If El = rngVal(i, 1) & rngVal(i, 1) Then boolF = True: Exit For
                Next
                If Not boolF Then colF1.Add rngVal(i, 1) & rngVal(i, 1): boolF = False
            End If
        ElseIf rngVal(i, 4) = "Center2" Then
            If rngVal(i, 2) = "M" Then
                For Each El In colM2
                    If El = rngVal(i, 1) & rngVal(i, 1) Then boolM = True: Exit For
                Next
                If Not boolM Then colM2.Add rngVal(i, 1) & rngVal(i, 1): boolM = False
            ElseIf rngVal(i, 2) = "F" Then
                For Each El In colF2
                    If El = rngVal(i, 1) & rngVal(i, 1) Then boolF = True: Exit For
                Next
                If Not boolF Then colF2.Add rngVal(i, 1) & rngVal(i, 1): boolF = False
            End If
        End If
    Next i
    Debug.Print "Total males : " & colM1.Count + colM2.Count
    Debug.Print "Total females: " & colF1.Count + colF2.Count
    Debug.Print "Males in Center1: " & colM1.Count, "Males in Center 2: " & colM2.Count
    Debug.Print "Females in Center1: " & colF1.Count, "Females in Center2: " & colF2.Count

The code puts the working range in a (variant) array and start processing.该代码将工作范围放在(变体)数组中并开始处理。 Each "M" and "F" of Center1 is added in appropriate collections (colM1, colF1) if they do not already exists there and does the same with Center2 members.如果 Center1 的每个“M”和“F”在适当的集合(colM1、colF1)中尚不存在,并且对 Center2 成员执行相同的操作,则会将它们添加到适当的集合(colM1、colF1)中。 Finally, the results are returned from the above mentioned collections using their `Count' property.最后,使用它们的 `Count' 属性从上面提到的集合中返回结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM