Let's say I have an excel table with 2 columns: dates in cells A1 to A10 and values in B1 to B10.
I want to sum all the values of May dates. I have 3 possibilities:
{=SUM((MONTH(A1:A10)=6)*(B1:B10))}
or
=SUMPRODUCT((MONTH(A1:A10)=6)+0;B1:B10)
or
=SUMIFS(B1:B10;A1:A10;">="&DATE(2016;6;1);A1:A10;"<="&DATE(2016;6;30))
What is the best formula to use? In which case? And why?
I have found answers regarding the last two formulas, but nothing regarding the first one.
The first formula would give you an error if B1:B10 contains any text values, the second one won't (it will just ignore text in B1:B10). You can change the first one to allow text in B1:B10 by switching to this syntax:
=SUM(IF(MONTH(A1:A10)=6;B1:B10))
Both of the first two formulas will also give you an error if A1:A10 contains text - SUMIFS won't and can also handle error values in those ranges (as long as not in the sum range on a row that satisfies the conditions)
For those reasons SUMIFS is better, and faster as Scott says.
Disadvantages of SUMIFS:
Can't work with closed workbooks - is less flexible in that it can't accept arrays, so you can't use functions on the ranges
In your specific example SUMIFS only sums amounts for June 2016. The first two formulas will sum for any June date in any year, so that flexibility may suit you better in some circumstances
The first and Second (SUM and SUMPRODUCT) are array type formulas; they will iterate through the range, this is slow and if too many will cause a slow down in the calculation speed and even crash excel.
The third is not an array type formula and has been optimized, and as such can use full column references without detriment to speed.
When ever SUMIFS can be used it is recommended to use it.
Related
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.
I would like to make a SUMIFS formula where I can change the sum_range parametr dynamically on the grounds of this formula where I get the column: SUBSTITUTE(ADDRESS(1;MATCH("aaa";1:1;0);4);1;"")
In other words, I want to replace B:B in this formula =SUMIFS(B:B;A:A;"abc") with the formula above. But I am not able to combine those...
I found one solution here: https://stackoverflow.com/a/25814571/10452645
but I'm not quite satisfied with it. Is there another possibility to solve this task by combining SUMIFS and ADDRESS formula.
In the above example, you can find the sum of abc from column aaa using one of the three formulas:
=SUMPRODUCT((B2:D13)*(B1:D1="aaa")*(A2:A13="abc"))
or
=SUMIFS(INDEX(B2:D13,,MATCH("aaa",B1:D1,0)),A2:A13,"abc")
or
=SUMIFS(INDIRECT(ADDRESS(2,MATCH("aaa",A1:D1,0))&":"&ADDRESS(13,MATCH("aaa",A1:D1,0))),A2:A13,"abc")
You can replace aaa and abc with a cell reference so you can "dynamically" change the SUMIFS criteria.
Please note, as mentioned by #ScottCraner
ADDRESS and INDIRECT are volatile and should be avoided. INDEX is the quickest most solid method.
Reason being a Volatile Function is one that causes recalculation of the formula in the cell where it resides every time Excel recalculates. This occurs regardless of whether the precedent data and formulas on which the formula depends have changed, or whether the formula also contains non-volatile functions. It means it could potentially slow down the calculation of your Excel workbook if it gets complicated overtime.
Having that said, choose the function that suits your preference.
I am using the Excel SUMIFS formulas to look for certain item numbers and add that value to the sum. The issue I am having is that many of our item numbers are very close to each other, i.e. 52000135890001 & 52000135890002.
The issue I am having is that the SUMIFS function seems to see these two items as the same value, and is suming them together. I want them added separately, as to us, they are essentially two different items.
I have tried changing the data type for the item numbers to every possible option but the formulas continues to group these together when performing the function.
Does anyone have any ideas how I can still use the SUMIFS formula but somehow tell it to see these two items as different, instead of adding them together under the same criteria?
I am at a loss and losing my mind so any advice would be beyond helpful!
Kyle
You format all your required cells (range cells, criteria and sum_range cells) to custom format as ##################', then apply the sumif it will work by using the right value.
I have many columns all labeled with many many values underneath, which can be words or numbers
Here is the current equation =INDEX(AK6:AK94,MODE(MATCH(AK6:AK94,AK6:AK94,0))) I have this on the in cell 5 of each column.
The number of values in each column may increase or decrease. If i reference the entire column (until the end of the worksheet) the blank spaces interfere with an accurate output.
How do I reference cell A6 to Last Non-Blank
There are much more efficient - and non-volatile - set-ups available for determining the last non-blank cell in a range than, for example, the SUMPRODUCT/MAX one given by sancho.s, though only if the blank cells within that range are all "genuine" blanks, and not the null string "" e.g. as a result of formulas in those cells.
If this can be guaranteed, then, for a range containing mixed datatypes (some text, some numerics) you can use:
=MAX(MATCH(REPT("z",255),A:A),MATCH(9.9E+307,A:A))
which will be far more efficient than any solution (such as the SUMPRODUCT/MAX set-up) which tests each individual cell within the specified range as to whether it is blank or not.
What's more, the above construction can reference the entirety of column A with no detriment to calculation speed, thus eliminating the need to select a limited range. (Note that using the same range, i.e. A:A, within SUMPRODUCT (or any other array formula) would not at all be a good idea, since this would be forcing Excel to calculate more than a million cells individually, leading to noticeably slower workbook performance).
As for forming a dynamic range, I'm constantly surprised that so many sources around the internet continue to advocate set-ups involving volatile functions such as OFFSET and INDIRECT (I've even seen several sites using ADDRESS for this purpose), especially when there is a perfectly good non-volatile (actually, not fully non-volatile, but near enough) INDEX set-up available, viz:
AK6:INDEX(A:A,LastRow)
where LastRow is a Defined Name given the formula I posted above.
Regards
You need to determine the row of last non-blank cell in the column. The method for this would depend on whether there are blank cells in the middle, for instance.
Two alternatives are (taken from here*):
=SUMPRODUCT(MAX(($AK6:$AK94<>"")*(ROW(AK6:AK94))))
=INDEX(MAX(($AK6:$AK94<>"")*(ROW(AK6:AK94))),0)
Then you can use this value with OFFSET to get a reference to the target cell. So your range will be (using the second form)
A6:OFFSET(AK1,INDEX(MAX(($AK6:$AK94<>"")*(ROW(AK6:AK94))),0)-1,0)
This expression will be embedded in a formula.
Notes:
You may have to change absolute/relative references.
Depending on the formula you embed the expression in, I foresee you might need to enter your formula as an array formula, with Ctrl+Shift+Enter.
*This aims at getting the last non-blank value instead of a reference to the cell, but some of the results posted are useful.
Would counting the non blank cells work, then use offset to move that number of rows.
Have a look at this:
MATCH(1,A6:OFFSET(A6,COUNTIF(A6:A600,">0"),))
the offset & count resolve to complete A6:A14 on my simple test sheet.
One option is to increase the number of rows in the formula to be as high as you might need, and add an extra IF function in the formula to handle blanks, e.g. this version will allow you up to 995 rows of data
=INDEX(AK6:AK1000,MODE(IF(AK6:AK1000<>"",MATCH(AK6:AK1000,AK6:AK1000,0))))
.....but will still work if you have fewer rows and blanks in that range
confirm with CTRL+SHIFT+ENTER
I have to put together a weekly reporting system in Excel. I need to report on the month to dale sales results and the completed week (Fri-Thu). This is collected from multiple sales agents in sales documents stored in Sharepoint.
For this, I've used "SUMIFS" to collect the data, the following way:
=SUMIFS('SHAREPOINTREF/FILE.xlsm'!SalesResults[One off],'SHAREPOINTREF/FILE.xlsm'!SalesResults[Date],">="&B7,'SHAREPOINTREF/FILE.xlsm'!SalesResults[Date],"<="&C7)
(B7 is a cell reference which determines the start date of the week, with C7 being the end of the week)
The trouble with SUMIFS, as well as SUMIF, COUNTBLANK, COUNTIF and COUNTIFS, is that they don't work when the sourcing document is closed. Microsoft has a workaround here: https://support.microsoft.com/kb/260415?wa=wsignin1.0
I can't seem to figure out how to adapt the workaround methodology recommended to apply not just to a simple IF statement, but to multiples. I assume I would need to use an "AND" statement, but I keep getting errors when I'm trying.
I have about half a dozen different calculations to make, but I am pretty confident if I can solve this one, the others should start to gel a bit better.
Try this:
=SUM(IF('SHAREPOINTREF/FILE.xlsm'!SalesResults[Date]>=B7,IF('SHAREPOINTREF/FILE.xlsm'!SalesResults[Date]<=C7,'SHAREPOINTREF/FILE.xlsm'!SalesResults[One off])))
Entered using Ctrl+Shift+Enter.
Non-Array formula equivalent:
=SUMPRODUCT(--('SHAREPOINTREF/FILE.xlsm'!SalesResults[Date]>=B7),--('SHAREPOINTREF/FILE.xlsm'!SalesResults[Date]<=C7),'SHAREPOINTREF/FILE.xlsm'!SalesResults[One off])
But both seems to return #REF! when source WB is closed even though the link provided in the question claims otherwise.
Edit1:
After more digging, above will work but you need to use a Normal Range and not a Table Range.
The only problem is, you loose the advantage of Table's Dynamic Data Range.
So something like this will work even if the source is closed:
=SUMPRODUCT(--('SHAREPOINTREF/[FILE.xlsm]Sheet1'!$A$2:$A$11>=B7),--('SHAREPOINTREF/[FILE.xlsm]Sheet1'!$A$2:$A$11<=C7),'SHAREPOINTREF/[FILE.xlsm]Sheet1'!$B$2:$B$11)
The recommended solution is to use array formulas. Those are a special type of formula that, when typed, must be activated by pressing Ctrl + Shift + Enter in the formula bar. Such a function works by applying a function that would normally accept a single cell (such as IF() ) to a range. You will need to wrap the result in an aggregating formula such as SUM() or COUNT(). Here's an example:
=SUM(IF($A$1:$A$10="Apple", $B$1:$B$10, 0))
This formula would check each cell from A1 to A10 and compare it to "Apple", if it is true it will return the corresponding row from $B$1:$B$10. The result would be an array of values of column B where column A is "Apples" with zeros where it is not. The surrounding SUM() aggregates the array and gives the equivalent of SUMIF().
As I mentioned, you would need to enter Ctrl + Shift + Enter after typing the formula for it to work as an array formula. Otherwise, it will work as a regular formula.