Sumproduct formula question (no VBA, please)

westc4

Board Regular
Joined
Aug 1, 2012
Messages
89
Office Version
  1. 365
Platform
  1. Windows
Hello excel experts,

I have the following formula:

=SUMPRODUCT(SUBTOTAL(103,OFFSET($F$26,ROW($F$26:$F$999999)-ROW($F$26),0)),($A$26:$A$999999=$A21)*($B$26:$B$999999=$B$7))

The issue that I have run into is that each time I update my pivot table that uses this formula I run out of resources. I would like to remove the "$999999" and find the last visible cell with data in it. Is there a way to do this in the formula? I do not want to run it with VBA. The workbook is extremely large and has a number of different pivot tables all linked to one source table. I just need to get this formula less resource-intensive, please.


Thank you,
Cari
 

Excel Facts

When they said...
When they said you are going to "Excel at life", they meant you "will be doing Excel your whole life".
I'm not following this part of your formula:
Excel Formula:
SUBTOTAL(103,OFFSET($F$26,ROW($F$26:$F$999999)-ROW($F$26),0))
What do you want this to return as an argument for the SUMPRODUCT function? The 103 code will perform a count of the range described by the OFFSET. And the OFFSET function is being passed an array for the number of rows...did you intend for ROW($F$26:$F$999999)-ROW($F$26) to return an array or a single number (which would happen if ROWS were used)? I would consider avoiding OFFSET and perhaps construct a dynamic range...but I'm not sure how to advise without knowing more about what is supposed to be delivered by this part of the formula. And would column F be reasonable to determine the lowest extent of the data table?
 
Upvote 0
I'm not following this part of your formula:
Excel Formula:
SUBTOTAL(103,OFFSET($F$26,ROW($F$26:$F$999999)-ROW($F$26),0))
What do you want this to return as an argument for the SUMPRODUCT function? The 103 code will perform a count of the range described by the OFFSET. And the OFFSET function is being passed an array for the number of rows...did you intend for ROW($F$26:$F$999999)-ROW($F$26) to return an array or a single number (which would happen if ROWS were used)? I would consider avoiding OFFSET and perhaps construct a dynamic range...but I'm not sure how to advise without knowing more about what is supposed to be delivered by this part of the formula. And would column F be reasonable to determine the lowest extent of the data table?

The data is hard to explain. Please see the sheet.

Book1.xlsx
C
22
100% Over 60


Thank you.
 
Upvote 0
There is nothing on the sheet...just a blank cell at C22.
 
Upvote 0
There is nothing on the sheet...just a blank cell at C22.
Book1.xlsx
ABCDE
2U001U021
3FY22 11 MAR3575,867.44626,825.81
4FY22 12 APR3359,971.60415,922.09
5FY23 01 MAY3195,406.0627,167.66
6
7FY22 11 MARU0010001258728101%227,509.06
8FY22 11 MARU0010002015529100%196,867.40
9FY22 11 MARU0010001934026100%151,490.98
10FY22 12 APRU0010001134211100%139,958.90
11FY22 12 APRU0010001593007100%138,212.70
12FY22 12 APRU0010001109728100%81,800.00
13FY23 01 MAYU0010001106652100%75,655.00
14FY23 01 MAYU0010001984352100%65,945.00
15FY23 01 MAYU0010002019671100%53,806.06
16FY22 11 MARU0210001973845100%4,713.82
17FY22 11 MARU0210001260448100%4,700.00
18FY22 11 MARU0210001108808100%4,492.43
19FY22 11 MARU0210001136476100%4,437.00
20FY22 11 MARU0210001769980100%4,282.56
21FY22 11 MARU0210001106312100%4,200.00
22FY22 12 APRU0210001105892100%4,060.31
23FY22 12 APRU0210001769874100%4,012.01
24FY22 12 APRU0210001742500100%4,001.89
25FY22 12 APRU0210001106343100%3,847.88
26FY23 01 MAYU0210001174248100%3,600.00
27FY23 01 MAYU0210001768982119%3,567.66
Sheet1
Cell Formulas
RangeFormula
B3:B5B3=SUMPRODUCT(SUBTOTAL(103,OFFSET($D$7,ROW($D$7:$D$999805)-ROW($D$7),0)),($A$7:$A$999805=$A3)*($B$7:$B$999805=$B$2))
C3:C5C3=SUMPRODUCT(SUBTOTAL(109,OFFSET($E$7,ROW($E$7:$E$999805)-ROW($E$7),0)),($A$7:$A$999805=$A3)*($B$7:$B$999805=$B$2))
D3:D5D3=SUMPRODUCT(SUBTOTAL(103,OFFSET($D$7,ROW($D$7:$D$999805)-ROW($D$7),0)),($A$7:$A$999805=$A3)*($B$7:$B$999805=$D$2))
E3:E5E3=SUMPRODUCT(SUBTOTAL(109,OFFSET($E$7,ROW($E$7:$E$999805)-ROW($E$7),0)),($A$7:$A$999805=$A3)*($B$7:$B$999805=$D$2))
 
Upvote 0
Have a look at the formula in F3:G5 and let me know if they improve the efficiency of the sheet. SUMPRODUCT with long arrays can be slow. This approach creates dynamic arrays for the three ranges of interest. To do that, this part of the LET formula finds the last row in the worksheet based on looking down column E (in this example, it returns 27).
Excel Formula:
lrow, MAX((E:E<>"")*(ROW(E:E))),
This part finds the index of the lowest row in column E...so the row number of the top cell is subtracted from lrow and then 1 added so the index begins at 1 for the 1st data point:
Excel Formula:
bidx,  lrow-ROW($E$7)+1,
These parts create the dynamic ranges, so instead of the ranges being described by arrays that are 999993 elements long, the range will adapt to smaller sizes:
Excel Formula:
dynE, $E$7:INDEX($E$7:$E$999999,bidx),
dynA, $A$7:INDEX($A$7:$A$999999,bidx),
dynB, $B$7:INDEX($B$7:$B$999999,bidx),
Finally, this part will filter the dynamic E range by determining where there are matches in the dynA and dyn B ranges to the values in $A3 and $D$2, respectively...and then the elements in that filtered array are summed.
Excel Formula:
SUM(FILTER(dynE,(dynA=$A3)*(dynB=$D$2))))
The count formula is similar, except COUNT replaces SUM in the last part of the formula.
MrExcel_20220603.xlsx
ABCDEFG
1
2U001U021
3FY22 11 MAR1572295614.27626825.81626825.81
4FY22 12 APR1321792781.66415922.09415922.09
5FY23 01 MAY3195406.0627167.6627167.66
6
7FY22 11 MARU00112587281.006572858227509.06
8FY22 11 MARU00120155291196867.4
9FY22 11 MARU00119340261151490.98
10FY22 12 APRU00111342111139958.9
11FY22 12 APRU00115930071138212.7
12FY22 12 APRU0011109728181800
13FY23 01 MAYU0011106652175655
14FY23 01 MAYU0011984352165945
15FY23 01 MAYU0012019671153806.06
16FY22 11 MARU021197384514713.82
17FY22 11 MARU021126044814700
18FY22 11 MARU021110880814492.43
19FY22 11 MARU021113647614437
20FY22 11 MARU021176998014282.56
21FY22 11 MARU021110631214200
22FY22 12 APRU021110589214060.31
23FY22 12 APRU021176987414012.01
24FY22 12 APRU021174250014001.89
25FY22 12 APRU021110634313847.88
26FY23 01 MAYU021117424813600
27FY23 01 MAYU02117689821.1861912583567.66
Sheet11
Cell Formulas
RangeFormula
D3:D5D3=SUMPRODUCT(SUBTOTAL(103,OFFSET($D$7,ROW($D$7:$D$999805)-ROW($D$7),0)),($A$7:$A$999805=$A3)*($B$7:$B$999805=$D$2))
E3:E5E3=SUMPRODUCT(SUBTOTAL(109,OFFSET($E$7,ROW($E$7:$E$999805)-ROW($E$7),0)),($A$7:$A$999805=$A3)*($B$7:$B$999805=$D$2))
F3:F5F3=LET(lrow, MAX(($E:$E<>"")*(ROW($E:$E))), bidx, lrow-ROW($E$7)+1, dynE, $E$7:INDEX($E$7:$E$999999,bidx), dynA, $A$7:INDEX($A$7:$A$999999,bidx), dynB, $B$7:INDEX($B$7:$B$999999,bidx), COUNT(FILTER(dynE,(dynA=$A3)*(dynB=$D$2))))
G3:G5G3=LET(lrow, MAX(($E:$E<>"")*(ROW($E:$E))), bidx, lrow-ROW($E$7)+1, dynE, $E$7:INDEX($E$7:$E$999999,bidx), dynA, $A$7:INDEX($A$7:$A$999999,bidx), dynB, $B$7:INDEX($B$7:$B$999999,bidx), SUM(FILTER(dynE,(dynA=$A3)*(dynB=$D$2))))
B5B5=SUMPRODUCT(SUBTOTAL(103,OFFSET($D$7,ROW($D$7:$D$999805)-ROW($D$7),0)),($A$7:$A$999805=$A5)*($B$7:$B$999805=$B$2))
C5C5=SUMPRODUCT(SUBTOTAL(109,OFFSET($E$7,ROW($E$7:$E$999805)-ROW($E$7),0)),($A$7:$A$999805=$A5)*($B$7:$B$999805=$B$2))
 
Upvote 0
You may want to use column A for determining the bottom row of data, as you appear to be using merged cells for column headings. Generally, that's a bad idea, as some formulas do not work correctly when they encounter a merged cell. I'd recommend leaving the heading in the first cell and then select it and the appropriate cells to its right and then Home > Alignment submenu (Format Cells), and then under horizontal, select Center Across Selection. Here is a version using column A for establishing the bottom row:
MrExcel_20220603.xlsx
ABCDE
1
2U001U021
3FY22 11 MAR3575,867.44626,825.81
4FY22 12 APR3359,971.60415,922.09
5FY23 01 MAY3195,406.0627,167.66
6
7FY22 11 MARU00112587281.006572858227,509.06
8FY22 11 MARU00120155291196,867.40
Sheet11 (2)
Cell Formulas
RangeFormula
B3:B5B3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$7)+1, dynE, $E$7:INDEX($E$7:$E$999999,bidx), dynA, $A$7:INDEX($A$7:$A$999999,bidx), dynB, $B$7:INDEX($B$7:$B$999999,bidx), COUNT(FILTER(dynE,(dynA=$A3)*(dynB=$B$2))))
C3:C5C3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$7)+1, dynE, $E$7:INDEX($E$7:$E$999999,bidx), dynA, $A$7:INDEX($A$7:$A$999999,bidx), dynB, $B$7:INDEX($B$7:$B$999999,bidx), SUM(FILTER(dynE,(dynA=$A3)*(dynB=$B$2))))
D3:D5D3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$7)+1, dynE, $E$7:INDEX($E$7:$E$999999,bidx), dynA, $A$7:INDEX($A$7:$A$999999,bidx), dynB, $B$7:INDEX($B$7:$B$999999,bidx), COUNT(FILTER(dynE,(dynA=$A3)*(dynB=$D$2))))
E3:E5E3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$7)+1, dynE, $E$7:INDEX($E$7:$E$999999,bidx), dynA, $A$7:INDEX($A$7:$A$999999,bidx), dynB, $B$7:INDEX($B$7:$B$999999,bidx), SUM(FILTER(dynE,(dynA=$A3)*(dynB=$D$2))))
 
Upvote 0
Thank you! This works, but calculates all cells, how would I calculate/count only the visible cells when the data is filtered?
 
Upvote 0
Finally some clarity on the question I asked in Post #2 about the OFFSET formula and why it was being used like that inside the SUBTOTAL function...if all you really wanted to do is perform conditional counts and sums of values in a column. A long time ago, @Domenic described a similar formula construction in response to a problem involving the SUBTOTAL function and array formulas:
The answer to my question is that you want to be able to manually filter your data and have the counts and sums produced by the formulas reflect the column autofilter selections. That's an important piece of information, and the solution I offered previously will not work under those conditions...as you've discovered. There aren't many formulas/functions that allow you to operate on cells that remain visible after manually hiding others. SUBTOTAL is one of the exceptions and is the reason why your initial formula used it. The OFFSET function works within the SUBTOTAL function to return an array of values that are to be counted or summed, subject to any conditionals, except values on any hidden/filtered rows will be replaced with 0. So the easiest solution is to revert back to a variation of the SUMPRODUCT/SUBTOTAL/OFFSET formula, except use dynamic arrays (yellow cells). Another variation to avoid SUMPRODUCT operating on long arrays is to use a SUM(IF construction (orange cells). I would try the latter first to see if it offers any performance improvements.
MrExcel_20220603.xlsx
ABCDEFGHI
1
2U001U021U021U021
3FY22 11 MAR3575,867.44626,825.8128774.9928774.99
4FY22 12 APR3359,971.60415,922.09311920.2311920.2
5FY23 01 MAY3195,406.0627,167.661360013600
6
7Date DescCodeNbr1Nbr2Amt
8FY22 11 MARU00112587281.006572858227,509.06
9FY22 11 MARU00120155291196,867.40
10FY22 11 MARU00119340261151,490.98
11FY22 12 APRU00111342111139,958.90
12FY22 12 APRU00115930071138,212.70
13FY22 12 APRU0011109728181,800.00
14FY23 01 MAYU0011106652175,655.00
15FY23 01 MAYU0011984352165,945.00
16FY23 01 MAYU0012019671153,806.06
19FY22 11 MARU021110880814,492.43
21FY22 11 MARU021176998014,282.56
23FY22 12 APRU021110589214,060.31
24FY22 12 APRU021176987414,012.01
26FY22 12 APRU021110634313,847.88
27FY23 01 MAYU021117424813,600.00
Sheet11 (2)
Cell Formulas
RangeFormula
B3:B5B3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$8)+1, dynE, $E$8:INDEX($E$8:$E$1000000,bidx), dynA, $A$8:INDEX($A$8:$A$1000000,bidx), dynB, $B$8:INDEX($B$8:$B$1000000,bidx), COUNT(FILTER(dynE,(dynA=$A3)*(dynB=$B$2))))
C3:C5C3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$8)+1, dynE, $E$8:INDEX($E$8:$E$1000000,bidx), dynA, $A$8:INDEX($A$8:$A$1000000,bidx), dynB, $B$8:INDEX($B$8:$B$1000000,bidx), SUM(FILTER(dynE,(dynA=$A3)*(dynB=$B$2))))
D3:D5D3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$8)+1, dynE, $E$8:INDEX($E$8:$E$1000000,bidx), dynA, $A$8:INDEX($A$8:$A$1000000,bidx), dynB, $B$8:INDEX($B$8:$B$1000000,bidx), COUNT(FILTER(dynE,(dynA=$A3)*(dynB=$D$2))))
E3:E5E3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$8)+1, dynE, $E$8:INDEX($E$8:$E$1000000,bidx), dynA, $A$8:INDEX($A$8:$A$1000000,bidx), dynB, $B$8:INDEX($B$8:$B$1000000,bidx), SUM(FILTER(dynE,(dynA=$A3)*(dynB=$D$2))))
F3:F5F3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$8)+1, dynE, $E$8:INDEX($E$8:$E$1000000,bidx), dynA, $A$8:INDEX($A$8:$A$1000000,bidx), dynB, $B$8:INDEX($B$8:$B$1000000,bidx), SUMPRODUCT(SUBTOTAL(103,OFFSET(dynE,ROW(dynE)-MIN(ROW(dynE)),0,1)),(dynA=$A3)*(dynB=$D$2)))
G3:G5G3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$8)+1, dynE, $E$8:INDEX($E$8:$E$1000000,bidx), dynA, $A$8:INDEX($A$8:$A$1000000,bidx), dynB, $B$8:INDEX($B$8:$B$1000000,bidx), SUMPRODUCT(SUBTOTAL(109,OFFSET(dynE,ROW(dynE)-MIN(ROW(dynE)),0,1)),(dynA=$A3)*(dynB=$D$2)))
H3:H5H3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$8)+1, dynE, $E$8:INDEX($E$8:$E$1000000,bidx), dynA, $A$8:INDEX($A$8:$A$1000000,bidx), dynB, $B$8:INDEX($B$8:$B$1000000,bidx), SUM(IF((dynA=$A3)*(dynB=$D$2),SUBTOTAL(103,OFFSET(dynE,ROW(dynE)-MIN(ROW(dynE)),0,1)),"")))
I3:I5I3=LET(lrow, MAX(($A:$A<>"")*(ROW($A:$A))), bidx, lrow-ROW($E$8)+1, dynE, $E$8:INDEX($E$8:$E$1000000,bidx), dynA, $A$8:INDEX($A$8:$A$1000000,bidx), dynB, $B$8:INDEX($B$8:$B$1000000,bidx), SUM(IF((dynA=$A3)*(dynB=$D$2),SUBTOTAL(109,OFFSET(dynE,ROW(dynE)-MIN(ROW(dynE)),0,1)),"")))
Named Ranges
NameRefers ToCells
'Sheet11 (2)'!_FilterDatabase='Sheet11 (2)'!$A$7:$E$28B3:I5
 
Upvote 0

Forum statistics

Threads
1,224,823
Messages
6,181,170
Members
453,021
Latest member
Justyna P

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