Excel - Calculate date closest to system date - excel

I have 4 fields that holds date information that are updated periodically, I need to add a 5th field that does the following for reporting in a pivot table:
Checks if all the fields are blank, if not calculate the field value (a date) that is closest to the system date(current date), I have the first part but the second part of the if statement has me stumped.
IF(AND(GT14="",GU14="",GV14="",GW14="",GX14=""),"No Tollgate Dates",if statement to field that is closest to most recent month)
Any help would be greatly appreciated.

You could use the ABS function as Ron Rosenfeld says, either in a helper row to get the absolute differences and find the date corresponding to the smallest one, or using an array formula. There could be two solutions, e.g. if today is 22/8/16, 21/8/16 and 23/8/16 would both be correct if all other dates are further away.
=MIN(IF(ABS(GT14:GX14-TODAY())=MIN(ABS(GT14:GX14-TODAY())),GT14:GX14))
to find the earlier one
=MAX(IF(ABS(GT14:GX14-TODAY())=MIN(ABS(GT14:GX14-TODAY())),GT14:GX14))
to find the later one.
You could put this formula inside your existing formula, but as mentioned it could be a bit long.

This should do the trick:
=IF(SUM(GT14:GX14)=0,"No Tollgate Dates",INDEX(GT14:GX14,MATCH(SMALL(ABS(TODAY()-(GT14:GX14)),1),ABS(TODAY()-(GT14:GX14)),0)))
It is an array-formula, so you must use ctrl+shift+enter.

Related

How can I find the LAST match in a MMULT lookup in Excel?

I am a song leader at our church, and I am using a spreadsheet to track how recently we have used each hymn in our hymnbook. (In an effort to give some rotation to the songs we sing each week.)
Using some very helpful guides on Exceljet, I was able to construct a formula that does almost exactly what I want... It tells me how many weeks ago we used each song in our hymnbook. The problem is that it currently only shows me the FIRST time we used the song, not the LAST or most recent time, which is what I am really wanting to do.
The key issue I am stuck on is how to get the last entry from a MMULT() formula. A simplified example is shown below... I want to return the last date from column A where example hymn #15 is listed in columns B, C, or D.
My current formula does a great job of getting the first matching row (Row 3) but does not give me the last row (Row 5).
{=INDEX(ServiceDate,MATCH(1,MMULT(--(HymnNumbers=F2),TRANSPOSE(COLUMN(HymnNumbers)^0)),0))}
(ServiceDate= A:A and HymnNumbers = B:D)
Yes, I realize that there are other ways to find the last match, with MATCH and LOOKUP if I build a very complicated expression that searches for the last match in each column individually and finds the largest date value, but performance is also an issue with the size of the data in the actual spreadsheet I am using.
Is there is something simple that I can tweak in my current MMULT function to return the last match instead of the first one?
If dates are sorted you can reduce your formula to
=INDEX(A:A,AGGREGATE(14,6,ROW(A:A)/(B:D=F2),1))
If you have Office365 and dynamic formulas then you can use simply below formula.
=MAX(FILTER(A2:A9,(B2:B9=F2)+(C2:C9=F2)+(D2:D9=F2)))
If you do not have Office365 then try below Array formula.
=MAX(IF(B2:B9=F2,A2:A9,""),IF(C2:C9=F2,A2:A9,""),IF(D2:D9=F2,A2:A9,""))
Press CTRL+SHIFT+ENTER to evaluate the formula as it is an array formula.
Here's a longer formula that will return the last match. I'm not sure if it fits your definition of "very complicated". This version is longer since it does not use the latest version of excel.
=INDEX(A1:A10,MATCH(LARGE(MMULT(--(B1:D10=F2),TRANSPOSE(COLUMN(B1:D10)^0))*ROW(A1:A10),1),MMULT(--(B1:D10=F2),TRANSPOSE(COLUMN(B1:D10)^0))*ROW(A1:A10),0))
Your formula can be amended as follows...
=INDEX(ServiceDate,MATCH(2,1/MMULT(--(HymnNumbers=F2),TRANSPOSE(COLUMN(HymnNumbers))^0)))
However, you can avoid using MMULT as follows...
=INDEX(ServiceDate,LARGE(IF(HymnNumbers=F2,ROW(ServiceDate)-MIN(ROW(ServiceDate))+1),1))
Note that both these formulas need to be confirmed with CONTROL+SHIFT+ENTER.

Dates are not recognized

I have written a conditional formula to recognize two dates (greater than and last than). However, there are a few dates that are returning 'false'. All of the columns are formatted as a date. Can someone please help?
This is not a direct answer to the question asked, but as Scott said, the formula you use is much more complex than necessary. If you need to return a number for a date that falls within a period and the periods do not overlap, the following formula can be used:
=SUMPRODUCT((AQ3>=$DF$3:$DF$15)*(AQ3<=$DF$3:$DF$15),$DH$3:$DH$15)
If you need to process text values, it is more complicated. For example, if 'expired' is the only value (also for dates that do not fit into any period), then we can add the IF function to the previous formula:
=IF(SUMPRODUCT((AQ3>=$DF$3:$DF$15)*(AQ3<=$DF$3:$DF$15),$DH$3:$DH$15)>0,SUMPRODUCT((AQ3>=$DF$3:$DF$15)*(AQ3<=$DF$3:$DF$15),$DH$3:$DH$15),"expired")

How to best find the minimum positive difference of a value compared to a table efficiently using one Excell cell only?

I want to avoid VBA as much as possible and try to find a solution in a single cell--if possible. I have been trying to find a way to do so, but I have no idea how to.
The logic is summarized in the image below. In words, the conditions are:
Search Name is looked for in the Name column of the right table.
Search Date has to be greater than the Date in the right table.
Search Date minus Date has to be the positive minimum value.
Return the Pay that matches the criteria--which is 500 in the example.
You could use the following array formula (i.e. you need to enter it with Ctrl+Shift+Enter, if you are successful, you will see the braces appear in the formula bar):
=INDEX(G:G,MATCH(A2,IF(F:F=B2,E:E)))
The formula will return #N/A if there are no dates earlier than the Search Date.
NOTE: The dates have to be sorted in ascending order for this to work
EDIT: A little more robust that doesn't require sorting:
=INDEX(G:G,MATCH(MAX(IF((F:F=B2)*(E:E<A2),E:E)-A2),IF((F:F=B2)*(E:E<A2),E:E)-A2,0))
Note: Since this doesn't use MATCH, you won't get #N/A in case there are no dates earlier than the Search Date and you will instead get Pay (i.e. the header). If you want to get something else, then you can wrap the whole function in an IFERROR, relying on the fact that excel returns an error if one attempts to multiply a text with a number, something like this:
=IFERROR(Formula*1, "No pay matched")
This can be done with SumProduct, which does not require Ctrl-Shift-Enter
=SUMPRODUCT($G$2:$G$9,(A2>$E$2:$E$9)*(MONTH(A2)=MONTH($E$2:$E$9)*($F$2:$F$9=B2)))
The logic commands that the Search Date is in the same month as the Date column.
If you have the new Dynamic Array functions, that are currently in preview in the Insider Fast build of Excel 365, you can use
=FILTER($G$2:$G$9,(A2>$E$2:$E$9)*(MONTH(A2)=MONTH($E$2:$E$9)*($F$2:$F$9=B2)))

How to use AverageIf worksheet function for calculating average date differences (in case date is filled in)

I'm making a summary of a list of tasks, and the corresponding dates (start date, first answer date, ...).
It looks more or less like the following:
Title Start date First answer
Task1 29/06/2018 02/07/2018
Task2 09/05/2018
Task3 13/06/2018 14/06/2018
I would like to calculate the average time, needed for the first answer to be given. In case no first answer is given yet, this entry needs to be ignored in the calculation of the average.
In order to be able to understand the formulas better, I've decided to use names for the headers, like:
Name "Header_Title" has value "Title"
Name "Header_Start_Date" has value "Start Date"
Name "Header_First_Answer" has value "First answer"
Also, the number of entries, defined as COUNTA(OFFSET(Header_Title;1;0):A1048576) has a name: Total_Count.
Next to that, I've created names for the ranges of the column values:
"All_Start_Dates" is defined as =OFFSET(Header_Start_Date;1;0):OFFSET(Header_Start_Date;Total_Count;0)
"All_First_Answered" is defined as =OFFSET(Header_First_Answer;1;0):OFFSET(Header_First_Answer;Total_Count;0)
Explanation : take the first entry under the header (column title) and go to the row, corresponding to the last task.
This makes it very easy to write a formula for calculating the average difference between those date columns:
{=AVERAGE(All_First_Answered_Dates-All_Start_Dates)}
// mind the {} for showing this is an array formula
Now the problem is: how to use the AverageIf worksheet function in order not to take into account the cases where First answer is not filled in?
I already tried using ">0" and ">"&0, but this does not work, the formulas are said not to be valid:
{=AVERAGEIF(All_First_Answered_Dates-All_Start_Dates;">0")}
{=AVERAGEIF(All_First_Answered_Dates-All_Start_Dates;">"&0)}
Does anybody have an idea?
Thanks in advance
P.s.1. As you can see, I'm using cell range A1048576 as the last entry of column A, does anybody know a more elegant way to describe this?
P.s.2. One extra thing, which would make my life easier, is the possibility to see which cells have a name (I was thinking about conditional formatting, but I didn't find the way to do this). Does anybody know if there is a way to highlight individual cells, linked to a name?
So my suggested answer would be
=AVERAGEIF(All_First_Answered,">0")-AVERAGEIF(All_First_Answered,">0",All_Start_Dates)
I'm assuming here that all start dates are present but first answered dates may be missing: you could easily add an extra condition for start date if you used AVERAGEIFS. Both parts of the formula include the same conditions so they are working on the same rows.
The intermediate columns above are just included by way of explanation.
Try an array formula.
If you're not familiar with array formulas, the significant difference is you press and hold Ctrl+Shift then hit Enter instead of just pressing Enter. You will see the formula preceded and followed by curly brackets. Do not type those. Those will appear automatically.
=AVERAGE(IF(INDIRECT("C14:C"&LOOKUP(2,1/(A:A<>""),ROW(A:A)))=0,"",INDIRECT("C14:C"&LOOKUP(2,1/(A:A<>""),ROW(A:A)))-INDIRECT("B14:B"&LOOKUP(2,1/(A:A<>""),ROW(A:A)))))

Excel - Minimum and If statement - date error

I am trying to write a formula that checks the status and name to be ongoing and joe blogs (in this example), and once finding a match, will identify the oldest date of a ticket raised.
My formula currently includes:
=MIN(IF('Sheet2'!AA:AA="ONGOING",IF('Sheet2'!Q:Q="Joe Bloggs",'Sheet2'!B18:B49)))
I also tried:
=IF((AND(sheet2!$AA:$AA="ongoing", 'Sheet2'!$Q:$Q="Joe Bloggs")), MIN('Sheet2'!B18:B49),"No")
In Column B contains dates. Q contains names, AA contains the status.
At the moment when this runs I get the result '00/01/1990'.
I have done some checks to find the error, and appears to be around the targets name, as when the second formula is tried, the output is "no". The name is definitely in the Q column, and I have completed other formulas including countifs which have worked perfectly fine.
I have done a lot of searching to find nested ifs and min statements to have no joy , would be grateful of any advice / tips. It may be a simple error to some.
Try entering this as an array formula:
=MIN(IF(sheet2!AA:AA="ongoing",IF(sheet2!q:q="Joe Bloggs",sheet2!B:B)))
FYI I found the solution here.
You will have to apply a date format to the result.
Your first formula works well on my data (as below). If I close the formula with ENTER only, I get the result '37128' and if I close the formula with CTRL+SHIFT+ENTER I get the expected result, '25/08/2001'.
Edit: As #FocusWiz said in the comments, the only major difference (other than different column names) between my formula and yours is the the last range in your formula (B18:B49) is a different sized range to the other two, which are referring to full columns.
*This could be solved either by using the same row range for all three column references (AA18:AA49, Q18:Q49, B18:B49) or referencing the full column range for all three ranges (AA:AA,Q:Q,B:B).
This is your formula I'm talking about:
=MIN(IF('Sheet2'!AA:AA="ONGOING",IF('Sheet2'!Q:Q="Joe Bloggs",'Sheet2'!B18:B49)))
And this is the formula in my workbook F7:
=MIN(IF(B:B="ONGOING",IF(A:A="Joe Bloggs",C:C)))
As you can see in the formula editor, squiggly brackets '{}' show around the formula when it has been closed as an array formula.
If that doesn't work for you, please post some sample data with datatypes so we can help figure out what is causing the lookup value to miss the data.
While I like the technique offered by Patrick (I have frequently forgotten an "else" portion of a formula and gotten "false" as a value in a cell but never thought of a use for that...thank you!), I think this question highlights an issue we all can have with array formulas. As girlvsdata indicates, your original formula:
=MIN(IF(Sheet2!AA:AA="ONGOING",IF(Sheet2!Q:Q="Joe Bloggs",Sheet2!B:B)))
(modified above to be more generic for column B) will also work when entered as an array formula.
What likely happened is that somehow the formula got edited and was not re-entered as an array formula.
While I do not dislike array formulas, I do try to avoid them because I have fat fingers and will frequently mess them up by accidentally hitting the wrong key as I am modifying other cells.
Here is an alternative without using an array formula:
=INDEX(LARGE((Sheet2!Q:Q&Sheet2!AA:AA="Joe bloggs"&"ongoing")*(Sheet2!B:B),COUNTIFS(Sheet2!Q:Q,"Joe Bloggs",Sheet2!AA:AA,"ongoing")),1)
What it does is basically create a candidate date value for every row that has "joe bloggs" and "ongoing" which is equal to the date in column B for all such rows. All other rows get a zero candidate date value. The LARGE function takes the smallest nonzero date by counting the n valid candidates with the COUNTIFS function and taking the nth largest such candidate.

Resources