简体   繁体   English

Excel VBA 计数包含特定值的行

[英]Excel VBA count rows containing specific values

I'm learning VBA and I have an exercise that I find difficult to solve.我正在学习 VBA,我有一个练习很难解决。 Here's an example of the main table:这是主表的示例:

   A        B      C       D
 person   team   date     task
--------------------------------
  toms      A    10/08     t1
  toms      A    10/08     t2
  toms      A    10/08     t3
  harry     B    10/08     t4
  harry     B    10/08     t5
  harry     B    11/08     t6
  toms      A    11/08     t7
  toms      A    11/08     t8
  jhon      B    11/08     t9

The goal is to count the number of tasks per person per day.目标是统计每人每天的任务数。 The result should look like this:结果应如下所示:

  A        B      C        D
 person   team   date     total    
--------------------------------
  toms      A    10/08      3
  toms      A    11/08      2
  harry     B    10/08      2
  harry     B    11/08      1
  jhon      B    11/08      1

I thought of using a dictionary but it seems like you can only use one key in a dictionary.我想过使用dictionary ,但似乎你只能在字典中使用一个键。 Is there a specific VBA function that can help me solve this problem?有具体的VBA function可以帮我解决这个问题吗?

Like @Scott Craner said, you could set up a PivotTable like this:正如@Scott Craner 所说,您可以像这样设置一个数据透视表:

在此处输入图像描述

I would use a Pivot Table (or Power Query) solution for this problem, but for an approach using dictionaries (since you are learning techniques) I suggest the following.对于此问题,我会使用 Pivot 表(或 Power Query)解决方案,但对于使用字典的方法(因为您正在学习技术),我建议如下。

  • Create a dictionary with the key being your major separation.创建一个字典,键是你的主要分离。 In your case, it appears it would name|team .在您的情况下,它似乎会name|team
  • This dictionary will store another dictionary with key=theDate and item=theCount该字典将存储另一个字典,其中 key=theDate 和 item=theCount
  • work in VBA arrays for speedier processing (useful on large data sets)在 VBA arrays 中工作以加快处理速度(对大型数据集有用)
  • qualify your various worksheet and range references.限定您的各种工作表和范围参考。
'Set reference to Microsoft Scripting Runtime
Option Explicit
Sub countTasks()
    Dim dPerson As Dictionary, dDate As Dictionary
    Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
    Dim vSrc As Variant, vRes As Variant
    Dim I As Long, sKeyP As String, dKeyDt As Date
    Dim V As Variant, W As Variant
    
'set worksheets, ranges, and read source data into variant array for processing speed
Set wsSrc = ThisWorkbook.Worksheets("sheet10")
Set wsRes = ThisWorkbook.Worksheets("sheet10")
    Set rRes = wsRes.Cells(1, 10)
    
With wsSrc
    vSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)).Resize(columnsize:=4)
End With

'iterate through the data and store the results
Set dPerson = New Dictionary
    dPerson.CompareMode = TextCompare 'case insensitive
    
For I = 2 To UBound(vSrc, 1)
    sKeyP = vSrc(I, 1) & "|" & vSrc(I, 2) 'will give different count for same name, different teams
    dKeyDt = vSrc(I, 3)
    
    If Not dPerson.Exists(sKeyP) Then
        Set dDate = New Dictionary
        dDate.Add Key:=dKeyDt, Item:=1
        dPerson.Add Key:=sKeyP, Item:=dDate
    Else
        With dPerson(sKeyP)
            If Not .Exists(dKeyDt) Then
                .Add Key:=dKeyDt, Item:=1
            Else
                .Item(dKeyDt) = .Item(dKeyDt) + 1
            End If
        End With
    End If
Next I
                
'Format and output the results
I = 0
For Each V In dPerson.Keys
    For Each W In dPerson(V)
        I = I + 1
    Next W
Next V

ReDim vRes(0 To I, 1 To 4)

'headers
vRes(0, 1) = "Person"
vRes(0, 2) = "Team"
vRes(0, 3) = "Date"
vRes(0, 4) = "Count"

'data
I = 0
For Each V In dPerson.Keys
    For Each W In dPerson(V)
        I = I + 1
        vRes(I, 1) = Split(V, "|")(0)
        vRes(I, 2) = Split(V, "|")(1)
        vRes(I, 3) = W
        vRes(I, 4) = dPerson(V)(W)
    Next W
Next V

'write the results to the worksheet and format
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
With rRes
    .EntireColumn.Clear
    .Value = vRes
    .Columns(3).NumberFormat = "dd/mmm/yyyy"
    With .Rows(1)
        .Font.Bold = True
        .HorizontalAlignment = xlCenter
    End With
    .EntireColumn.AutoFit
End With
    
End Sub

在此处输入图像描述

在此处输入图像描述

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

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