I need an aggregate function to sum a column depending on what's on the next column. I only want to sum values in front of cells formatted as dates (2nd and 4th rows) which correspond to February only (2nd row).
Here's how the table looks :
Sum (1) | Date (2)
40 February
29,05 19/02/2019
0,00 February
10,00 23/03/2019
10,00 February
17,65 March
0,00 February
I found a way to do this, but this is an array formula, and I have to avoid to enter it with the Control-Shift-Enter key combination.
Here is the working formula I have now (I found part of this formula here: Excel Formula to SUMIF date falls in particular month)
={SUM(IFERROR(IF(MONTH(February_expenses[Date])=2;February_expenses[Sum];0);0))}
This gives the 29.05 expected result. Now, here is what I have for the aggregate function (code 9 is for "sum", code 6 is for "ignoring errors") :
=AGGREGATE(9;6;February_expenses[Sum]/(MONTH(February_expenses[Date])=2))
Which also translates to (highlight + F9 key) :
=AGGREGATE(9;6;{#VALUE!;29,05;#VALUE!;#DIV/0!;#VALUE!;#VALUE!;#VALUE!})
The problem is, this function returns "#VALUE!". I can't figure out why because I indicated the function to ignore errors (code 6). Any idea where I may be wrong ?
The Reference forms of the AGGREGATE function doesn't accept arrays as arguments (unless the array is a range of cells). And the Array forms don't include a SUM function.
If you want to avoid having to use CSE, you can use SUMPRODUCT like this:
=SUMPRODUCT(ISNUMBER(1/(MONTH(February_Expenses[Date])=2))*February_Expenses[Sum])
The 1/(…) converts the FALSE returns to an error to eliminate the non-February months in addition to the real error values.
Related
I'm trying to sum the values in sheet GLTB column D where the value in column A starts with 2.21 and the value in column E is equal to the date in the cell A1. I tried this formula:
=SUMIFS(GLTB!$D$3:$D$26522,GLTB!$A$3:$A$26522,"2.21*",GLTB!$E$3:$E$26522,GLTB!$A$1)*-1
The problems:
The date in A1 doesn't appear anywhere else on the GLTB sheet, so I should get 0 for a sum, but I don't. I get some number that doesn't correspond to anything I can find.
I can make all the values in column D where column A starts with 2.21 equal to 0 (or any other number) and it has no effect on the result of the formula.
I tried this formula based on answers to other questions:
=SUMIFS(GLTB!$D$3:$D$26522,GLTB!$A$3:$A$26522,"2.21*",GLTB!$E$3:$E$26522,GLTB!"="&$A$1)*-1
This just changes the last criterion reference. However, Excel gives me a formula error response.
Any ideas?
This should get you a little closer:
=SUMIFS(GLTB!$D$3:$D$26522,GLTB!$A$3:$A$26522,">=2/21/16",GLTB!$E$3:$E$26522,GLTB!$A$1)*-1
This assumes that column A contains date values which are formatted as string. If these values are not date values, then please give some example of what cell contents in column A.
Note: I'm not clear on why you're searching for "2.21*" so I used the >= operator. That can be changed, or we could add additional criteria to the SumIfs based on your needs.
Other things to be careful of:
Ensure that column E and cell A1 both contain the same type of data (either date formatted as string, or string data representing dates. If you have inconsistent data types, the equivalence test in your Criteria2 (GLTB!$E$3:$E$26522,GLTB!$A$1) will not return the desired results.
To start with, you should format your data as table. To do this, use "Start > Format as table". This will also give you the option of giving your table a name, e.g. data. Basically this makes performing the following steps easier.
From then on, you don't need to reference with GLTB!$A3:$A26522anymore, but can use data[ColumnA].
I'm assuming you have a column ValueA with something in there that might start with 2.21, then ValueD which you want to sum and DateE which should be equal to a certain date.
The formula you are looking for is not SUMIF, but the much better SUMPRODUCT, as this allows you to check multiple conditions.
The final formula will look like this:
=SUMPRODUCT((data[DateE]=A1)*(LEFT(data[ValueA],4)="2.21")*data[ValueD])
Now what does this do. SUMPRODUCT first builds a product and then sums that up. Let's assume the following values:
A1 = 2016-03-01
DateE = 2016-03-01
ValueA = 2.213454
ValueD = 3
The formula will then do the following:
(2016-03-01=2016-03-01) is 1
("2.21" = "2.21) is 1
3 is 3
1*1*3 = 3
Now if you change the date in A1, the value of your SUMPRODUCT cell should change accordingly.
As a starter I recommend using Tables - it's much easier to read and maintain your data: Insert-->Table.
e.g.
Here I have "Table1", with the Date column formatted as a Short Date.
Name Date Quantity
Alpha 17-Mar-16 1
Beta 15-Feb-16 2
Charlie 11-Mar-16 3
Dog 11-Feb-16 4
Echo 9-Feb-16 4
Foo 6-Jan-16 5
Then in a separate row/cell, you can input a formula to sum the quantity column where the data is from 1st Feb onwards.
Here I've used a different date format, but Excel is fine with it.
Feb Onwards Total: 14 =SUMIFS(Table1[Quantity],Table1[Date],">=01-Feb-16")
Feb Only Total: 10 =SUMIFS(Table1[Quantity],Table1[Date],">=01-Feb-16", Table1[Date],"<29-Feb-16")
Try something like this:
=SUMPRODUCT((INT(GLTB!$E$3:$E$26522)=INT(GLTB!$A$1))*(ROUNDDOWN(GLTB!$A$3:$A$26522,2)=2.21)*(GLTB!$D$3:$D$26522))
If this Returns and error, then one of two things:
your dates are not true dates but text that look like dates.
your have errors in your cells in some of the columns.
I have an Excel 2010 workbook with this formula:
=EOMONTH("01"&TEXT(B7,"MMM")&IF(MONTH(CMVAR)<4,TEXT(YEAR(CMVAR)-1,"YYYY"),TEXT(YEAR(CMVAR),"YYYY")),0)
It resolves when you are in the cell and press Enter, however when the workbook first opens or is refreshed, the result is #VALUE!. Here are the components:
B7 =IF(OR(MONTH(CMVAR)>6,MONTH(CMVAR)<4),"Apr",IF(MONTH(CMVAR)=4,TEXT(EDATE(CMVAR,-3),"MMM"),IF(MONTH(CMVAR)=5,TEXT(EDATE(CMVAR,-3),"MMM"),TEXT(EDATE(CMVAR,-3),"MMM"))))
which equates to Apr.
CMVAR 31/03/2015
The formula is being used because in April, May, June (first three fiscal periods) we require comparison data to show in the 12-period grid from the previous financial year. From July onwards we will have comparable data from the current year and so the grid can start from April. Once the month has been determined I'm trying to work out what the date of the end of that period is, taking into account that Jan, Feb and Mar are actually periods 10, 11 and 12 of the fiscal year and so the year element of the formula will be the prior year if CMVAR shows the date to be in any of those months.
Is there a better way that avoids the error or a way to fix it?
It is not completely clear what result do you expect for different values of CMVAR, but looking at your formula, I suppose you want it to be:
You can calculate Result with the following formula:
=EOMONTH(CMVAR,-MAX(MOD(MONTH(CMVAR)-4,12),3))
If the picture above does not show your expected output, can you please prepare similar table?
EDIT:
To explain how the problem is solved, I have created additional columns with intermediate calculations:
column C is the month difference between CMVAR and expected result - the goal is to find a formula returning this number
column D calculates month of CMVAR
column E - function MOD returns the remainder after number is divided by divisor (12).
column E matches all values of C, except 0,1,2, so in column F function MAX replaces those values with 3
Your EOMONTH formula is going wrong because the TEXT part should be in the form TEXT(date,"YYYY"). YEAR(CMVAR) gives a number rather than a date.
You could use instead
=EOMONTH("01"&TEXT(B7,"MMM")&IF(MONTH(CMVAR)<4,TEXT(EDATE(CMVAR,-12),"YYYY"),TEXT(CMVAR"YYYY")),0)
or this may be easier than using the TEXT functions
=EOMONTH("01"&B7&IF(MONTH(CMVAR)<4,YEAR(CMVAR)-1,YEAR(CMVAR)),0)
Your B7 formula is OK but could be simplified to
=IF(OR(MONTH(CMVAR)>6,MONTH(CMVAR)<4),"Apr",TEXT(EDATE(CMVAR,-3),"MMM"))
In table A I have a list of codes that contain a numerical component after 1-3 letters. I need to use the numerical value to find the corresponding year via the ranges detailed in table B.
Table A: Table B:
Code Year Value Min Value Max Year
AC19 ? 0 10 2011
ABC2 ? 11 20 2012
AC12 ? 21 30 2013
AFC30 ? 31 40 2014
GXC0 ? 41 50 2015
To separate out the number I have been using:
=(RIGHT(B7,LEN(B7)-(FIND("C",B7)+0)))
(Where B7 in this case is the first code in the table)
This works well as all codes have a C before the numerical component.
I found that using example numerical segments (without using the above formula) I could use VLOOKUP with the "True" flag. However when I attempted to run it using the numerical value generated with the above formula I got a #Ref! error.
Why would VLOOKUP suddenly stop working when using data collected from the formula above?
The ideal output would be:
Code Year
AC19 2012
ABC2 2011
AC12 2012
ACF30 2012
GXC0 2011
If AC19 is in B7, please try in C7 and copied down to suit:
=VLOOKUP(VALUE(RIGHT(B7,LEN(B7)-FIND("C",B7))),TableB,3)
Functions like LEFT, RIGHT and MID always return text results so you get a data mismatch between the text formatted lookup value and your numeric table - the VALUE function employed by punts converts the lookup value to a number
Another possible approach:
=LOOKUP(LOOKUP(100,RIGHT(B7,{1,2})+0),Table)
Explanation:
This part of the formula retrieves the number from the end of the string (assuming at most 2 digits):
LOOKUP(100,RIGHT(B7,{1,2})+0)
The RIGHT function is returning an array which consists of the last 1 and last 2 characters of B7, so when B7 = AC19 that returns an array like this
{"9","19"}
The quotes indicate that these are text values but we want numbers, so the +0 converts this to the following
{9,19}
Now when we lookup a large value (relatively in this case) of 100 in that array we get a match with the last number, in this case 19
[Note when there is only a single digit like in ABC2 the array is {"2","C"} which converts with +0 to {2,"#VALUE!"} - LOOKUP ignores the error and still returns the last number, i.e. 2]
so now 19 is the lookup value in our second LOOKUP function, assuming that Table is the the three columns of Table B (without headers).
This is a more "normal" LOOKUP function - 19 is looked up in the first column of Table and matches with the largest value smaller than or equal to 19, i.e. 11,. and then returns the value from the same row but in the last column of Table, i.e. 2012
LOOKUP with a table array always matches in the first column of that table and returns a value from the last column (unless the table is wider than it is tall, in which case it matches with the first row and returns a value from the last row)
See attached example below:
The named range Table is shown in orange and the results in blue
Column A Column B
13-06-2013 10:50
13-06-2013 11:30
13-06-2013 12:40
14-06-2013 10:30
I need to find the values which are before a particular entry date and time.
For example, say I want to find the values in the example table above that are immediately prior to the values "13-06-2013" and "12:30".
Since 12:30 is not in column B, how do I find the values I am looking for? The answer should be 13-06-2013 and 11:30.
C7 =VLOOKUP(A7&B7,A1:C4,3,TRUE)
Here A1 = B1&C1
A B C
1 414380.451388888888889 13-06-2013 10:50
2 414380.479166666666667 13-06-2013 11:30
3 414380.527777777777778 13-06-2013 12:40
4 414390.4375 14-06-2013 10:30
5
6 Enter date Enter Time Returned Time
7 13-06-2013 12:30 11:30:00
Setting 'range_lookup' as 'True' adds the flexibility to return the closest approximate value if the exact value is not available.
I think you're looking for something like this. using index and match.
I didn't take into account the date for now. but this gives you an example.
You can compare date strings with operators like > or < etc. Concatenate your values in columns A & B, compare to the desired date/time string. In cell C1 put the following formula, and then drag down:
="13-06-2013 12:30"<A1&" "&B1
or more specifically, depending on which "12:30" you want (AM or PM), ="13-06-2013 12:30AM" or ="13-06-2013 12:30PM"
Your data in column B may default to AM unless otherwise specified/imported differently, so you may need to tweak the data or to account for this.
Here is another approach to answering your question that uses a combination of MATCH, INDEX, and array operations to provide a compact formula solution that does not rely on helper columns.
I'll assume that your two columns of dates and times are in cells A2:B5, and the two date and time values that you want to look up are in cells A9:A10. Then the following two formulas will return what you require, the latest date and time values in your data that are less than or equal to the date and time that you are looking up. (The dollar signs in the formulas are hard on the eyes, but they are important if you will need to copy the formulas to other locations; for clarity, I omit them in the discussion that follows.)
DATE: =INDEX($A$2:$B$5,MATCH(A9+A10,$A$2:$A$5+$B$2:$B$5,1),1) --> 13-06-2013
TIME: =INDEX($A$2:$B$5,MATCH(A9+A10,$A$2:$A$5+$B$2:$B$5,1),2) --> 11:30 AM
These are array formulas and need to be entered with the Control-Shift-Enter key combination. (Of course, only the bits starting with the equal (=) sign and ending with the last parenthesis need to be entered into the worksheet.)
Things to consider:
The formulas assume that your data are valid Excel date and time values. Excel date values are whole numbers that count the number of days that have elapsed since January 1, 1900; Excel time values are decimal amounts between 0 and 1 that represent the fraction of 24 hours that a particular time represents. While your example data don't display AM or PM, I assume that their underlying values do have that information.
If your values are text (having been imported from another source, for instance), you should convert them to date/time values, if lucky, using only Excel's DATEVALUE and TIMEVALUE functions; if not so lucky, using some combination of Excel's string manipulation functions as well. (The values could be kept as strings, but you would almost certainly need to massage them so they would compare correctly "alphabetically" - much easier just to deal with Excel date/time values.)
If they are not already, your dates and times will need to be sorted from smallest to largest. (Your sample looks like they are sorted, and the formulas assume as much.)
How the formulas work
The basic idea behind the formulas is two-fold: first find the row in your data that holds the latest (largest) date and time that is still less than or equal to the date and time you are looking up. That row information can then be used to fetch the final result from each column of the data range (one for date and one for time).
Since both date and time figure in to what point in time is latest, the date and time components of both the value to be looked up and the values that will be searched must be combined somehow.
This can be achieved by simply adding the dates and times together. This does nothing more than what Excel does: an Excel date/time value has an integer part (the number of days since 1/1/1900) and a decimal part (the fraction of 24 hours that a particular time represents).
What is neat here is that the adding up of the dates and times - and the lookup of the particular date and time - can be done all at once, on the fly.
Take a look at the MATCH: The cells that contain the date and time to be looked up - A9 and A10 - are added together, and then this sum is matched against the sum of the date column (A2:A5) and the time column (B2:B5) - an operation that is possible of Excel's array arithmetic capabilities. The match returns a value of 2, indicating correctly that the date and time that fill your requirements are in row 2 of the data table.
DATE/TIME MATCH: = MATCH( A9+A10, A2:A5 + B2:B5, 1 ) --> 2
The 1 that is the final argument to the MATCH function is an instruction that the match results be calculated to be less than or equal to the value to be looked. It is the default value and is often omitted, or replaced with another value (for example, using a value of 0 will produce an exact match, if there is one).
(For readability, I've removed the dollar signs that are in the full formula; these anchor a range so that it remains the same even if the formula is copied to another location.)
Having figured out the row to look in, the rest of the formula is straightforward. The INDEX function returns the value in a data range that is at the intersection of a specified row and column. So, for the date in question, the formula reduces to:
DATE FETCH: = INDEX( A2:B5, 2, 1) --> 13-06-2013
In other words, INDEX is to return the value in the second row and first column of the data range A2:B5.
The formula for the time proceeds in exactly the same fashion, with the only difference that the value is returned from the second column of the data range.
Part 1:
I was able to construct a formula that does exactly what I want (from some examples), but yet, I'm unable to figure out how exactly it works. I have, starting with cell A1:
Price $
table 20
chair 10
Invoice Quantity
table 17
chair 1
chair 2
table 3
What I want is the final total (430) for the invoice which is computed as Quantity*Price for each item (17*20 + 1*10 + 2*10 + 3*20). the following formula correctly does this:
=SUMPRODUCT(B6:B9,SUMIF(A2:A3,A6:A9,B2:B3))
I understand the basics of SUMPRODUCT and SUMIF. But here, my argument for SUMIF's range is A2:A3, which makes me think the SUMIF would iterate through A2 and A3, and not through A8:A11 (which is the criteria). What gives?
Edit: the unclear part is, what exactly does SUMIF do (what is its iteration pattern) when the first two arguments are of different dimensions (here, the range is 2 cells while the criteria is 4 cells). Also, what is the "output" of SUMIF? An array? Of what dimensions?
Part 2:
In addition, if I ignored the quantity and simply wanted to add 20 whenever I saw a table and 10 whenever I saw a chair, I figured I would do:
=SUMIF(A2:A3,A6:A9,B2:B3)
But that doesn't work, and I have to enclose it with a SUMPRODUCT() for it to work and correctly evaluate to 60. Enclosing it within a SUM doesn't work either (probably because the SUMIF doesn't return an array?) Why?
I've read a bunch of tutorials and still can't understand this, and would be most grateful for a clear, intuitive explanation for both these cases. Thank you.
SUMIF can produce an array of results. If you take my formula
=SUMIF(A6:A9,A2:A3,B6:B9)
it says
For the criteria in A2 (ie table)
- look at A6:A9
- where table is matched, sum the corresponding value in B6:B9
- returns 20 (ie 17 +0 +0 +3)
- this is stored in the first position of the array
Then for the criteria in A3 (ie chair)
- look at A6:A9
- where table is matched, sum the corresponding value in B6:B9
- returns 3 (ie 0 +1 +2 +0)
- this is stored in the second position of the array
So the end array from the SUMIF is {20:3}
You can see the array result by highlighting the SUMIF formula in Excel's formula bar and then pressing F9
Then use SUMPRODUCT to multiple the count in the SUMIF by the $ values in B2:B3 to get total dollars
={20;3}*{20:10}
=20*20 + 3*10
= 430
Part 1
Rather than
SUMIF(A2:A3,A6:A9,B2:B3)
which produces a four element array of
={20;10;10;20}
(corresponding to table;chair;chair;table)
You should use
SUMIF(A6:A9,A2:A3,B6:B9)
which sums the values in B6:B9 against your two criteria in A2:A3 giving the desired result
={20;3}
(corresponding to table;chair)
and then use SUMPRODUCT to weight your array, ie
=SUMPRODUCT(SUMIF(A6:A9,A2:A3,B6:B9),B2:B3)
={20;3}*{20:10}
=430
Part 2
Use COUNTIF to return an array of the number of chairs and tables and then multiply by the vales using SUMPRODUCT
=SUMPRODUCT(B2:B3,COUNTIF(A6:A9,A2:A3))
={20;10} * {2;2}
=60
Well you only have one minor mistake:
probably because the SUMIF doesn't return an array?
SUMIF can work with arrays, thats why you formula SUMPRODUCT( SUMIF() ) works in first place, to SUMIF show an array you have to select a group of cells (like C6:C9) input the formula and use CTRL+SHIFT+ENTER instead of ENTER only. this generate an "array fomula", identified by curly brackets {} (those can only be entered with CTRL+SHIFT+ENTER, no manualy) and show the array formula and results