Excel: Matching the closest date from range of dates - excel

I'm trying to display the header of the column that its cell that contains a date, is the closest (out of 3 other cells with dates, B2:D2) to the a specific cell (A2)
So here's my sheet:
A B C D
1 | T1 | T2 | T3 | T4 |
2 | 5/1/2013 | 5/31/2013 | 2/5/2013 | 3/2/2013 |
A2 = a date.
B2:D2 = 3 dates, can also be blank
I've tried using the following array formula that I found online:
=IF(COUNT($B2:$D2)>0,INDEX($B$1:$D$1,MATCH(MIN(ABS($B2:$D2-$A2)),ABS($B2:$D2-$A2),0)),"")
But it sometimes when there is only one or two dates, it gives me the wrong header. I would also like to avoid using array formulas, but couldn't convert it to a regular one.
Would highly appreciate assistance on this matter

Can you give an instance were the array formula you are using isn't working ? It worked for the cases I tried.
You can avoid using the array formula if you are prepared to have another row with the difference in the dates and your date cell A2.
Push your rows down one row, so the headings are on row 2 and the dates on row 3 and enter the following formula across row 1, starting at cell B1
=ABS(B3-$A$3)
Drag this across and enter the following HLOOKUP to get your header row
=HLOOKUP(MIN(B1:D1),B1:D3,2,FALSE)
if you can't move your rows down for some reason you can use a combination of MATCH and INDEX (which is slower) . If you were to put the difference function =ABS(B2-$A$2) across row 7 the formula would be
=INDEX(B1:D1,1,MATCH(MIN(B7:D7),B7:D7,0))

Okay so the answer was fairly simple.
I went back to the sheet to investigate the scenarios in which this happens.
It seems that when A2 is blank (= no date to make the comparison) it just gives out the only date available from B2:D2.
By simply adding another condition to the IF statemented that would work only if A2 has a value resolved the issue. So we're checking if both A2 and B2:D2 has values in them (with B2:D2 needs to be at least one:
=IF(AND(COUNT($B2:$D2)>0,$A2>0),......)
and here is the full formula
=IF(AND(COUNT($B2:$D2)>0,$A2>0),INDEX($B$1:$D$1,MATCH(MIN(ABS($B2:$D2-$A2)),ABS($B2:$D2-$A2),0)),"")
Thanks for making me go back to the investigate! :D

For a non-array alternative, you could try:
=LOOKUP(2,1/FREQUENCY(0,ABS(B2:D2-A2)),B$1:D$1)
in place of the INDEX(...) part of the formula.

Related

Excel: Obtain a column by sorting anotr one values

I need to automatically obtain a sorted column of values from another given column values, like in the sample:
I have I need A unchanged, and also B obtained from A
A A B
-----------------
1 1 0
0 0 0
3 3 1
8 8 3
0 0 8
I mean if the values from A changes, the B should change accordignly...
Is that possible in MS Excel?
Here a sandbox and sample:
http://1drv.ms/1SkqMhS
If you put The formula =SMALL(A:A,ROW()) in B1 and copy down then the cells in B will be linked to the cells in A in such a way that the numbers in B will be the numbers in A in sorted order. This won't be efficient for larger ranges but will work fine for small to medium size ranges.
If you want the numbers to start in a lower row, say B2 because you have a header in B1, adjust ROW() to something like ROW()-1.
A word of warning: Use of ROW() can make a spreadsheet somewhat fragile in that formulas that involve it can change their meaning if rows are inserted or deleted or the block containing the formula is moved to somewhere else. Rather than using ROW(), there is something to be said for adding a helper column which numbers the data in A (which would then be in e.g. B) and referring to these numbers rather than small. For example, in:
If I put the formula
=SMALL($B$2:$B$5,A2)
In C1 and copy down, it works as intended. In response to a question you raised in the comments, I added still another column which gives an index where the corresponding value occurs. To do this I wrote in D2 (then copied) the formula
=MATCH(C2,$B$2:$B$5,0)
Of course. Highlight your range and in the Data tab, click "Sort", then you can choose how you want to sort your data:
If column B has information that is to be used with Column A (like next to A1 is "Car"), and you want to sort the whole table, based on Column A, then just select Columns A and B, then sort by column A.
Found the answer, thanks to John Coleman !
Just some minor details like cell value fixing (with $, like A$2)and the -1+ROW adjustment for the 1 header row!

Formula returning Column A value for row containing MAX value of a range

Assume I have the following table:
A B C
1 Week 1 Week 2
2 Melissa 114.7 82.8
3 Mike 105.5 122.5
4 Andrew 102.3 87.5
5 Rich 105.3 65.2
The names are in column A, the Week values are in Row 1. (So A1 is blank, B1 = Week 1, and A2 = Melissa.)
I'm trying to build a formula that looks at all the values in a known range (in this example, B2:C5), chooses the highest value of the bunch (here, 122.5) and returns the name of the person from Column A that got that value. If I use this formula, it works for the values in range B2:B5:
=INDEX(A2:A5,MATCH(MAX(B2:B5),B2:B5,0))
That returns Melissa but if I expand the range to include more than just column B's values, I get an #N/A returned:
=INDEX(A2:A5,MATCH(MAX(B2:C5),B2:C5,0))
The weird part (to my simple brain) is that the MATCH portion of the formula works fine, if I just put in this formula, it returns the highest value of 122.5 from C3:
=MAX(B2:C5,B2:C5,0)
So clearly something it going wrong when I'm using either the MATCH or INDEX commands.
Hopefully this makes sense and someone can point out my error?
Try this:
=INDEX(A:A,MAX((B2:C5=MAX(B2:C5))*ROW(B2:C5)))
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
Note: Match can only search one vector at a time. It can be one row or one column or one array. It cannot be two or more rows or columns or a 2D array.
Do it "twice"? Please try:
=INDEX(A2:A5,IFERROR(MATCH(MAX(B2:C5),B2:B5,0),MATCH(MAX(B2:C5),C2:C5,0)))
If you are going to have up to 52/53 weeks to cope with I'd suggest instead inserting a helper column with the MAX for each row. Make that an new (inserted) ColumnA (say =MAX(C2:BC2) etc.) and a simple VLOOKUP should serve, say:
=VLOOKUP(MAX(A:A),A:B,2,0)

Excel matching multiple cells for duplicates

I need to populate a cell where the result is either valid or an error based on the following criteria. I'm not sure if using Match, Lookup formulas will work for this problem.
Given
A B C
+-----------+-----------+----------
1 | IntRef | Value | Result
2 |-----------|-----------+----------
3 | r01 | Value 123 | Success (because B4 matches B3)
4 | r01 | Value 123 | Success (because B3 matches B4)
5 | r02 | Value ABC | Failed (because B6 differs from B5)
6 | r02 | Value XYZ | Failed (because B5 differs from B6)
Success Criteria
Scan each IntRef (A) column for all duplicate keys. Where they match
on a row check the Value column (B). Where all matching cells have
the same value set their result cell (C) to Success.
Failed Criteria
Scan each IntRef (A) column for all duplicate keys. Where they match
on a row check the Value column (B). Where all matching cells have a
different value set their result cell (C) to Failed.
I am sure there is a formula that can be entered into each cell of column C which will do a lookup for each IntRef cross referencing the contents of column B where the match occurs. This is going beyond Excel formula knowledge.
Is it possible to create and help formulate the calculation of the success/failed criteria (Column C)?
This appears to do the trick...
{=IF(COUNT(IF($B$3:$B$6=B3,IF($C$3:$C$6=C3,1)))=COUNTIF($B$3:$B$6,B3),"Success","Failed")}
Note that that's an array lookup formula (meaning you need to hit Ctrl+Shift+Enter when entering it).
This formula basically counts the number of times the A and B column values appear together and compares this to the number of times the A column value appears. If the two counts match, you have success.
Try this formula:
=IF(SUMPRODUCT(IF(A2=A$2:A$9,1,0),IF(B2=B$2:B$9,1,0))>1,"Success","Fail")
Assuming you have your data like this:
Formula is entered as Array Formula in C2 by pressing Ctrl+Shift+Enter.
Then just copy on the remaining cells.
I just added and changed the position of some data for testing.
Hope this works for you. Change the Range to suit your data size.

Add cell string to another cell if 2 cells are the same for 2 rows

I'm trying to make a macro that will go through a spreadsheet, and based on the first and last name being the same for 2 rows, add the contents of an ethnicity column to the first row.
eg.
FirstN|LastN |Ethnicity |ID |
Sally |Smith |Caucasian |55555 |
Sally |Smith |Native American | |
Sally |Smith |Black/African American | |
(after the macro runs)
Sally |Smith |Caucasian/Native American/Black/African American|55555 |
Any suggestions on how to do this? I read several different methods for VBA but have gotten confused as to what way would work to create this macro.
EDIT
There may be more than 2 rows that need to be combined, and the lower row(s) need to be deleted or removed some how.
If you can use a formula, then you can do those:
Couple of assumptions I'm making:
Sally is in cell A2 (there are headers in row 1).
No person has more than 2 ethnicities.
Now, for the steps:
Put a filter and sort by name and surname. This provides for any person having their names separated. (i.e. if there is a 'Sally Smith' at the top, there are no more 'Sally Smith' somewhere down in the sheet after different people).
In column D, put the formula =if(and(A2=A3,B2=B3),C2&"/"&C3,"")
Extend the filter to column D and filter out all the blanks.
That is does is it sees whether the names cells A2 and A3 are equal (names are the same), and whether the cells B2 and B3 are equal (surnames are the same).
If both are true, it's the same person, so we concatenate (using & is another way to concatenate besides using concatenate()) the two ethnicities.
Otherwise, if either the name, or username, or both are different, leave as blank.
To delete the redundant rows altogether, copy/paste values on column D, filter on the blank cells in column D and delete. Sort afterwards.
EDIT: As per edit of question:
The new steps:
Put a filter and sort by name and surname. (already explained above)
In column E, put the formula =IF(AND(A1=A2,B1=B2),E1&"/"&C2,C2) (I changed the formula to adapt to the new method)
In column F, put the formula =if(and(A1=A2,B1=B2),F1+1,1)
In column G, put the formula =if(F3<F2,1,0)
In column H, put the formula =if(and(D2="",A1=A2,B1=B2),H1,D2) (this takes the ID wherever it goes).
Put the formulae as from row 2. What step 3 does is putting an incremental number for the people with same name.
What step 4 does is checking for when the column F goes back to 1. This will identify your 'final rows to be kept'.
Here's my output from those formulae:
The green rows are what you keep (notice that there is 1 in column G that allows you to quickly spot them), and the columns A, B, C, E and H are the columns you keep in the final sheet. Don't forget to copy/paste values once you are done with the formulae and before deleting rows!
If first Sally is in A1 then =IF(AND(A1=A2,B1=B2),C1&"/"&C2,"")copied down as appropriate might suit. Assumes where not the same a blank ("") is preferred to repetition of the C value.

defining variables in excel formulas?

i have a simple table data like:
date | Jenna | Tom | Robin
01/01/12 2 5 8
02/01/12 3 4 7
(date columns starts from the first day of the year and goes all the way down to he next year.)
I have a formula getting the min. and max. values (for example for Jenna) for the month January.
I have to change the row numbers every month to get the right result.
Is it possible for me to define variables in two cells and use them in that formula without using VBA.
For example;
I will put two values in H1 and H2 cells, which are 28 and 58 respectively. And i will define E1 as start and E2 as end. And write down this formula:
=min(Cstart:Cend)
=max(Cstart:Cend)
=average(Cstart:Cend)
The first formula means to get the min value between the C28 and C58.
That way i will not have to change every formula manually on the page. I will just change the values of 2 cells and that will be enough.
I hope, I have explained.
Sure. You have to use the INDIRECT() function. INDIRECT transforms a string to a range reference.
=MIN(INDIRECT("C" & $H$1 &":C" & $H$2))

Resources