SUMPRODUCT with INDIRECT - excel

I have checked all question related to this topic, but none of it helped.
I have this formula
=SUMPRODUCT((INDIRECT("Ap"&ROW()&":"&"Ap"&(ROW()+$T4-1)));(INDIRECT("Ap"&ROW()&":"&"Ap"&(ROW()+$T4-1))))
This results in - 0.
=SUMPRODUCT((INDIRECT("Ap"&ROW()&":"&"Ap"&(ROW()+$T4-1)))*(INDIRECT("Ap"&ROW()&":"&"Ap"&(ROW()+$T4-1))))
This results in - "VALUE!
With SUM command everything worked fine, but I'm stuck with this now. I use Microsoft Office 2013 and I can't seem to find out the problems with this INDIRECT function, since it works nicely with other command.
For example, if I have in column A numbers from 1 to 5 in the first 5 rows, and the same in column B, I put the formula in C1
=SUMPRODUCT((INDIRECT("A"&ROW()&":"&"A"&(ROW()+4)))*(INDIRECT("B"&ROW()&":"&"B"&(ROW()+4))))
Results the same as the original example.

The construction you are using is quite poor, to be honest. Not only is the unqualified ROW() a very unrigorous choice, but volatile INDIRECT constructions can almost always be avoided in this type of set-up.
Much better is:
=SUMPRODUCT(INDEX(A:A,ROWS($1:1)):INDEX(A:A,ROWS($1:1)+4),INDEX(B:B,ROWS($1:1)):INDEX(B:B,ROWS($1:1)+4))
See here for a discussion on the advantages of using ROWS instead of ROW:
http://excelxor.com/2014/08/25/row-vs-rows-for-consecutive-integer-generation/
Regards

Using your example with data in columns A and B, and this answer on a similar question, the ROW() function returns an array, rather than a single value. Wrapping it in sum() solves this.
=SUMPRODUCT(INDIRECT("A"&SUM(ROW())&":"&"A"&SUM((ROW()+4))),INDIRECT("B"&SUM(ROW())&":"&"B"&SUM((ROW()+4))))

Related

EXCEL Averaging with multiple Criteria

I have tried 2 approaches to my problem and can't quite figure out where I'm going wrong.
=AVERAGEIFS(CALC!L:L,CALC!C:C,Consignee!A2,CALC!K:K,CALC!A:A) and =IF(AND(Consignee!A2=CALC!C:C,CALC!K:K=CALC!A:A),AVERAGE(CALC!L:L),0)
Basically I need to start with CONSIGNEE!A2, then find it's match in CALC!C:C, which I then need to check against CALC!A:A to find the ones that go with it in the same row and see if that/those cell(s) match any in CALC!K:K and then take the average of the corresponding values in CALC!L:L and average them. I hope that makes sense. I feel like I've gotten close but am missing something.
Thank you in advance for your help!
I suspect that the formula below may not be the most efficient possible but it will do the job.
=SUMPRODUCT((CALC!A:A=CALC!K:K)*(CALC!C:C=CONSIGNEE!A2),CALC!L:L)/SUMPRODUCT((CALC!A:A=CALC!K:K)*(CALC!C:C=CONSIGNEE!A2))
Edit
In my original answer a reference to L1 was erroneously left over from the formula I tested where I had L1 taking the place of CONSIGNEE!A2. I have corrected this error and believe that the formula works fine for your requirement now.
Note that there are two separate SUMPRODUCT functions which you can test each by itself, one returning the count, the other the sum. If the count = 0 a #DIV/0 error will occur. You can prevent that by embedding the formula in and IFERROR() function.

Excel sum formula over varying indices

I'm trying to reproduce the sum of the values in column I within one cell, without having to evaluate them for each row individually. For better understanding see the following screenshot:
I've sifted through endless INDEX/INDIRECT/etc. results both here and on Google, but can't seem to figure it out... Basically I want to just sum over the row-wise evaluations of this formula:
=-MAX($B$1-MAX(A$1:A1)+MIN(A$1:A1),0)
Note that the starting row of each evaluation is fixed.
Edit: the solution proposed by Scott works if Excel recognizes the LET() function, which does not seem to be the case for my work laptop even though it has Office 365 Pro Plus, probably this latest insider program is not enabled.
With the dynamic array formula in Office 365:
=LET(seq,SEQUENCE(COUNT(A:A)),rng,OFFSET(A1,0,0,seq),SUMPRODUCT(-(B1-MAXIFS(rng,rng,"<>")+MINIFS(rng,rng,"<>"))*(B1-MAXIFS(rng,rng,"<>")+MINIFS(rng,rng,"<>")>0)))

Combine two lists in Excel, one underneath the other

I have two lists of products in Excel. Each list will be of varying length each month.
Is there a way to combine the two lists into a third list, with the second list being underneath the first?
I would like to do this avoiding macros.
I image this could be done using Dynamic Arrays, but I can't figure it out.
Please see an example below:
Thank you so much in advance.
I have had this problem before and used this tutorial to help me. I attach the example sheet also, which provides the formula that may work for your problem.
See the image below for cell references - then try this:
=IFERROR(INDEX($B$3:$B$7, ROWS(H2:$H$2)), IFERROR(INDEX($D$3:$D$4, ROWS(H2:$H$2)-ROWS($B$3:$B$7)), IFERROR(INDEX($F$3:$F$6, ROWS(H2:$H$2)-ROWS($B$3:$B$7)-ROWS($D$3:$D$4)), "")))
I have managed to find a solution that works for me, where the lists are of variable length.
Using a similar scenario to Mardi-Louise's answer, I am using the following formula in cell F3, and then dragging down:
=IF(B3<>"",B3,OFFSET($D$3,ROW()-COUNTA($B$3:$B$7),0))
Explanation:
So long as List 1 is not finished, it takes the value from List 1.
Once List 1 is finished, it begins at the top of List 2, and uses an offset to move down.
I'm late to the party, but for anyone still looking for this there's (now) a function for this in Excel 365: vstack(array1;array2;...)
Here is Microsoft's page on it
With the arrays as columns in tables you'll get dynamic lengths. It's also possible to combine vstack() with for example unique().
I benefitted from Answer 2 with slightly different syntax. The ROW() function provides an output based on the absolute cell address when an output based on the relative position of the list is actually more generally applicable. I found the following syntax works better to reference the output of ROW() to the cell above the top cell of range D3:D8:
=IF(B3<>"",B3,OFFSET($D$2,ROW()-ROW($D$2)-COUNTA($B$3:$B$7),0))
Additionally, the COUNTA function can provide inconsistent results when cells in the range are not based on simple data but on the output of formulas which can be equal to 0 or blank without actually being empty. In that case COUNTIF often works better such as:
=IF(B3<>"",B3,OFFSET($D$2,ROW()-ROW($D$2)-COUNTIF($B$3:$B$7,"<>"&0),0))

SUMIFS source code for excel 2003 AND the ability to calculate on columns

we are looking to find the original? source code for SUMIFS to use in out excel sheet (for both 2003 and 2007. Here is why:
2003 doest support the SUMIFS method
When we do have SUMIFS we cannot utilize formulas "around" the columns (like YEAR())
For example, we want to calculate the ANSWERS that match the YEAR value of the date in cell A1 with the date values in range L:L. Now this doesnt work because we cant use YEAR(L:L) and hence we need to make another column M:M with the YEAR values from L:L
Thus we need the source to be able to upgrade the code further
=SUMIFS(ANSWERS;L:L;"="&YEAR(A1)) <= This works
=SUMIFS(ANSWERS;YEAR(L:L);"="&YEAR(A1)) <= This doesnt
Many thanks
With referenc to these questions:
Replacing SUMIFS in Excel 2003
VBA code for SUMIFS?
I doubt that you'll find the original code, which is, I imagine, C++ and part of the Excel internals. If that's correct, then it wouldn't help much, even if Microsoft gave it to you!
In general, I recommend against using =SUMIF(), =SUMIFS() and other functions that take a string to define the condition for testing: apart from anything else, I'm concerned that they're going to be slow, since my best guess is that internally they construct a string for evaluation for each value. In XL2007 (all I have available right now) at least, this turns out not to be necessarily true (see comments below).
I'm generally much happier with array functions. This, for example, should work in both Excel 2003 & 2007:
=SUMPRODUCT(--(YEAR(L:L)=YEAR(A1)),ANSWERS)
This gets the same answer:
{=SUM(IF(YEAR(L:L)=YEAR(A1),ANSWERS,0))}
In the latter case, you'd enter the formula without the curly braces ({ & }) and confirm it using Control+Shift+Enter to tell Excel it's an array formula.
In the first example, we build a list of boolean results with YEAR(L:L)=YEAR(A1) and convert it into an array of 1s and 0s using the double-negative. Then SUMPRODUCT takes care of the rest. This version requires that ANSWERS has the same dimension as L:L, i.e. it should be the entire column (or the range in L should be constrained in size).
In the second, Excel will run through each entry in L:L. If its year matches that in A1 then the corresponding ANSWERS value will be used, otherwise zero. This formula seems to be more tolerant of dimension differences but I'd still be careful.

Trying to improve efficiency of array formula

I have a SUM array formula that has multiple nested IF statements, making it very inefficient. My formula spans over 500 rows, but here is a simple version of it:
{=SUM(IF(IF(A1:A5>A7:A11,A1:A5,A7:A11)-A13:A17>0,
IF(A1:A5>A7:A11,A1:A5,A7:A11)-A13:A17,0))}
As you can see, the first half of the formula checks where the array is greater than zero, and if they are, it sums those in the second part of the formula.
You will notice that the same IF statement is repeated in there twice, which to me is inefficient, but is the only way I could get the correct answer.
The example data I have is as follows:
Sample Data in spreadsheet http://clients.estatemaster.net/SecureClientSite/Download/TempFiles/example.jpg
The answer should be 350 in this instance using the formula I mentioned above.
If I tried to put in a MAX statement within the array, therefore removing the test to find where it was greater than zero, so it was like this:
{=SUM(MAX(IF(B2:B6>B8:B12,B2:B6,B8:B12)-B14:B18,0))}
However, it seems like it only calculates the first row of data in each range, and it gave me the wrong answer of 70.
Does anyone know a away that I can reduce the size of the formula or make it more efficient by not needing to repeat an IF statement in there?
UPDATE
Jimmy
The MAX formula you suggested didnt actually work for all scenarios.
If i changed my sample data in rows 1 to 5 as below (showing that some of the numbers are greater than their respective cells in rows 7 to 11, while some of the numbers are lower)
Sample Data in spreadsheet http://clients.estatemaster.net/SecureClientSite/Download/TempFiles/example2.jpg
The correct answer im trying to achive is 310, however you suggested MAX formula gives an incorrect answer of 275.
Im guessing the formula needs to be an array function to give the correct answer.
Any other suggestions?
=MAX( MAX( sum(A1:A5), sum(A7:A11) ) - sum(A13:A17), 0)
A more calculation-efficient (and especially re-calculation efficient) way is to use helper columns instead of array formulae:
C1: =MAX(A1,A7)-A13
D1: =IF(C1>0,C1,0)
copy both these down 5 rows
E1: =SUM(D1:D5)
Excel will then only recalculate the formulae dependent on any changed value, rather than having to calculate all the virtual columns implied by the array formula every time any single number changes. And its doing less calculations even if you change all the numbers.
You may want to look into the VB Macro editor. In the Tools Menu, go to Macros and select Visual basic Editor. This gives a whole programming environment where you can write your own function.
VB is a simple programming language and google has all the guidebooks you need.
There, you can write a function like MySum() and have it do whatever math you really need it to, in a clear way written by yourself.
I pulled this off google, and it looks like a good guide to setting this all up.
http://office.microsoft.com/en-us/excel/HA011117011033.aspx
This seems to work:
{=SUM(IF(A1:A5>A7:A11,A1:A5-A13:A17,A7:A11-A13:A17))}
EDIT
- doesn't handle cases where subtraction ends up negative
This works - but is it more efficient???
{=SUM(IF(IF(A1:A5>A7:A11,A1:A5,A7:A11)>A13:A17,IF(A1:A5>A7:A11,A1:A5,A7:A11)-A13:A17,0))}
What about this?
=MAX(SUM(IF(A1:A5>A7:A11, A1:A5, A7:A11))-SUM(A13:A17), 0)
Edit:
Woops - Missed the throwing out negatives part. What about this? Not sure it it's faster...
=SUM((IF(A1:A5>A7:A11,IF(A1:A5>A13:A17,A1:A5,A13:A17),IF(A7:A11>A13:A17,A7:A11,A13:A17))-A13:A17))
Edit 2:
How does this perform for you?
=SUM((((A1:A5>A13:A17)+(A7:A11>A13:A17))>0)*(IF(A1:A5>A7:A11,A1:A5,A7:A11)-A13:A17))

Resources