I have a workbook with 2 tabs that are relevant to my query, 'Workings' and 'Data'.
On the 'Workings' tab I have an array of ~3000 SUMIF formulas that looks at ~12000 rows of data on the 'Data' tab. As this cumulatively looks at ~37M rows of data this is slowing down my workbook, so I want to use a macro to limit the range and sum_range within these SUMIF formulas to just the rows in which the first and last instance of each criteria appears. For example if criteria X in (cell A1 of the 'Workings' tab) first appears in row 2040 of the 'Data' tab and last appears in row 2825 of the 'Data' tab, I want to limit the SUMIF formula to be:
Rather than the altogether more inefficient:
Not all of the criteria in the ~3000 rows of SUMIF formulas will actually be in the 'Data' tab, and so if that is the case I want to limit the SUMIF ranges to a single row to minimise impact. I've done a crude experiment using INDIRECT and this allows me to reduce the total number of rows of data considered within the SUMIF formulas to ~300k, which has a noticeable impact on file performance, but I want to avoid using INDIRECT where possible.
To find the rows in the 'Data' tab that first and last instance of a criteria appears, I've created named ranges in the 'Workings' tab called FirstInstanceRange (column AK in my workbook) and LastInstanceRange (column AL in my workbook), located adjacent to each other. I've named the criteria range in the 'Data' tab (column A in my workbook) CriteriaRange. The range in the 'Workings' tab that has the ~3000 SUMIF formulas is called FormulaRange.
I want to apply the code to assign the value for each respective row to the SUMIF formula, but I can't work out how to obtain XXXX (the row number of the first instance) or YYYY (the row number of the last instance)
The code I have so far is:
Any suggestions welcome
On the 'Workings' tab I have an array of ~3000 SUMIF formulas that looks at ~12000 rows of data on the 'Data' tab. As this cumulatively looks at ~37M rows of data this is slowing down my workbook, so I want to use a macro to limit the range and sum_range within these SUMIF formulas to just the rows in which the first and last instance of each criteria appears. For example if criteria X in (cell A1 of the 'Workings' tab) first appears in row 2040 of the 'Data' tab and last appears in row 2825 of the 'Data' tab, I want to limit the SUMIF formula to be:
Excel Formula:
=SUMIF('Data'!A2040:A2825,'Workings'!A1,'Data'!B2040:B2825)
Excel Formula:
=SUMIF('Data'!A1:A12000,'Workings'!A1,'Data'!B1:B12000)
Not all of the criteria in the ~3000 rows of SUMIF formulas will actually be in the 'Data' tab, and so if that is the case I want to limit the SUMIF ranges to a single row to minimise impact. I've done a crude experiment using INDIRECT and this allows me to reduce the total number of rows of data considered within the SUMIF formulas to ~300k, which has a noticeable impact on file performance, but I want to avoid using INDIRECT where possible.
To find the rows in the 'Data' tab that first and last instance of a criteria appears, I've created named ranges in the 'Workings' tab called FirstInstanceRange (column AK in my workbook) and LastInstanceRange (column AL in my workbook), located adjacent to each other. I've named the criteria range in the 'Data' tab (column A in my workbook) CriteriaRange. The range in the 'Workings' tab that has the ~3000 SUMIF formulas is called FormulaRange.
I want to apply the code to assign the value for each respective row to the SUMIF formula, but I can't work out how to obtain XXXX (the row number of the first instance) or YYYY (the row number of the last instance)
The code I have so far is:
VBA Code:
Sub ApplyReduction()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Range("FirstInstanceRange").FormulaR1C1 = "=IFERROR(MATCH(RC1,CriteriaRange,0),1)"
Range("LastInstanceRange").FormulaR1C1 = "=IF(RC[-1]=1,RC[-1],SUMPRODUCT(MAX(ROW(CriteriaRange)*(RC1=CriteriaRange))))"
Range("FormulaRange").FormulaR1C1 = "=SUMIF('Data'!R" & XXXX & "C1:R" & YYYY & "C1,RC1,'Data'!R" & XXXX & "C2:R" & YYYY & "C2)"
Range("FirstInstanceRange").Clear
Range("LastInstanceRange").Clear
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Any suggestions welcome