Sumifs VBA with multiple criteria in multiple cells

xs4amit

New Member
Joined
May 21, 2018
Messages
34
Hi Excel Champs,

Please help me getting this calculated

I have data like this

DateEmp CodeEmp NameProductivityAHT
15-02-2018726462ABC25410 Min
15-02-2018734840DEF12312 Min
15-02-2018746569GHI6563 Min
15-02-2018726462ABC15320 Min
15-02-2018734840DEF3456 Min
15-02-2018746569GHI23410 Min
15-02-2018726462ABC4845 Min
15-02-2018734840DEF5562 Min
16-02-2018726462ABC64512 Min
16-02-2018746569GHI9372 Min
16-02-2018734840DEF29410 Min
16-02-2018734840DEF4755 Min
16-02-2018746569GHI28410 Min

<tbody>
</tbody>

And data goes on for upcoming dates in next Rows.


Where i need to make a productivity report out of above data like this

Emp CodeEmp Name15-02-201816-02-201817-02-201818-02-2018
726462ABC=SUMIFS()=SUMIFS()
734840DEF

<tbody>
</tbody>

Right now i am using SUMIFS but my data expands upto 50000 Rows and SUMIFS is very slow. Can you please help me with a VBA code which calculates this for above table.
 

Excel Facts

When did Power Query debut in Excel?
Although it was an add-in in Excel 2010 & Excel 2013, Power Query became a part of Excel in 2016, in Data, Get & Transform Data.
Hi,

Are you trying to sum Productivity or AHT.
 
Upvote 0
There must be a more elegant way to do this. That said, this code assumes your data is in Sheet1 starting in cell A1. It will write your results to Sheet2 starting in Cell A1..

Code:
Sub EmpSum()
    
    Dim ws1 As Worksheet: Set ws1 = Worksheets("Sheet1")
    Dim ws2 As Worksheet: Set ws2 = Worksheets("Sheet2")
    Dim lRow As Long, x As Long, lRow2 As Long, i As Long, c As Long
    Dim dts As Variant
    
    lRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
    dts = ws1.Range("A2:A" & lRow)


    With CreateObject("Scripting.Dictionary")
        For x = LBound(dts) To UBound(dts)
            If Not IsMissing(dts(x, 1)) Then .Item(dts(x, 1)) = 1
        Next
        dts = .Keys
    End With
    
    ws2.Range("C1").Resize(, UBound(dts) + 1) = dts
    ws1.Range("B1:C" & lRow).Copy ws2.Range("A1")
    ws2.Range("A2:B" & lRow).RemoveDuplicates Columns:=Array(1, 2), _
        Header:=xlNo
    lRow2 = ws2.Cells(Rows.Count, 1).End(xlUp).Row
    
    For c = 3 To 3 + UBound(dts)
        For i = 2 To lRow2
            ws2.Cells(i, c) = Application.WorksheetFunction.SumIfs _
            (ws1.Range("D:D"), ws1.Range("A:A"), ws2.Cells(1, c), _
            ws1.Range("B:B"), ws2.Range("A" & i))
        Next
    Next
    
End Sub
 
Upvote 0
If you do not want to use SUMIFS neither in the spreadsheet nor in VBA maybe this macro
Assumes
Data in Sheet1 columns A:F
Results (report) in Sheet2

Code:
Sub aTest()
    Dim dDate As Object, dCode As Object
    Dim vData As Variant, i As Long
    
    Set dDate = CreateObject("Scripting.Dictionary")
    dDate.CompareMode = vbTextCompare
    Set dCode = CreateObject("Scripting.Dictionary")
    dCode.CompareMode = vbTextCompare
    
    'Data in Sheet1
    With Sheets("Sheet1")
        vData = .Range("A2:F" & .Cells(.Rows.Count, "A").End(xlUp).Row)
    End With
    For i = LBound(vData, 1) To UBound(vData, 1)
        dCode(vData(i, 2)) = vData(i, 3)
        If dDate.exists(vData(i, 1)) Then
            dDate(vData(i, 1))(vData(i, 2)) = dDate(vData(i, 1))(vData(i, 2)) + vData(i, 4)
        Else
            Set dDate(vData(i, 1)) = CreateObject("Scripting.Dictionary")
            dDate(vData(i, 1))(vData(i, 2)) = vData(i, 4)
        End If
    Next i
    
    'Results in Sheet2
    Dim vResult As Variant, j As Long
    With Sheets("Sheet2")
        .Range("A1:B1") = Array("Code", "Name")
        .Range("A2").Resize(dCode.Count, 2) = Application.Transpose(Array(dCode.keys, dCode.items))
        .Range("C1").Resize(, dDate.Count) = dDate.keys
        vResult = .Range("A1").Resize(dCode.Count + 1, dDate.Count + 2)
        For i = LBound(vResult, 1) + 1 To UBound(vResult, 1)
            For j = LBound(vResult, 2) + 2 To UBound(vResult, 2)
                vResult(i, j) = dDate(vResult(1, j))(vResult(i, 1))
            Next j
        Next i
        .Range("A1").Resize(dCode.Count + 1, dDate.Count + 2) = vResult
        .Columns("C").Resize(, dDate.Count).AutoFit
    End With
End Sub

M.
 
Upvote 0
@Marcelo

Your code is obviously- shall we call it "more mature" than my code, so out of curiosity I ran the OP's data down to just over 100K rows and put a timer on both.

I commented out your autofit columns. Your code completed in .37 seconds and much to my surprise my code completed in .19 seconds. I did not expect that result.

igold
 
Upvote 0
igold

I'm surprised either. Thought SUMIFS would impair the performance with so many rows. Learning every day!

M.
 
Upvote 0
Perhaps with more diverse data, the results would be different. I only extended what he had and did not add any additional dates or employees. Perhaps If I get ambitious I will try it again with additional unique data...
 
Upvote 0
Maybe OP can upload his data to a file sharing site and put a link here.
He said he has 50K rows of data and the SUMIFS formulas are very slow - that's why i tried to avoid the same formulas in VBA.

M.
 
Upvote 0
Yes, that would be interesting to see. Maybe he meant he was manually adding the SUMIFS formulas with every set of new data.

igold
 
Upvote 0

Forum statistics

Threads
1,214,411
Messages
6,119,346
Members
448,888
Latest member
Arle8907

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top