Sumif using offset and columns functions - excel

I want Excel to find a date and sum the preceding 12 cells in the row based on a keyed date.
I have 3 1/2 years of monthly financial data. I want to get the trailing twelve month totals based on a selected date. In my 'data input' tab row 111 is the month and row 112 are the respective revenues. H43 is my input cell for the date I want it to calculate from.
=SUMIF('data input'!$D$111:$AR$111,$H$43,OFFSET('data input'!$D$112,0,COLUMNS('data input'!$D$112:$AR$112),1,-12))/1000
If I key in 4/30/2019 I want the formula to return the total revenues for MAY 2018 - APR 2019. When I step through the formula, it always references the last 12 columns in the array regardless of what date I input and the value comes back to 0.

What your OFFSET function is doing is first going to the end (because the start column=the third argument is set to you by the COlUMNS() formula, which is constant and equal to the length), and then going back 12 months. This is why the referenced ones are the last 12.
The SUMIF is wrong in many ways. You are trying to map an array of all (about 50?) columns to an array of 12. The first and last parameter of SUMIF must be the same length. Not only that, but you have added H43 as the criterion, which even if you got the last parameter correct, would only return you the one month you selected, and not the rest 12.
What you really need to do is simply SUM the correct range found by OFFSET. Try this:
=SUM(OFFSET('data input'!$D$112,0,-12+MATCH($H$43,'data input'!$D$111:$AR$111,0),1,12))
(Having a negative size feels alien to me, so I moved the starting point back by 12)
You might have to play around with MATCH a bit, eg using a conversion function from H43 to the values present in the 111 row.
And of course, you might have to do some editing on the formula if your H43 belongs to the first 11 columns.

Related

Incrementing a Cell Reference By x

I am trying to average a large data set within Excel where there is data by 30 minute periods for each day of the month. I have a header for 'start date' and 'Start time' which displays 00:00:00 - 23:30:00 for each day, with the data in question in columns to the right. I am trying to develop a formula which averages data which concerns 00:00:00 - 11:30:00 for each day and 12:00:00 - 23:30:00 for each day (AM:PM).
I have one header for AM values and another for PM values, and Im looking to average both these elements for each day of the month
I have used the following formula which does work:
=AVERAGE(OFFSET(C6,24,0,-24))
This formula capture the range from 00:00:00 - 11:30:00 and averages it like I want, but when I drag the formula down to the next cell, C6 increments to C7, but I want it to increment by 48 each time, meaning C6 should become C54. This means when I drag it down each time it will average the AM values for 02/01/2019 and so on.
Is there any way the cell reference in the above formula can increment by 48 instead of 1 each time it is dragged down into another cell?
Sample Data
Expected output
I made up a dataset kind of like yours:
The formula I've used in F4 to obtain the average of values, when date is '01/01/2019' and time is AM, is AVERAGEIFS:
AVERAGEIFS function
My formula is:
=AVERAGEIFS($C$6:$C$101;$A$6:$A$101;E4;$B$6:$B$101;"<"&0,5)
You can use it and just drag down. As you can see in the image above, the formula returns 27,07
The formula will work only with AM because the criteria is "<"&0,5. In the column where you want to do the average of PM times, we would use the same, but changing criteria to ">="&0,5, this means:
=AVERAGEIFS($C$6:$C$101;$A$6:$A$101;E4;$B$6:$B$101;">="&0,5)
Hope you can adapt this to your needs.
NOTE: Because your data is in a Pivot Table (you never mentioned that), if the Pivot Table changes, you'll neeed to adapt the formula. A solution would be using ranges from row 6 until last one, so the formula will take always all the rows. Remember to not show total row or it may affect the result.
OPTION 2: In case you can add an extra column to original data (not in the Pivot Table), maybe this can help a lot.
I've used same data than before, but I added an extra column, named AM/PM with a formula on it:
=IF(B6<0,5;"AM";"PM")
It looks like this:
Then I created a Pivot Table based on it, with a configuration:
Field Start date to section of rows.
Field AM/PM to columns.
Field VALUE to values section, but instead of suming up, I did average operation.
I get this on my Pivot Table:
As you can see, AM for 01/01/2019 is 27,07 (the oher numbers are based on random numbers I made up).
Hope this can help.
If you absolutely must go with the AVERAGE(OFFSET()) solution I would have a 'helper' cell (in this case J6) with 1 in it, then J7 have =J6+48, then the main formula could be
=AVERAGE(OFFSET($C$6,J6,0,24))
Then when you copy the formula down, you'll also need to copy down from J7.
The Rows argument is purpose built for what you want to do. Going to efforts to change the reference cell defies this purpose.
Edited because I missed the AM/PM split:
I think, however, AVERAGEIFS() will fit your requirement better. This takes the average of all values in column C where the date in column A matches that in cell G6 (Change this to wherever your output is). This will avoid errors should any of your dates have any half hour periods missing.
=AVERAGEIFS($C:$C,$A:$A,G6,$B:$B,"<"&TIMEVALUE("12:00:00"))

How to use the current time & date to display specific value?

I'm trying to set up an excel sheet which displays the name of the person available at the current time and date. I have one sheet with a list of dates and times along with the persons name who is available at that time. For example:
- 01/07/19 09:00 Bob
- 01/07/19 10:00 Bill
- 01/07/19 11:00 Ben
I can do this successfully for a full day or week using the WEEKNUM or DAYNUM functions, and the week/day number listed against the list of names.
I can use NOW() to get the current date and time, but I'm unsure how I can use this to get the desired results.
I've tried searching online for the answer but have been unable to find what I'm looking for.
Based on my example above, if the current time is between 9:00 & 10:00 I want the name Bill to be displayed.
Based on your dates being actual dates stored as number for excel and not numbers stored as text, and same for time, then the following solution should work for you. You can test your data to see if its an actual date using:
=ISNUMBER(A2) `where A2 is the cell in question
If the formula returns true then you know your are dealing with a number that has been formatted to display as a date or time.
As a side note, dates are stored as integers and are the number of days since 1900/01/01 with that date being 1. Time is stored as a decimal representing the portion of the day. 0.5 would be 12 noon.
This solution assumes the data is layed out as per the image below.
In cell F1, place your NOW() function. I have manually entered the date to control the value for demonstration purposes.
In cell F2 enter the following formula:
=INDEX(C:C,AGGREGATE(15,6,ROW($A$2:$A$4)/((INT($F$1)=$A$2:$A$4)*(MOD($F$1,1)<=$B$2:$B$4)),1))
AGGREGATE will make a list or all row number and sort them from largest to smallest. All Those row numbers will be divided by your criteria checks. If your criteria results are ALL True, then the row is divided by 1 and remains unchanged. If a criteria is not met the Row number is divided by 0 which causes an error. The 6 in the function tells aggregate to ignore error results. So you wind up with a list or row numbers that march your criteria. The 15 in aggregate tells aggregate to sort the row numbers from largest to smallest. The 1 tells aggregate to return the row number in position 1 of the sorted list. Aggregate then passes that row number to INDEX which finds the row in the corresponding column and returns the address of that cell.
now just so you are aware. The break point for time was set so that the person beside the list time is the one that will be picked when that exact time is provided. Meaning for a time of 0900 on the specified day, Bob would be selected. At 10:00:01 Ben will be selected. At 11:00:01 an error will be generated. you can control this by placing the whole thing in an IFERROR function. At 00:00:00 Bob is selected.
I believe this will do what you want:
=INDEX(C2:C4,MATCH(NOW()-TODAY(),B2:B4,1))
Where column C contains the names and column B the times
If date and time are in one column, you can try:
=INDEX(B1:B3,MATCH(NOW(),A1:A3,1))
Where column B contains the names and column A the date and time
Here is one way:
Formula in F1:
=INDEX(C2:C4,MATCH(1,INDEX((A2:A4=TODAY())*(HOUR(B2:B4)<=HOUR(NOW()))*(HOUR(B2:B4)>=HOUR(NOW())),0,1),0))
What's happening? We use MATCH to get the first TRUE in an INDEX list that compares column A against TODAY times column B for HOUR.
We can leave out the second INDEX but that would make it an array formula to be entered through CtrlShiftEnter
Note that this example is made around 9:30 on the 4th of July.

Counting cells in Excel while comparing to the value of the previously counted cell

I'm trying to find a way, without writing VBA code, to count the number of cells, containing date and time, that are a full day apart while not counting the cells in between.
Example:
I have rows with the following values:
2018-03-19 18:33
2018-03-30 08:21
2018-03-30 11:21
2018-04-01 06:51
2018-04-01 08:17
2018-04-01 15:34
I want to get the number of cells that correspond to my conditions. In that case, the result I would like is 3, because the first cell and second cell are at least a day apart and the only value after, that is a full day following the second cell is the fourth cell.
To sum it up, I always need to go 24h from the last "counted" cell and count that cell etc.
I've found a way to do it using the SMALL function and outputting the results to multiple columns. Basically I start by getting the smallest date, then reference this value using another SMALL function but adding 1 to the previous value. But that way gives me the actual date and requires a different column for each iteration when in reality all a need is a count.
I also tried using SUMPRODUCT and comparing the range to an offset version of itself, but that compares the value to the last one in the array rather than the last "found" value.
I'm looking for suggestions and pointers on which Excel function to use. Any help will be greatly appreciated.
Thanks!
I can't think of a way of doing it without a helper column. If a helper column can be used, you could do it like this:
(1) Set B2 to 1.
(2) Copy this formula down from B3:
=IF(A3-INDEX(A:A,MATCH(2,B$1:B2))>=1,1,"")
Then just count up the 1's in B3 onwards.

Calculating Year-To-Date Accuracy removing predicted forecasts

I have an Excel spreadsheet and looking to add what I think will be a simple formula.
The calculation I am looking for is to calculate the Actual Year-to-Date (YTD) percentage of delivery performance.
Currently the YTD calculation takes the sum of cells B13:G13 (Bulks Accurate) divided by the sum of cells B4:G4 (No of Bulks Due per week). This doesn't show an accurate YTD as it also includes the forecasted number of bulks due in weeks 5 and 6. I am looking for a formula that will include a statement to say if the yellow cells in row 6 are not completed then the YTD calculation will not include the forecasted bulks due in row 4.
Thanks for your help in advance!
YTD Spreadsheet Image
Could you change the logic of row 11 (No of Bulks) to show the value in row 4, but only if row 6 AND 7 are blank? An IF AND formula would suffice, entered in B11 and then copied across:
=IF(AND(B6="",B7=""),0,B4)
Then, your YTD formula can be simply
=SUM(B13:G13)/SUM(B11:G11)
This way, even if no delivery has taken place when due, you enter "0" and the % will then include that week's due figure in the overall calculation.
1st Example Spreadsheet Img
If you can't change row 11 because it needs to match row 4, then you could insert a new row to implement the IF AND formula and amend my YTD formula above to use the new row instead of row 11.
If you can't add to the structure of your table at all, then you can still achieve the same result by using a SUMIFS as your divisor, as below:
=SUM(B13:G13)/SUMIFS(B4:G4,B6:G6,">=0",B7:G7,">=0")
The only difference with the SUMIFS route, is both the row 6 and row 7 values must be set as at least 0 for it to include row 4's value. The first route means row 4's value is included as soon as row 6 OR row 7 have a value entered.
2nd Example Spreadsheet Img

How To Ignore Blank Cells for a Formula

I'm tracking hours for my company and I need to see the updated hours daily. I have everything formatted how I want it, except I want two columns to show how many hours over and under each employees current hours are.
What I have right now is
=(D3-C3)+(F3-E3)+(H3-G3)+(J3-I3)+(L3-K3)+(N3-M3)+(P3-O3)
But it is including all the empty cells (for days that haven't been worked yet) as a zero.
I want a formula that can allow me to ignore those blank cells until they have content.
I can't just use a SUMIF >0 function because I need to count the number of hours employees have MISSED (i.e. scheduled 12 hrs, actually worked 0).
Here's an alternate approach to #Tom's, though it works on similar principles. This one, however, relies on your ability to add a couple of 'HELPER' rows, above your current data.
I'm assuming that row 1 will alternate between saying "PROJECTED", and "ACTUAL".
I'm assuming that row 2 will be dates for that week, in Date format. So A2 will be Jan 1 2015, B2 will be Feb 1 2015, C3 will be Feb 1 2015, or however often the time blocks go up. The key here is that the PROJECTED columns and the ACTUAL columns will each need the date in them.
The formula to check the variance between that row's PROJECTED amount and that row's ACTUAL amount, only for dates prior to today, is (for row 3 and copied down, and assuming the data goes to column Z):
=SUMIFS(A3:Z3,$A$1:$Z$1,"PROJECTED",$A$2:$Z$2,"<"&TODAY())-SUMIFS(A3:Z3,$A$1:$Z$1,"ACTUAL",$A$2:$Z$2,"<"&TODAY())
This checks to see the value of PROJECTED columns for that row, where the date is less than today, and subtracts the value of ACTUAL columns for that row, where the date is less than today.
If you are looking to compare with something other than TODAY(), you can set up a cell to be your 'comparison point'. Manual type the breakoff period you are concerned with into that cell, and replace "&TODAY()" with, say, "&AA1" [assuming your breakoff point is entered in cell AA1].
As it stands, either a very long series of IF's and OR's or an array formula:-
=SUM(IF(OR(D3="",C3=""),0,D3-C3),IF(OR(F3="",E3=""),0,F3-E3),IF(OR(H3="",G3=""),0,H3-G3),IF(OR(J3="",I3=""),0,J3-I3),IF(OR(L3="",K3=""),0,L3-K3),IF(OR(N3="",M3=""),0,N3-M3),IF(OR(P3="",O3=""),0,P3-O3))
=SUM(D3:P3*ISEVEN(COLUMN(D3:P3))*(C3:O3<>""))-SUM(C3:O3*ISODD(COLUMN((C3:O3))*(D3:P3<>"")))
The second one must be entered with CtrlShiftEnter
Note that it could easily be broken by insertion/deletion of columns.

Resources