Compare Data in Two Ranges Row by Row and Count Matches

Steviemac

New Member
Joined
May 24, 2021
Messages
14
Office Version
  1. 2019
Platform
  1. Windows
Hi there, first time poster, long time lurker

Hoping some kind soul can speed up this macro with a light speed modification

The data to check (InputData) is replaced many times at this part of the process and at the rate the InputData comes in is
proving to be a real bottleneck, the macro works fine, it's just that it takes 16 seconds to run each time, which is too long
Hopefully there is a better faster way (maybe a macro rewrite!)

Data is held in two data sets, both 5 columns across
InputData set is 56 rows (variable)
TaskPercentComplete set is 2000 rows (variable)

Every row in the 'InputData' table is compared with Each row in turn in the 'TaskPercentComplete' table
for matches - it only has to record whether there is a match of 3 values and/or a match of 4 values

Any help is very much appreciated

Thanks Ste


VBA Code:
Sub TaskPercentages()

Application.ScreenUpdating = False

Dim InputData As Long

Sheets("TaskPercentComplete").Range("J3:L10000").ClearContents

 InputData = 2
 
   Do While Not Sheets("TaskPercentComplete").Cells(InputData, 46).Value = ""
  
       TaskDataOutput = 3
                 
        Do While Not Sheets("TaskPercentComplete").Cells(TaskDataOutput, 3).Value = ""
       
            Dim rngA As Range: Set rngA = Range("C" & TaskDataOutput & ":G" & TaskDataOutput)
            Dim rngB As Range: Set rngB = Range("AT" & InputData & ":AX" & InputData)

            If Evaluate("SUMPRODUCT(COUNTIF(" & rngA.Address & "," & rngB.Address & "))") = 4 Then
            Sheets("TaskPercentComplete").Cells(TaskDataOutput, 11).Value = "80%"
            End If
           
            If Evaluate("SUMPRODUCT(COUNTIF(" & rngA.Address & "," & rngB.Address & "))") = 3 Then
            Sheets("TaskPercentComplete").Cells(TaskDataOutput, 10).Value = "60%"
            End If

        TaskDataOutput = (TaskDataOutput + 1)
     
       Loop
   
      InputData = (InputData + 1)
  
   Loop
  
  'nextonwardmacro
 
End Sub
 

Excel Facts

Select a hidden cell
Somehide hide payroll data in column G? Press F5. Type G1. Enter. Look in formula bar while you arrow down through G.
Hi & welcome to MrExcel.
One way to speed it up would be to assign the value of
VBA Code:
Evaluate("SUMPRODUCT(COUNTIF(" & rngA.Address & "," & rngB.Address & "))")
to a variable & then test if the variable is 3 or 4.
That way you only need to run the evaluate once per row.
 
Upvote 0
Hi & welcome to MrExcel.
One way to speed it up would be to assign the value of
VBA Code:
Evaluate("SUMPRODUCT(COUNTIF(" & rngA.Address & "," & rngB.Address & "))")
to a variable & then test if the variable is 3 or 4.
That way you only need to run the evaluate once per row.

Thanks for the reply and your time Fluff - I never even thought about checking for both at once! - I'm not a coder

is there any chance you could alter the code so I can try it out please
 
Upvote 0
How about
VBA Code:
Sub TaskPercentages()

Application.ScreenUpdating = False

Dim InputData As Long
Dim Result As Variant

Sheets("TaskPercentComplete").Range("J3:L10000").ClearContents

 InputData = 2
 
   Do While Not Sheets("TaskPercentComplete").Cells(InputData, 46).Value = ""
  
       TaskDataOutput = 3
                 
        Do While Not Sheets("TaskPercentComplete").Cells(TaskDataOutput, 3).Value = ""
       
            Dim rngA As Range: Set rngA = Range("C" & TaskDataOutput & ":G" & TaskDataOutput)
            Dim rngB As Range: Set rngB = Range("AT" & InputData & ":AX" & InputData)

            Result = Evaluate("SUMPRODUCT(COUNTIF(" & rngA.Address & "," & rngB.Address & "))")
            If Not IsError(Result) Then
               If Result = 4 Then
                  Sheets("TaskPercentComplete").Cells(TaskDataOutput, 11).Value = "80%"
               ElseIf Result = 3 Then
                  Sheets("TaskPercentComplete").Cells(TaskDataOutput, 10).Value = "60%"
               End If
            End If

        TaskDataOutput = (TaskDataOutput + 1)
     
       Loop
   
      InputData = (InputData + 1)
  
   Loop
  
  'nextonwardmacro
 
End Sub
 
Upvote 0
Fluff - Officially impressed!! - Your quick (and clever) solution knocked 6 seconds off the run time

I mean, man, You have just reduced the wait time by 37% - Ace, Thank you very much

I don't really want to ask for further help, but, would there be a way of getting rid of the loops?
I presume looping is also a massive hurdle
 
Upvote 0
Once an input row has 3 or 4 matches on one of the output rows, will it possible match other output rows?
 
Upvote 0
yes

The input row could match many output rows with 3 or 4 matches
 
Upvote 0
Fluff, I just tested one input row

It matched

21 rows of 60%
3 rows of 80%
 
Upvote 0
Another option that might save a bit more time is
VBA Code:
Sub TaskPercentages()

Application.ScreenUpdating = False

Dim InputData As Long, TaskDataOutput As Long
Dim Result As Variant

Sheets("TaskPercentComplete").Range("J3:L10000").ClearContents

 InputData = 2
 
   Do While Not Sheets("TaskPercentComplete").Cells(InputData, 46).Value = ""
  
       TaskDataOutput = 3
                 
        Do While Not Sheets("TaskPercentComplete").Cells(TaskDataOutput, 3).Value = ""
            If Cells(TaskDataOutput, 10) = "" Or Cells(TaskDataOutput, 11) = "" Then
               Dim rngA As Range: Set rngA = Range("C" & TaskDataOutput & ":G" & TaskDataOutput)
               Dim rngB As Range: Set rngB = Range("AT" & InputData & ":AX" & InputData)
   
               Result = Evaluate("SUMPRODUCT(COUNTIF(" & rngA.Address & "," & rngB.Address & "))")
               If Not IsError(Result) Then
                  If Result = 4 Then
                     Sheets("TaskPercentComplete").Cells(TaskDataOutput, 11).Value = "80%"
                  ElseIf Result = 3 Then
                     Sheets("TaskPercentComplete").Cells(TaskDataOutput, 10).Value = "60%"
                  End If
               End If
            End If
        TaskDataOutput = (TaskDataOutput + 1)
     
       Loop
   
      InputData = (InputData + 1)
  
   Loop
  
  'nextonwardmacro
 
End Sub
This way if an output row is already flagged as 60% & 80% it won't get checked again.
 
Upvote 0
This is interesting - Tested three times
so, even though the 60% and 80% get flagged it runs ever so slightly slower

1st code change takes 9.72 seconds
2nd code change takes 10.31 seconds
 
Upvote 0

Forum statistics

Threads
1,215,650
Messages
6,126,010
Members
449,280
Latest member
Miahr

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