Excel VBA,循环求和,然后使用每个新值重新计数

Excel VBA,循环求和,然后使用每个新值重新计数,vba,excel,Vba,Excel,对于商店中的每个员工,都有一项任务。如果员工完成了任务,则在“车间”的“任务”列中有“1”。我必须对每个车间的所有“1”进行求和,并检查每个车间完成任务的总百分比。举例如下: Shop Task 1002 0 1002 1 1002 0 1002 0 1002 0 1008 1 1008 1 1008 1 1008 1 etc... 我不知道如何创建一个循环来完成总和和百分比,它会随着每个“商店”的变化而变化。非常感谢您的帮助。您可以使用

对于商店中的每个员工,都有一项任务。如果员工完成了任务,则在“车间”的“任务”列中有“1”。我必须对每个车间的所有“1”进行求和,并检查每个车间完成任务的总百分比。举例如下:

Shop  Task
1002    0
1002    1
1002    0
1002    0
1002    0
1008    1
1008    1
1008    1
1008    1
etc...

我不知道如何创建一个循环来完成总和和百分比,它会随着每个“商店”的变化而变化。非常感谢您的帮助。

您可以使用数据验证选择要与之合作的店铺,并使用sumifs()进行计算,请参阅:

我怀疑这是否真的比SUMIF快,但它确实一次收集了店铺标识和总数

sub shopTotals()

    dim i as long, arr as variant, dict as object

    set dict = createobject("scripting.dictionary")
    dict.comparemode = vbtextcompare

    with worksheets("sheet1")

        arr = .range(.cells(2, "A"), .cells(.rows.count, "B").end(xlup)).value2

        for i=lbound(arr, 1) to ubound(arr, 1)
            dict.item(arr(i, 1)) = dict.item(arr(i, 1)) + arr(i, 2)
        next i

        .cells(2, "D").resize(dict.count, 1) = application.transpose(dict.keys)
        .cells(2, "E").resize(dict.count, 1) = application.transpose(dict.items)

    end with

end sub

AVERAGEIF或COUNTIF可以检索其他统计信息。

这是一个如何使用dictionary对象和variant数组的循环示例。有时在VBA 100%代码中实现业务逻辑更容易。您可以在循环行时执行各种操作。此示例仅打印出每个键的countIfOne值([0]总计,[1]=countIfOne值)

   ' Tools/References: [x]Microsoft Scripting Runtime
    Public Sub sumShops()
        Dim ws As Worksheet
        Dim arr As Scripting.Dictionary
        Dim iRow As Long
        Dim val As String
        Dim item As Variant

        Set arr = New Scripting.Dictionary
        Set ws = Application.Worksheets("Shops")
        For iRow = 2 To ws.UsedRange.Rows.Count
            val = Trim(ws.Cells(iRow, 1)) ' 1001,1002,..
            If Not arr.Exists(val) Then
                ReDim item(0 To 1) As Long
                item(0) = 0 ' total count
                item(1) = 0 ' count if task=1
                Call arr.Add(val, item)
            Else
                item = arr.item(val)
            End If
            item(0) = item(0) + 1
            If ws.Cells(iRow, 2).Value = "1" Then item(1) = item(1) + 1 ' count task=1 rows
            ' we must reference array back to the dictionary key
            arr(val) = item
        Next

        ' Loop dictionary by keys and print an array(0..1)
        For iRow = 0 To arr.Count - 1
            val = arr.Keys(iRow)
            item = arr.item(val)
            Debug.Print val & "=" & item(0) & "," & item(1)
        Next
    End Sub

考虑到您输入数据的方式(1和0),您可以只使用数据透视表

将商店拖到行区域,将任务拖到值区域两次。 首先使用SUM 对于完成百分比,使用平均值


sumif/sumifs有什么问题?事实上,几乎有18000行和700家不同的商店,我正在寻找一种方法来优化它。@Szymon我怀疑循环18000行比在工作表上使用公式更快。使用
=SUMIF(A:A,A:A,B:B)
计算每个店铺的
1
=SUMIF(A:A,A:A,B:B)/COUNTIF(A:A,A:A)*100之和,计算每个店铺的百分比。•或者也可以使用数据透视表。谢谢@Pᴇʜ,原来我对苏米夫的了解不如我想象的那么深。原来这是一个相当愚蠢的问题,很抱歉打扰你了。@Pᴇ当然,也有averageif。Excel native总是比VBABut更快,首先收集唯一的店铺标识符列表,然后每个标识符的条件合计可能会更慢。