I have a table with two active columns. In Column A I have all the dates between, let`s say, January 1, 2012 to December 31, 2019. In column B I have a corresponding name. For instance:
[
etc.
I want to create ranges based on criteria, like:
The trick is, this should be done by calendar year, which means that during the 8-year period, I should have 8 set of 3 columns (from / to / name), one for each calendar year. If one range covers two years (let's say, November 1, 2012 to February 1st, 2013), the last row of 2012 should read
2012-11-01 to 2012-12-31
while the first row of 2013 will read
2013-01-01 to 2013-02-01
I managed to separate the ranges, but for some reason I am not able to go further and do that for each calendar year. Is there a way to do that?
Let's assume you want to place your 8 set of 3 columns starting from column G and that your list in the range D:F has headers in row 1 and data from row 2 on. In cell G1 write down your first year (2012), in cell H1 "From", in cell I1 "To" and in cell J1 "Name".
Now in cell H2 write this formula:
=IF(IF(OR(IF(AND($E2>=DATE(G$1,1,1),$D2<=DATE(G$1,12,31)),1,0),IF(AND($D2>=DATE(G$1,1,1),$E2<=DATE(G$1,12,31)),1,0)),1,0),MAX($D2,DATE(G$1,1,1)),"")
In cell I2 write this formula:
=IF(IF(OR(IF(AND($E2>=DATE(G$1,1,1),$D2<=DATE(G$1,12,31)),1,0),IF(AND($D2>=DATE(G$1,1,1),$E2<=DATE(G$1,12,31)),1,0)),1,0),MIN($E2,DATE(G$1,12,31)),"")
In cell J2 write this formula:
=IF(AND(H2<>"",I2<>""),F2,"")
Drag the 3 of them all the way down accordingly to your need. You can then copy the G:J range and paste any time you need next to itself; just change the year in the top left cell and it should do the trick.
Report any question you have or bug you have encountered. If, according to your judgment, this answer (or any other) is the best solution to your problem you have the privilege to accept it (link).
Related
I need to choose cells in one column that are between two dates, and then based on the rows that contain those dates, choose cells in another row that also contains content.
I didn't use ISBLANK because it counts a formula yet an empty cell as a not-blank. Instead check if there is content by "*".
Here is what I came up with, but instead of returning the number of cells, instead this returns TRUE (which obviously isn't what I want).
In the formula below I am assuming:
C:C is the whole column containing DATES.
E:E is the whole column containing CONTENT.
The date range in this case is January 1, 2018 to January 31, 2018.
"*" means is there is content in the cell
=IF(AND(COUNTIFS(C:C,">="&"2018-1-1",C:C,"<="&"2018-1-31"),COUNTIF(E:E,"*"))=0,"",AND(COUNTIFS(C:C,">="&"2018-1-1",C:C,"<="&"2018-1-31"),COUNTIF(E:E,"*")))
My goal is to:
count the numbers of the cells in column E that are between the dates in column C
if the whole formula is 0, then return a blank.
See this picture of a sample excel sheet to make my intent clear:
How can I get my formula working so it does as needed?
SOLUTION
Hi all, so thanks to #girlvsdata, we have a working solution. I had to do a couple edits to her code to work for my uses, but her formula overall works perfect. Here is the solution:
To choose all cells in column E that are not blank, in between the date range of all of January (unknown end date) based on the adjacent C column if that is your date column, then the solution is:
=IF(COUNTIFS(C:C,">="&"2018-1-1",C:C,"<="&EOMONTH("2018-1-1",0),E:E,"*")=0,"",COUNTIFS(C:C,">="&"2018-1-1",C:C,"<="&EOMONTH("2018-1-1",0),E:E,"*"))
Note that "2018-1-1" is January 1 2018, and EOMONTH("2018-1-1",0) is the last valid day of January in the year 2018 (in this case, 31, but if it is different another year (e.g. for February this works for leap years too) then it will be that last day). Also it eliminates the need to calculate which is the last day or every month, as well as months that have changing end dates dependent on the year (e.g. Feb). This is important to eliminate a margin of error.
The only thing you have to do to change the month is only change e.g. -1- (Jan) to -2- for Feb, or change the year for other years. With this formula you can ignore the day part.
If the answer is 0 (no cells have any content in between the range), then the cell is blank instead of 0. (GOod for when you want to create a sheet checking future dates for future reference when more rows are added to the sheet.
It also works across different sheets, just use, say your other sheet is called "Tracker" then use Tracker!C:C and Tracker!E:E. Hope it helps!
Thank you all! :D
(Please note: My local date format is day, then month)
With the data laid out as in your example above:
A B
1 Dates |Content
------------+-------
2 1/01/2018 |
3 2/01/2018 |123456
4 3/01/2018 |
5 4/01/2018 |12398
6 5/01/2018 |484
7 6/01/2018 |1538
8 7/01/2018 |
9 8/01/2018 |
10 9/01/2018 |
11 10/01/2018 |14648
12 11/01/2018 |
13 12/01/2018 |145615
14 13/01/2018 |
And with the date range in cells D2 and E2:
Date Start Date End
2/01/2018 7/01/2018
This formula returns the count:
=COUNTIFS(A:A,">="&D2,A:A,"<="&E2,B:B,">0")
This will depend on whether your numbers in Column B are formatted as text or number. If they are formatted as numbers, the above formula will work. If they are formatted as text, replace the last section ">0" with "*".
This formula adds the conditional part of your question:
=IF(COUNTIFS(A:A,">="&D2,A:A,"<="&E2,B:B,">0")=0,"",COUNTIFS(A:A,">="&D2,A:A,"<="&E2,B:B,">0"))
(If the formula returns 0, show blank)
I have the following Excel spreadsheet:
A B C D E F G
1 Year 2015 2016 2017 2018 2019 2020
2 Revenue 5.000 4.000 6.000
3 Years to go back: 2
4 Sum of Periods: 10.000
In Row 1 you can find the years 2015 til 2020 and in Row 2 the corresponding revenue of each year.
In Cell C3 the user should input the number of years to go back and sum up the revenues. For example if the user puts in a 2 Excel goes back 2 years and sums up the revenue of 2017 and 2016 which is 10.000 in the case above. For this I used the following formula:
=SUM(OFFSET($E$2,0,-C3):$E$2)
This formula and the described calculation above work perfectly so far.
However, in 2018 I will have to adjust the starting point of Cell $E$2 in the formula above to Cell $F$2. Ohterwise the year 2018 will be excluded from the calculation.
=SUM(OFFSET($F$2,0,-C3):$F$2)
My question is now how can I avoid this permanent re-adjustment every year?
--> I think the solution should be a formula that identifies the first "non empty" cell within in a Row and then starts counting back the years from this cell. Somehow a combination of the SUM, OFFSET, ROW & COLUMN formula.
You may use this formula:
=SUM(INDIRECT("R2C" & (MATCH(YEAR(TODAY()),$1:$1,0) - $C$3 + 1) & ":R2C" & MATCH(YEAR(TODAY()),$1:$1,0), FALSE))
But be aware I'm assume the current year - $C$3 is within your data range.
Brief explain:
YEAR(TODAY()) - it will return the year of current date, then you don't need to re-adjust every year
MATCH(lookup_value, lookup_array, match_type) - it will find the value matched in first row, and return the index of cell
INDIRECT() - Form the result of match to a R1C1 notation, and convert the text to excel range
A simpler formula could be to use the 4th parameter of OFFSET to set the width and to calculate the starting point of the OFFSET using YEAR(TODAY()0-2016
=SUM(OFFSET($B$2,0,YEAR(TODAY())-$C$1,1,$B$3))
NON VOLATILE OPTION
Well non volatile if it were not for the TODAY() function. Replace TODAY() with a cell containing the starting year as a date. or replace Year(Today()) with a cell reference just containing the year (integer) and then it will be a non volatile option.
=SUM(INDEX($1:$1,MATCH(YEAR(TODAY()),$1:$1,0)):INDEX($1:$1,MATCH(YEAR(TODAY()),$1:$1,0)-($C$3-1))
Volatile functions recalculate every time something on the spreadsheet changes.
Non volatile functions only recalculate when something affecting them changes.
The index function returns the cell address with in the range its looking. for a 2D range you need to give row and column reference. For a 1D range, you only need to give find the position within the range.
Match finds a value within a given range.
A B C D
1 Department Jan Feb Mar
2 Marketing 100 200 300
3 R&D 150 250 350
4 Marketing 300 400 500
I have a sample file like the above table.
The SUMPRODUCT formula below only sums the specific rows and column, which is row 2 to 20 and column B to C for summing
=SUMPRODUCT((A2:A20="Marketing")*(B2:C20))
Actual formula (from comments):
=SUMPRODUCT(INDEX(BW!$A$3:$AE$3,MATCH(C$35,BW!$1:$1,0)+MATCH("JAN 2016",BW!$F$2:$R$2,0)-1):INDEX(BW!$A$108:$AE$108,MATCH(C$35,BW!$1:$1,0)+MATCH("AUG 2016",BW!$F$2:$R$2,0)-1)*(BW!$B$3:$B$108=$E$1))
My questions, is there a way to make SUMPRODUCT dynamic, in a sense, it knows the first row to take will be 2nd and ends at 20.
As for the dynamic column to sum, it'll depend on the criteria. i.e. if the criteria is Feb and Mar, it'll take column C2:D20...again, the row is dynamic as well.
If you turn your range into a table called Table1 then the following should work:
=SUMPRODUCT((Table1[Department]="Marketing")*(INDIRECT("Table1[[Jan]:["&VLOOKUP("*",Table1[#Headers],COLUMNS(Table1),FALSE)&"]]")))
To make the SUMPRODUCT dynamic we can use INDEX/MATCH to find the extents of the data.
Then all that is need is to put the months wanted listed in one cell, I used I7
=SUMPRODUCT((ISNUMBER(SEARCH($B$1:INDEX(1:1,MATCH("ZZZ",1:1)),I7)))*($A$2:INDEX(A:A,MATCH("ZZZ",A:A))="Marketing")*B2:INDEX(A:DD,MATCH("ZZZ",A:A),MATCH("ZZZ",1:1)))
The INDEX(A:A,MATCH("ZZZ",A:A)) will find the last cell with text in Column A, and use that to set the extent of the dataset.
For the Last column we use INDEX(1:1,MATCH("ZZZ",1:1))
If you are not going to work with a ListObject (aka Structured) table, then a dynamic named range would certainly help.
Go to Formulas, Defined Names, Name Manager and when the Name Manager dialog opens, click New.
Give your defined name range a unique name; I've chosen Departments.
Leave the Scope as workbook and use the following formula for the Refers to: =BW!$A$1:INDEX(BW!$A:$M, MATCH("zzz",BW!$A:$A ), MATCH(1E+99,BW!$1:$1 )) Columns A:M will cover a Department column and Jan through Dec. Note that Jan 2016-Dec 2016 are real dates (e.g. 1/1/2016 to 12/1/2016) formatted as mmm yyyy.
You should end up with the following dynamic named range:
Now you can 'shape' the sections of the defined range using INDEX/MATCH function pairs.
=SUMPRODUCT((INDEX(Departments, 0, 1)=Q3)*
(INDEX(Departments, 0, MATCH(R3, INDEX(Departments, 1, 0), 0)):
INDEX(Departments, 0, MATCH(S3, INDEX(Departments, 1, 0), 0))))
My spreadsheet has 2 sheets.
Sheet 1 contains 30 days worth of values.
Each day's values are a maximum of 19 rows, consisting of names and correspoding values. The names that will appear for each day are not the same every day. In other words my name might appear on the 1st, 2nd and 14th of the month and not on any other days. (And these values may not be sorted.)
My second sheet will display only one persons values for the month, and I therefore use a lookup.
The formula for the 1st day is:
=LOOKUP("name";'Input Sheet'!$A$2:$A$20; 'Input Sheet'!B2:B20)
For the second day it would be:
=LOOKUP("name";'Input Sheet'!$A$22:$A$40; 'Input Sheet'!B22:B40)
The only thing that changes for each day is the lookup range/vector. I have a separate (hidden) column already that has calculated the correct starting row number, i.e. 22, 42, 62, but how would I use that number to change the lookup range on my formula?
Thanks a lot
Michael
The indirect() function will allow you to specify the range for your lookup in terms of another cell.
For example, if Sheet1 of the workbook has the numbers 1-10 going from A3:A12, where the starting row (3) is specified in cell B1 of the same worksheet.
3
1
2
3
4
5
6
7
8
9
10
Then to lookup the value 5 and place the answer on any other sheet of the workbook:
=LOOKUP(5,INDIRECT("Sheet1!$A"&Sheet1!$B$1&":$A$12"))
I have written this function that will give me a monthly sum for two columns: one has the date of each order, one has the cost of each order.
=SUMIF($C$1:$C$1000,">="&DATE(2010,6,1),$D$1:$D$1000)-SUMIF($C$1:$C$1000,">="&DATE(2010,7,1),$D$1:$D$1000)
Using data like this:
8/16/10 17:00 7.99
8/16/10 14:25 7.99
8/15/10 22:42 7.99
I end up with a table like this:
May 998
June 968.28
July 1239.76
August 514.96
However, now I would like to do daily sums and using my way I have to hand edit each row.
How can I do this better in Excel?
Use a column to let each date be shown as month number; another column for day number:
A B C D
----- ----- ----------- --------
1 8 6 8/6/2010 12.70
2 8 7 8/7/2010 10.50
3 8 7 8/7/2010 7.10
4 8 9 8/9/2010 10.50
5 8 10 8/10/2010 15.00
The formula for A1 is =Month(C1)
The formula for B1 is =Day(C1)
For Month sums, put the month number next to each month:
E F G
----- ----- -------------
1 7 July $1,000,010
2 8 Aug $1,200,300
The formula for G1 is =SumIf($A$1:$A$100, E1, $D$1:$D$100). This is a portable formula; just copy it down.
Total for the day will be be a bit more complicated, but you can probably see how to do it.
Use pivot tables, it will definitely save you time. If you are using excel 2007+ use tables (structured references) to keep your table dynamic. However if you insist on using functions, go with Smandoli's suggestion. Again, if you are on 2007+ use SUMIFS, it's faster compared to SUMIF.
Following up on Niketya's answer, there's a good explanation of Pivot Tables here:
http://peltiertech.com/WordPress/grouping-by-date-in-a-pivot-table/
For Excel 2007 you'd create the Pivot Table, make your Date column a Row Label, your Amount column a value. You'd then right click on one of the row labels (ie a date), right click and select Group. You'd then get the option to group by day, month, etc.
Personally that's the way I'd go.
If you prefer formulae, Smandoli's answer would get you most of the way there. To be able to use Sumif by day, you'd add a column with a formula like:
=DATE(YEAR(C1), MONTH(C1), DAY(C1))
where column C contains your datetimes.
You can then use this in your sumif.
Add a column to your existing data to get rid of the hour:minute:second time stamp on each row:
=DATE(YEAR(A1), MONTH(A1), DAY(A1))
Extend this down the length of your data. Even easier: quit collecting the hh:mm:ss data if you don't need it. Assuming your date/time was in column A, and your value was in column B, you'd put the above formula in column C, and auto-extend it for all your data.
Now, in another column (let's say E), create a series of dates corresponding to each day of the specific month you're interested in. Just type the first date, (for example, 10/7/2016 in E1), and auto-extend. Then, in the cell next to the first date, F1, enter:
=SUMIF(C:C, E1, B:B )
autoextend the formula to cover every date in the month, and you're done. Begin at 1/1/2016, and auto-extend for the whole year if you like.
If the second row has the same pattern as the first row, you just need edit first row manually, then you position your mouse pointer to the bottom-right corner, in the mean time, press ctrl key to drag the cell down. the pattern should be copied automatically.