I have an Excel spreadsheet with two columns, the first with dates and the second with values. The dates span over several years. I want to write a function that retrieves the maximum value for each year.
For example, in the following data set:
June 3, 2009 3
June 5, 2009 5
January 1, 2010 7
July 7, 2010 1
April 1, 2013 12
May 2, 2013 77
The function for the year 2009 would return the value 3
The function for the year 2010 would return the value 7
The function for the year 2013 would return the value 77
All of the dates are in column A
All of the values are in column E
In column J I have a list of years needed, i.e. J1 = 2009, J2 = 2010, J3 = 2011, etc.
the function for each year is located in column K corresponding to the year in column J, i.e. the maximum value for 2009 is in cell K1, the maximum value for 2010 is in cell K2, etc.
I believe this function should look something like:
=MAX(some type of function that gives me the range of dates per year)
Thanks for all the help
You can use:
=MAX(IF(YEAR($A$2:$A$9)=J1,$E$2:$E$9,0))
Array Formula press Ctrl+Shift+Enter at the same time
You can drag it
$A$2:$A$9 the column of Date $ for absolute references change it to your last row
$E$2:$E$9 the column of values change it to your last row
J1 the first Date in the new column it will change automatically when dragging
If will test the year of the Date to J1 and return the corresponding Value
Let's consider this example:
+---+------------+------+-------+-------------+
| | A | B | C | D |
+---+------------+------+-------+-------------+
| 1 | Date | Year | Value | Max of year |
| 2 | 03/06/2009 | 2009 | 3 | 5 |
| 3 | 05/06/2009 | 2009 | 5 | 5 |
| 4 | 01/01/2010 | 2010 | 7 | 7 |
| 5 | 07/07/2010 | 2010 | 1 | 7 |
| 6 | 01/04/2013 | 2013 | 12 | 77 |
| 7 | 02/05/2013 | 2013 | 77 | 77 |
+---+------------+------+-------+-------------+
You have two choices.
1st solution (easiest)
Add one column named YEAR where you calculate the year of each cell of column A. Then you build a pivot table with max of the column C.
2nd solution (hardest)
Use the matrix function. Add a column B with the year calculated. Then in cell D2 write the following: =MAX(IF(B:B=B2,C:C)) and press CTRL + SHIFT + ENTER.
The formula will be transofrmed (into a matrix function) like ={=MAX(SE(B:B=B7;C:C))}. Now you can drag the cell D2 to the end of the column (D7 in the example).
You can also use a combination of my second solution with the YEAR function as answered by #Yass.
I managed to answer the question for myself. If I defined the columns corresponding to the dates and values as arrays then I can use the following function:
=MAX(IF(Transaction_Date<=DATE(J1,12,31),IF(Transaction_Date>=DATE(J1,1,1),Account_Balance)))
Related
I have a question regarding conditional formatting in Excel.
I have a sheet that acts as a calendar for my team members whereby calendar dates are in row 1 and each person’s name in column A. Each person occupies 3 rows unmerged, so the first name occupies rows 2 to 4, the next person 5 to 7, and so on. If the person will not be at work on a particular day, a “out of office” will be written on the respective first row. Assuming that 1 January occupies column B and that the first person will be out of office then, the value of cell B2 will be “out of office”. Using conditional formatting, I was able to highlight B2:B4 without issues. However, I was only able to do this for a single person.
I would like to know if there is a way of extending some conditional formatting formula to all 20 members so that I do not have to do the same thing for another 19 times (more if new members join).
So if any cell in column B contains "out of office" then this cell and the next 2 cells below shall be formatted? Or in other words a cell shall be formatted if itself or the cell 1 row above or the cell 2 rows above contains "out of office"?
This can be achieved using the following conditionla formatting rule for whole column B:
Conditional formatting rule based on formula:
=OR(B1="out of office",B1048576="out of office",B1048575="out of office")
Background: In CF the references are like a carousel. So what in B1 is
=OR(B1="out of office",B1048576="out of office",B1048575="out of office")
will be in B2 then
=OR(B2="out of office",B1="out of office",B1048576="out of office")
(B1048576 plus 1 row = B1)
and in B3 then
=OR(B3="out of office",B2="out of office",B1="out of office")
If you are using Conditional Formatting Formula, then you can use the following code to retrieve the value from the current or previous row in the pattern 2, 5, 8, 11, etc:
INDEX(A:A, 3*INT((ROW()-2)/3)+2, 1)
To break it down: Using INDEX(A:A and , 1) will get us a row from Column A (of course, this moves across as your Format Condition does) - the row itself is specified by the ungainly mess in the middle: 3 * INT((ROW() - 2) / 3) + 2
Putting that kludge into plain-text: Start with the current row, subtract 2, round down to a multiple of 3, then add 2 again
Row | Subtract 2 | Round down to 3 | Add 2
1 | -1 | -3 | -1
2 | 0 | 0 | 2
3 | 1 | 0 | 2
4 | 2 | 0 | 2
4 | 3 | 3 | 5
.. | .... | .... | ..
28 | 26 | 24 | 26
29 | 27 | 27 | 29
30 | 28 | 27 | 29
31 | 29 | 27 | 29
32 | 30 | 30 | 32
So - you can now just apply whole-column conditional formatting, with a formula something like this:
=INDEX(A:A, 3*INT((ROW()-2)/3)+2, 1) = "Out of Office"
And it will apply to blocks of 3 rows at a time in each column, starting at Row 2 (or -1)
In excel, I have data divided into
Year Code Class Count
2001 RAI01 LNS 9
2001 RAI01 APRP 4
2001 RAI01 3
2002 RAI01 BPR 3
2002 RAI01 BRK 3
2003 RAI01 URE 3
2003 CFCOLLTXFT APRP 2
2003 CFCOLLTXFT BPR 2
2004 CFCOLLTXFT GRL 2
2004 CFCOLLTXFT HDS 2
2005 RAI HDS 2
where I need to find the top 3 products for that particular customer for that particular year.
The real trick here is to rank each row based on a group.
Your rank is determined by your Count column (Column D).
Your group is determined by your Year and Code (I think) columns (Column A and B respectively).
You can use this gnarly sumproduct() formula to get a rank (Starting at 1) based on the Count for each Group.
So to get a ranking for each Year and Code from 1 to whatever, in a new column next to this data:
=SUMPRODUCT(($A$2:$A$50=A2)*(B2=$B$2:$B$50)*(D2<$D$2:$D$50))+1
And copy that down. Now you can AutoFilter on this to show all rows that have a rank less than 4. You can sort this on Customer, then Year and you should have a nice list of top 3 within each year/code.
Explanation of sumproduct.
Sumproduct goes row by row and applies the math that is defined for each row. When it is done it sums the results.
As an example, take the following worksheet:
+---+---+---+
| | A | B |
+---+---+---+
| 1 | 1 | 1 |
| 2 | 1 | 4 |
| 3 | 2 | 2 |
| 4 | 4 | 1 |
| 5 | 1 | 2 |
+---+---+---+
`=SUMPRODUCT((A1:A5)*(B1:B5))`
This sumproduct will take A1*B1, A2*B2, A3*B3, A4*B4, A5*B5 and then add those five results up to give you a number. That is 1 + 4 + 4 + 4 + 1 = 15
It will also work on conditional/boolean statements returning, for each row/condition a 1 or a 0 (for True and False, which is a "Boolean" value).
As an example, take the following worksheet that holds the type of publication in a library and a count:
+---+----------+---+
| | A | B |
+---+----------+---+
| 1 | Book | 1 |
| 2 | Magazine | 4 |
| 3 | Book | 2 |
| 4 | Comic | 1 |
| 5 | Pamphlet | 2 |
+---+----------+---+
=SUMPRODUCT((A1:A5="Book")*(B1:B5))
This will test to see if A1 is "Book" and return a 1 or 0 then multiple that result by whatever is B1. Then continue for each row in the range up to row 5. The result will 1+0+2+0+0 = 3. There are 3 books in the library (it's not a very big library).
For this answer's sumproduct:
So ($A$2:$A$50=A2) says to return a 1 if A2=A2 or a 0 if A2<>A2. It does that for A2 through A50 comparing it to A2, returning a 1 or a 0.
(B2=$B$2:$B$50) will test each cell B2 through B50 to see if it is equal to B2 and return a 1 or 0 for each test.
The same is true for (D2<$D$2:$D$50) but it's testing to see if the count is less than the current cells count.
So... essentially this is saying "For all the rows 1 through 50, test to find all the other rows that have the same value in Column A and B AND have a count less than this rows count. Count all of those rows up that meet that criteria, and add 1 to it. This is the rank of this row within its group."
Copying this formula has it redetermine that rank for each row allowing you to rank and filter.
Column: A | B | C | D
Row 1: Variable | Margin | Sales | Index
Row 2: banana | 2 | 20 | 1
Row 3: apple | 5 | 10 | 2
Row 4: apple | 10 | 20 | 3
Row 5: apple | 10 | 10 | 4
Row 6: banana | 10 | 15 | 5
Row 7: apple | 10 | 15 | 6
"Variable" sits in column A, row 1.
"Fruit" refers to A2:A6
"Margin" refers to B2:B6
"Sales" refers to C2:C6
"Index" refers to D2:D6
Question:
From the above table, I would like to find the row of two largest "Sales" values when Fruit = "apple" and Margin >= 10. The correct answer would be values from row 3 and 6. I have tried the following methods without success.
I have tried
=LARGE(IF(Fruit="apple",IF(Margin>=10,Sales)),{1,2}) + CSE
and this returns 20 and 15, but not the row.
I have tried
=MATCH(LARGE(IF(Fruit="apple",IF(Margin>=10,sales)),{1,2}),Sales,0)+1
but returns row 2 and 6 as the first matches to come up are the 20 and 15 from "banana" not "apple".
I have tried
=INDEX(D2:D7,LARGE(IF(Fruit="apple",IF(Margin>=10,ROW(Sales)-ROW(INDEX(Sales,1,1))+1)),{1,2}),1)
But this returns row 7 and 5 (i.e. "Index" 6 and 4) as these are just the first occurrences of "apple" starting from the bottom of the table. They are not the largest values.
Can this be done with an Excel formula or do would I need a macro? If macro, can I please get help with the macro? Thank you!
use this formula:
=INDEX(D:D,AGGREGATE(15,6,ROW($A$2:$A$7)/(($B$2:$B$7>=10)*($A$2:$A$7="apple")*($C$2:$C$7 = AGGREGATE(14,6,$C$2:$C$7/(($B$2:$B$7>=10)*($A$2:$A$7="apple")),F2))),1))
I put 1 and 2 in F2 and F3 respectively to find the first and second.
Edit #1
to deal with duplicates we need to add (COUNTIF($G$1:G1,$D$2:$D$7) = 0). The $G$1:G1 needs to refer to the cell directly above the first placement of this formula. So the formula needs to start in at least row 2.
=INDEX(D:D,AGGREGATE(15,6,ROW($A$2:$A$7)/((COUNTIF($G$1:G1,$D$2:$D$7) = 0)*($B$2:$B$7>=10)*($A$2:$A$7="apple")*($C$2:$C$7 = AGGREGATE(14,6,$C$2:$C$7/(($B$2:$B$7>=10)*($A$2:$A$7="apple")),F2))),1))
I am attempting to write a macro to find February 2nd of each year in column A and then count the number of rows (days) until the value in column B changes. This count could be put in a new column, column C, but on the same row as the February 2nd that it correlates to, in this case row 3.
Using the table below the output to C3 would be 5. I am not counting the day of February 2nd but I am counting the day the change occurs. This is for 100+ years that I will need to loop through.
id | A | B | C
----------------------------
1 | 1946/01/31 | 0 |
2 | 1946/02/01 | 0 |
3 | 1946/02/02 | 0 |
4 | 1946/02/03 | 0 |
5 | 1946/02/04 | 0 |
6 | 1946/02/05 | 0 |
7 | 1946/02/06 | 0 |
8 | 1946/02/07 | 2 |
9 | 1946/02/08 | 0 |
The real challenge is to do it with a formula. Well, 2 formulas.
The first formula in cell E2 finds the date 2nd Feb by looking for "02/02" at the end of the text in column B and if it is found it places the contents of C2 in that cell. if it's not found it compares C1 with D1, the 2 cells above to see if they are the same because a match was previously found and if so it takes the contents of the cell above. This results in the zeros you can see in column E between 2nd Feb and the point where column C changes.
Formula for E2 and then autofill down to the end of your data
=IF(AND(MONTH(B2)=2,DAY(B2)=2),C1,IF(AND(E1<>"",E1=C1),E1,""))
Now all we need to do is count the cells in column D by looking for the first non blank cell in column D AND(E1="",E2<>"") and then count all the cells that match that cell. I'm not sure what gap you're expecting to find but you can change the 200 to ensure that you count everything. The last part is to take away 1 so that the 2nd feb row is not being counted.
Formula for D2 and then autofill down to the end of your data
=if(AND(E1="",E2<>""),countif(E2:E200,E2)-1,"")
Suppose i need to multiply the entries in these two columns in the following order in MS Excel
This is just an example
A | B
1 | 5
2 | 10
3 | 15
4 | 20
bolck1:1*5
block2:(2*5)+(1*10)
block3:(3*5)+(2*10)+(1*15)
block4:(4*5)+(3*10)+(2*15)+(1*20)
how would i do it?
I used SUMPRODUCT(A4:A1,B4:B1) but it returned the same old sum 150 as was the case with SUMPRODUCT(A4:A4,B1:B4).
You could add a helper column. In C1 put:
=SUMPRODUCT(A1*INDEX($B$1:$B$4,1):INDEX($B$1:$B$4,COUNT($B$1:$B$4)-(ROW(1:1)-1)))
Drag it down then total the results: