Excel INDIRECT() with non-contiguous range ... only works with COUNTIF()? - excel

I need to use the Excel Indirect() function to reference a non-contiguous range. This (How to define a non continuous range in COUNTIF) answer gives an example.
In summary, the OP has two ranges, C1:C15 and A16. Each range contains either an A or a B, and the way to count the number of B's across these two ranges is
=SUM(COUNTIF(INDIRECT({"C1:C15","A16"}),"B"))
If I change all the B's to 1's and the A's to 0's, and change this formula slightly to
=SUM(COUNTIF(INDIRECT({"C1:C15","A16"}),"1"))
Then this still works ... BUT! this doesn't:
=SUM(INDIRECT({"C1:C15","A16"}))
I can work around this, but am I missing something fundamentally magic about the COUNTIF() function, that somehow influences the INDIRECT() function to behave as expected?

It's not possible to use a non-contiguous range in COUNTIF.
What's actually happening with the first formula is that COUNTIF is being fed with an array of (two) separate ranges and therefore the result is an array of the results of two counts, then SUM is used to sum the array.
If you actually have 1s and zeroes wouldn't you just SUM them with this formula
=SUM(C1:C15,A16)
If you are just trying to find why your last formula doesn't work then, yes, I think COUNTIF does work differently - it's able to handle an array of ranges while some other functions can't. This is common to the "IFS" family of functions, so SUMIF, for example, can do the same

Related

Countifs using multiple dynamic arrays as criteria

I have a countifs formula that seems to be letting me down.
It's using 2 different criteria and both are dynamic arrays - here represented by the cell ref and the hashtag:
COUNTIFS(A:A,B1#,C:C,D1#)
The dynamic arrays in cells B1 and D1 are working fine, and if I change the countifs so only 1 of the criteria refers to a dynamic range (removing the hashtag and selecting 1 of the results in the array) then it works fine. The problem is when I need it to use 2 (or more?) dynamic ranges.
Any thoughts?
if the items are independent of each other as in B1 does not directly correlate to D1 and B2 directly correlates to D2 then you need to Transpose one of the arrays.
=COUNTIFS(A:A,B1#,C:C,TRANSPOSE(D1#))
Note:
This will create a 2D array with as many rows as in B1# and as many Columns as in D1#. So to get the total wrap it in SUM or SUMPRODUCT.
Also, The max independent arrays are two.
Also that it is an AND situation so the value in A must be equal to the a value in B and the value in C in the same row, must be equal to a value in D
If one wants more than two we need to move away from countifs and use array type formula which will require the use of ranges that encompass the most rows that would be used and not full columns.
=SUMPRODUCT(ISNUMBER(MATCH(A1:A100,B1#,0))*ISNUMBER(MATCH(C1:C100,D1#,0)))
This version is AND like the COUNTIFS where the values in A and C on the same row must exist their corresponding lists to be counted. IF you want to count them individually then change the * to + which makes it an OR.
And the use of ISNUMBER(MATCH(A1:A100,B1#,0)) can be added as many as desired changing the ranges as necessary.
Edit: This will not work, see below comment by #Scott Craner
I'm unsure if COUNTIFS work well with dynamic arrays, which is what you are currently using.
A workaround can be to try use SUMPRODUCT
=SUMPRODUCT((A:A=B1#)*(C:C=D1#))

Aggregating Price using IFERROR/SUMIF

Problem
Unable to sum prices for different part numbers using the combo of formula mentioned below
What Am I Trying To Accomplish?
I am trying to sum up prices for various part numbers in a different sheet. They are in millions
My Formula
I am using a combination of IFERROR and SUMIF
What my desired result should look like
Note
When using the combo of IFERROR and SUMIF I am considering both Part num and ALT Part so that if either of the two exists, it should sum the price for both
Thanks
Perhaps you may try using SUMPRODUCT() Function,
• Formula used in cell C2
=SUMPRODUCT((--ISNUMBER(MATCH($G$2:$G$9,A2:B2,0)))*($F$2:$F$9))
To explain the above Formula.
• We are using MATCH() Function to find the positions of the both Part Numbers in the range G2:G9
=MATCH($G$2:$G$9,A2:B2,0)
The above on evaluating returns
{1;#N/A;#N/A;#N/A;2;#N/A;#N/A;#N/A}
• Next we are wrapping this within an ISNUMBER() Function to exclude the #N/A and to take only numbers.
ISNUMBER(MATCH($G$2:$G$9,A2:B2,0))
Which returns
{TRUE;FALSE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE}
• Using double unary to convert the Boolean values to 1's and 0's
{1;0;0;0;1;0;0;0}
• Next we are then doing a matrix multiplication of the 1's with the corresponding range i.e. F2:F9
(--ISNUMBER(MATCH($G$2:$G$9,A2:B2,0)))*($F$2:$F$9)
Which returns,
{5000;0;0;0;5000;0;0;0}
• Lastly we wrapping the whole within an SUMPRODUCT() Function to get the SUM
=SUMPRODUCT((--ISNUMBER(MATCH($G$2:$G$9,A2:B2,0)))*($F$2:$F$9))
Hence we are not using and IFERROR() here since IFERROR() function is relatively inefficient and makes calculations slow, if there was no option then we could have used it perhaps when there is way why not use the formula as shown in the screenshot.
Also note to change the ranges in the formulas as per your suit.
If I’m understanding this right, the formula you are probably looking for is
=iferror(sumif1,0)+iferror(sumif2),0)

Why does excel SUMIF function give wrong figure?

Taking sum of HP. But my formula is providing me wrong amount despite of criteria not being fulfilled!
I think it's worth posting an explanation as to why your original formula does not work, as it highlights an interesting feature of the function SUMIF.
As stated in one of my commments, you are passing a range parameter to that function of CN_2021[[#All],[HP]:[Sum of ORDER_AMT]], which is a reference to the entire table (including headers). Hence, you are effectively searching for the entry from P14 in all three columns, not just the first.
However, you are also using a sum_range parameter of CN_2021[[#All],[Sum of ORDER_QTY]], which is only one column. One might think that the construction should flat out error, since your range and sum_range parameters are not of an equal dimension (the former comprises 3 columns, the latter only 1).
The reason it does not error is due to the fact that, in such cases, Excel redimensions the sum_range so as to be of an equal dimension to the range.
So, if we replace the Table references with their equivalent worksheet references (assuming that table begins in A3) for the sake of simplification, we have that
=SUMIF(CN_2021[[#All],[HP]:[Sum of ORDER_AMT]],P14,CN_2021[[#All],[Sum of ORDER_QTY]])
which is equivalent to
=SUMIF(A3:C19,P14,B3:B19)
should error, though the single-column range
B3:B19
is redimensioned to a three-column range in line with the range, i.e.
B3:D19
which means that you are effectively performing
=SUMIF(A3:C19,P14,B3:D19)
This could have potential consequences were column D also populated: for example, place a 3 in cell C14 and 1000 in cell D14. The formula will now pick up this extra 1000 in the sum.
Strangely, unlike SUMIF, SUMIFS does not appear to be so lenient with respect to this redimensioning:
=SUMIFS(B3:B19,A3:C19,P14)
errors.

Excel CountIfs with an or condition on Dates

Looking to try and find the following in Excel but am having issues getting this to work.
I have Dates in Column A which need to be checked against Dates in the Query Column to compare. I want to count all records where the comparison column is greater than the date in A5 or is an empty cell. There are other conditions that I will also want to check but cannot seem to get this to work.
=COUNTIFS(Query1[Purchased Date],OR(Query1[Purchased Date]="",Query1[Purchased Date]>A5))
use:
=SUMPRODUCT(--((Query1[Purchased Date]="")+(Query1[Purchased Date]>A5)>0))
You can use an array function instead of countif.
Suppose your dates are in the range A2:A25 and your reference date is in cell B2.
If you type in any other cell
=SUM((A2:A25>B2)+(A2:A25=""))
and hit Ctrl+Shift+Enter it will give you the count you want.
This happens because Excel will resolve the first inner parentheses (A2:A25>B2) as an array of TRUE/FALSE, and does the same to the second (A2:A25=""). Next it will sum them, which is equivalent to the OR operation, and yields as a result an array of zeros (FALSE) and ones (TRUE). It wraps up by summing this array (with the function sum), all in one cell.
Perhaps this is more of a comment than an answer, but in this particular case you can just add the two separate totals:
=COUNTIF(Query1[Purchased Date],"")+COUNTIF(Query1[Purchased Date],">"&A5)
because the conditions are mutually exclusive.
Whether this helps or not depends on what additional criteria you want to add.
BTW there are two issues with your original formula:
(1) If you are combining lists of values with OR logic, you have to use addition instead (as in the two answers which use Sum or Sumproduct).
(2) The syntax of a Countif or Countifs where the range has to be kept separate from the criteria won't let you do what you want to do, so this again leads you to Sum or Sumproduct.

ROW() function behaves differently inside SUM() and SUMPRODUCT()

Problem definition:
Enter any number in cell A1. Now try the following formulae anywhere on first row.
=SUM(INDIRECT("A"&ROW()))
and
=SUMPRODUCT(INDIRECT("A"&ROW()))
The first formula evaluates, the second one gives a #VALUE error.
This is caused by the ROW() function behaving differently inside SUMPRODUCT().
In the first formula, ROW() returns 1. In the second formula, row returns {1} (array of one length), even though the formula has not been entered as a CSE formula.
Why does this happen?
Background
I need to evaluate a formula of the type
=SUMPRODUCT(INDIRECT(*range formed by concatenation and using ROW()*)>1)
This is working out to an error. As a workaround to this issue, I now calculate ROW() in another cell (in the same row, obviously) and concatenate that inside my INDIRECT(). Alternately, I also have tried encapsulating it inside a sum function, like SUM(ROW()), and that works as well.
I would sure appreciate it if someone could explain (or point me to a resource that can explain) why ROW() returns an array inside SUMPRODUCT() without being CSE entered.
Interesting question. There are subtle issues here which I haven't seen documented.
It seems INDIRECT("A"&ROW()) returns an array consisting of one element which is a reference to a cell - not the value in that cell. Many functions cannot resolve this type of data correctly but a few functions such as N and T can "dereference" the array and return the underlying value.
Take this case where there are two elements in the array:
=SUM(N(INDIRECT("A"&ROW(1:2))))
This returns A1+A2 when array entered but it only returns A1 when entered normally. However changing ROW(1:2) to {1;2} in this formula returns the correct result when entered normally. The equivalent SUMPRODUCT formula returns A1+A2 whether array entered or not.
This may be related to how the arguments are registered in the function. According to http://msdn.microsoft.com/en-us/library/bb687900.aspx there are essentially two methods to register function arguments to handle Excel data types:
Type R/U: "Values, arrays, and range references."
Type P/Q: "Excel converts single-cell references to simple values and multi-cell references to arrays when preparing these arguments."
SUM arguments seem to conform with type R/U while SUMPRODUCT arguments behave like type P/Q. Array-entering the SUM formula above forces the range reference argument in ROW to be evaluated as an array whereas this happens automatically with SUMPRODUCT.
Update
After a little more investigation, here's further evidence that might support this theory. Based on the link in the comment, the formula =SUM((A1,A2)) gives the same values as:
?executeexcel4macro("CALL(""Xlcall32"",""Excel4"",""2JRJR"",4,,1,(!R1C1,!R2C1))")
Registering the last argument as type P by changing 2JRJR to 2JRJP gives an error in this case but does allow for single area ranges like !R1C1:!R2C1. On the other hand, changing the 4 (xlfsum) to 228 (xlfsumproduct) only allows single area references either way it's called just like SUMPRODUCT.
As ROW() returns an array, use INDEX to get the 1st element.
You example then becomes: =SUMPRODUCT(INDIRECT("A"&INDEX(ROW(),1)))
I don't think ROW() behaves differently here, it returns an array in both cases. I assume that SUM and SUMPRODUCT treat that array differently - not sure why.
Many functions or combinations of them return arrays - you don't need CTRL+SHIFT+ENTER to make that happen, you only need CSE in many cases to process the arrays created.
I would just use INDEX in place of INDIRECT (which also benefits you by avoiding a volatile function), i.e.
=SUMPRODUCT(INDEX(A:A,ROW()))
....expanding that to your range this formula will count the number of values > 1 in a range in column A where x defines the start row and y the end row
=COUNTIF(INDEX(A:A,x):INDEX(A:A,y),">1")
x and y can be calculated by formulas
you can use SUMPRODUCT or COUNTIFS in a similar way if there are more conditions to add

Resources